]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
More bounds checking when fetching addresses and converting to strings.
[tcpdump] / print-802_11.c
1 /*
2 * Copyright (c) 2001
3 * Fortress Technologies, Inc. All rights reserved.
4 * Charlie Lenahan (clenahan@fortresstech.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23 /* \summary: IEEE 802.11 printer */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include "netdissect-stdinc.h"
30
31 #include <string.h>
32
33 #include "netdissect.h"
34 #include "addrtoname.h"
35
36 #include "extract.h"
37
38 #include "cpack.h"
39
40
41 /* Lengths of 802.11 header components. */
42 #define IEEE802_11_FC_LEN 2
43 #define IEEE802_11_DUR_LEN 2
44 #define IEEE802_11_DA_LEN 6
45 #define IEEE802_11_SA_LEN 6
46 #define IEEE802_11_BSSID_LEN 6
47 #define IEEE802_11_RA_LEN 6
48 #define IEEE802_11_TA_LEN 6
49 #define IEEE802_11_ADDR1_LEN 6
50 #define IEEE802_11_SEQ_LEN 2
51 #define IEEE802_11_CTL_LEN 2
52 #define IEEE802_11_CARRIED_FC_LEN 2
53 #define IEEE802_11_HT_CONTROL_LEN 4
54 #define IEEE802_11_IV_LEN 3
55 #define IEEE802_11_KID_LEN 1
56
57 /* Frame check sequence length. */
58 #define IEEE802_11_FCS_LEN 4
59
60 /* Lengths of beacon components. */
61 #define IEEE802_11_TSTAMP_LEN 8
62 #define IEEE802_11_BCNINT_LEN 2
63 #define IEEE802_11_CAPINFO_LEN 2
64 #define IEEE802_11_LISTENINT_LEN 2
65
66 #define IEEE802_11_AID_LEN 2
67 #define IEEE802_11_STATUS_LEN 2
68 #define IEEE802_11_REASON_LEN 2
69
70 /* Length of previous AP in reassocation frame */
71 #define IEEE802_11_AP_LEN 6
72
73 #define T_MGMT 0x0 /* management */
74 #define T_CTRL 0x1 /* control */
75 #define T_DATA 0x2 /* data */
76 #define T_RESV 0x3 /* reserved */
77
78 #define ST_ASSOC_REQUEST 0x0
79 #define ST_ASSOC_RESPONSE 0x1
80 #define ST_REASSOC_REQUEST 0x2
81 #define ST_REASSOC_RESPONSE 0x3
82 #define ST_PROBE_REQUEST 0x4
83 #define ST_PROBE_RESPONSE 0x5
84 /* RESERVED 0x6 */
85 /* RESERVED 0x7 */
86 #define ST_BEACON 0x8
87 #define ST_ATIM 0x9
88 #define ST_DISASSOC 0xA
89 #define ST_AUTH 0xB
90 #define ST_DEAUTH 0xC
91 #define ST_ACTION 0xD
92 /* RESERVED 0xE */
93 /* RESERVED 0xF */
94
95 static const struct tok st_str[] = {
96 { ST_ASSOC_REQUEST, "Assoc Request" },
97 { ST_ASSOC_RESPONSE, "Assoc Response" },
98 { ST_REASSOC_REQUEST, "ReAssoc Request" },
99 { ST_REASSOC_RESPONSE, "ReAssoc Response" },
100 { ST_PROBE_REQUEST, "Probe Request" },
101 { ST_PROBE_RESPONSE, "Probe Response" },
102 { ST_BEACON, "Beacon" },
103 { ST_ATIM, "ATIM" },
104 { ST_DISASSOC, "Disassociation" },
105 { ST_AUTH, "Authentication" },
106 { ST_DEAUTH, "DeAuthentication" },
107 { ST_ACTION, "Action" },
108 { 0, NULL }
109 };
110
111 #define CTRL_CONTROL_WRAPPER 0x7
112 #define CTRL_BAR 0x8
113 #define CTRL_BA 0x9
114 #define CTRL_PS_POLL 0xA
115 #define CTRL_RTS 0xB
116 #define CTRL_CTS 0xC
117 #define CTRL_ACK 0xD
118 #define CTRL_CF_END 0xE
119 #define CTRL_END_ACK 0xF
120
121 static const struct tok ctrl_str[] = {
122 { CTRL_CONTROL_WRAPPER, "Control Wrapper" },
123 { CTRL_BAR, "BAR" },
124 { CTRL_BA, "BA" },
125 { CTRL_PS_POLL, "Power Save-Poll" },
126 { CTRL_RTS, "Request-To-Send" },
127 { CTRL_CTS, "Clear-To-Send" },
128 { CTRL_ACK, "Acknowledgment" },
129 { CTRL_CF_END, "CF-End" },
130 { CTRL_END_ACK, "CF-End+CF-Ack" },
131 { 0, NULL }
132 };
133
134 #define DATA_DATA 0x0
135 #define DATA_DATA_CF_ACK 0x1
136 #define DATA_DATA_CF_POLL 0x2
137 #define DATA_DATA_CF_ACK_POLL 0x3
138 #define DATA_NODATA 0x4
139 #define DATA_NODATA_CF_ACK 0x5
140 #define DATA_NODATA_CF_POLL 0x6
141 #define DATA_NODATA_CF_ACK_POLL 0x7
142
143 #define DATA_QOS_DATA 0x8
144 #define DATA_QOS_DATA_CF_ACK 0x9
145 #define DATA_QOS_DATA_CF_POLL 0xA
146 #define DATA_QOS_DATA_CF_ACK_POLL 0xB
147 #define DATA_QOS_NODATA 0xC
148 #define DATA_QOS_CF_POLL_NODATA 0xE
149 #define DATA_QOS_CF_ACK_POLL_NODATA 0xF
150
151 /*
152 * The subtype field of a data frame is, in effect, composed of 4 flag
153 * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
154 * any data), and QoS.
155 */
156 #define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01)
157 #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
158 #define DATA_FRAME_IS_NULL(x) ((x) & 0x04)
159 #define DATA_FRAME_IS_QOS(x) ((x) & 0x08)
160
161 /*
162 * Bits in the frame control field.
163 */
164 #define FC_VERSION(fc) ((fc) & 0x3)
165 #define FC_TYPE(fc) (((fc) >> 2) & 0x3)
166 #define FC_SUBTYPE(fc) (((fc) >> 4) & 0xF)
167 #define FC_TO_DS(fc) ((fc) & 0x0100)
168 #define FC_FROM_DS(fc) ((fc) & 0x0200)
169 #define FC_MORE_FLAG(fc) ((fc) & 0x0400)
170 #define FC_RETRY(fc) ((fc) & 0x0800)
171 #define FC_POWER_MGMT(fc) ((fc) & 0x1000)
172 #define FC_MORE_DATA(fc) ((fc) & 0x2000)
173 #define FC_PROTECTED(fc) ((fc) & 0x4000)
174 #define FC_ORDER(fc) ((fc) & 0x8000)
175
176 struct mgmt_header_t {
177 nd_uint16_t fc;
178 nd_uint16_t duration;
179 nd_mac_addr da;
180 nd_mac_addr sa;
181 nd_mac_addr bssid;
182 nd_uint16_t seq_ctrl;
183 };
184
185 #define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
186 IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+\
187 IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN)
188
189 #define CAPABILITY_ESS(cap) ((cap) & 0x0001)
190 #define CAPABILITY_IBSS(cap) ((cap) & 0x0002)
191 #define CAPABILITY_CFP(cap) ((cap) & 0x0004)
192 #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008)
193 #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
194
195 struct ssid_t {
196 uint8_t element_id;
197 uint8_t length;
198 u_char ssid[33]; /* 32 + 1 for null */
199 };
200
201 struct rates_t {
202 uint8_t element_id;
203 uint8_t length;
204 uint8_t rate[16];
205 };
206
207 struct challenge_t {
208 uint8_t element_id;
209 uint8_t length;
210 uint8_t text[254]; /* 1-253 + 1 for null */
211 };
212
213 struct fh_t {
214 uint8_t element_id;
215 uint8_t length;
216 uint16_t dwell_time;
217 uint8_t hop_set;
218 uint8_t hop_pattern;
219 uint8_t hop_index;
220 };
221
222 struct ds_t {
223 uint8_t element_id;
224 uint8_t length;
225 uint8_t channel;
226 };
227
228 struct cf_t {
229 uint8_t element_id;
230 uint8_t length;
231 uint8_t count;
232 uint8_t period;
233 uint16_t max_duration;
234 uint16_t dur_remaining;
235 };
236
237 struct tim_t {
238 uint8_t element_id;
239 uint8_t length;
240 uint8_t count;
241 uint8_t period;
242 uint8_t bitmap_control;
243 uint8_t bitmap[251];
244 };
245
246 #define E_SSID 0
247 #define E_RATES 1
248 #define E_FH 2
249 #define E_DS 3
250 #define E_CF 4
251 #define E_TIM 5
252 #define E_IBSS 6
253 /* reserved 7 */
254 /* reserved 8 */
255 /* reserved 9 */
256 /* reserved 10 */
257 /* reserved 11 */
258 /* reserved 12 */
259 /* reserved 13 */
260 /* reserved 14 */
261 /* reserved 15 */
262 /* reserved 16 */
263
264 #define E_CHALLENGE 16
265 /* reserved 17 */
266 /* reserved 18 */
267 /* reserved 19 */
268 /* reserved 16 */
269 /* reserved 16 */
270
271
272 struct mgmt_body_t {
273 uint8_t timestamp[IEEE802_11_TSTAMP_LEN];
274 uint16_t beacon_interval;
275 uint16_t listen_interval;
276 uint16_t status_code;
277 uint16_t aid;
278 u_char ap[IEEE802_11_AP_LEN];
279 uint16_t reason_code;
280 uint16_t auth_alg;
281 uint16_t auth_trans_seq_num;
282 int challenge_present;
283 struct challenge_t challenge;
284 uint16_t capability_info;
285 int ssid_present;
286 struct ssid_t ssid;
287 int rates_present;
288 struct rates_t rates;
289 int ds_present;
290 struct ds_t ds;
291 int cf_present;
292 struct cf_t cf;
293 int fh_present;
294 struct fh_t fh;
295 int tim_present;
296 struct tim_t tim;
297 };
298
299 struct ctrl_control_wrapper_hdr_t {
300 nd_uint16_t fc;
301 nd_uint16_t duration;
302 nd_mac_addr addr1;
303 nd_uint16_t carried_fc[IEEE802_11_CARRIED_FC_LEN];
304 nd_uint16_t ht_control[IEEE802_11_HT_CONTROL_LEN];
305 };
306
307 #define CTRL_CONTROL_WRAPPER_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
308 IEEE802_11_ADDR1_LEN+\
309 IEEE802_11_CARRIED_FC_LEN+\
310 IEEE802_11_HT_CONTROL_LEN)
311
312 struct ctrl_rts_hdr_t {
313 nd_uint16_t fc;
314 nd_uint16_t duration;
315 nd_mac_addr ra;
316 nd_mac_addr ta;
317 };
318
319 #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
320 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
321
322 struct ctrl_cts_hdr_t {
323 nd_uint16_t fc;
324 nd_uint16_t duration;
325 nd_mac_addr ra;
326 };
327
328 #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
329
330 struct ctrl_ack_hdr_t {
331 nd_uint16_t fc;
332 nd_uint16_t duration;
333 nd_mac_addr ra;
334 };
335
336 #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
337
338 struct ctrl_ps_poll_hdr_t {
339 nd_uint16_t fc;
340 nd_uint16_t aid;
341 nd_mac_addr bssid;
342 nd_mac_addr ta;
343 };
344
345 #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\
346 IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN)
347
348 struct ctrl_end_hdr_t {
349 nd_uint16_t fc;
350 nd_uint16_t duration;
351 nd_mac_addr ra;
352 nd_mac_addr bssid;
353 };
354
355 #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
356 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
357
358 struct ctrl_end_ack_hdr_t {
359 nd_uint16_t fc;
360 nd_uint16_t duration;
361 nd_mac_addr ra;
362 nd_mac_addr bssid;
363 };
364
365 #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
366 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
367
368 struct ctrl_ba_hdr_t {
369 nd_uint16_t fc;
370 nd_uint16_t duration;
371 nd_mac_addr ra;
372 };
373
374 #define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
375
376 struct ctrl_bar_hdr_t {
377 nd_uint16_t fc;
378 nd_uint16_t dur;
379 nd_mac_addr ra;
380 nd_mac_addr ta;
381 nd_uint16_t ctl;
382 nd_uint16_t seq;
383 };
384
385 #define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
386 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\
387 IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN)
388
389 struct meshcntl_t {
390 nd_uint8_t flags;
391 nd_uint8_t ttl;
392 nd_uint32_t seq;
393 nd_mac_addr addr4;
394 nd_mac_addr addr5;
395 nd_mac_addr addr6;
396 };
397
398 #define IV_IV(iv) ((iv) & 0xFFFFFF)
399 #define IV_PAD(iv) (((iv) >> 24) & 0x3F)
400 #define IV_KEYID(iv) (((iv) >> 30) & 0x03)
401
402 #define PRINT_SSID(p) \
403 if (p.ssid_present) { \
404 ND_PRINT(" ("); \
405 fn_print_str(ndo, p.ssid.ssid); \
406 ND_PRINT(")"); \
407 }
408
409 #define PRINT_RATE(_sep, _r, _suf) \
410 ND_PRINT("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
411 #define PRINT_RATES(p) \
412 if (p.rates_present) { \
413 int z; \
414 const char *sep = " ["; \
415 for (z = 0; z < p.rates.length ; z++) { \
416 PRINT_RATE(sep, p.rates.rate[z], \
417 (p.rates.rate[z] & 0x80 ? "*" : "")); \
418 sep = " "; \
419 } \
420 if (p.rates.length != 0) \
421 ND_PRINT(" Mbit]"); \
422 }
423
424 #define PRINT_DS_CHANNEL(p) \
425 if (p.ds_present) \
426 ND_PRINT(" CH: %u", p.ds.channel); \
427 ND_PRINT("%s", \
428 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "");
429
430 #define MAX_MCS_INDEX 76
431
432 /*
433 * Indices are:
434 *
435 * the MCS index (0-76);
436 *
437 * 0 for 20 MHz, 1 for 40 MHz;
438 *
439 * 0 for a long guard interval, 1 for a short guard interval.
440 */
441 static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
442 /* MCS 0 */
443 { /* 20 Mhz */ { 6.5f, /* SGI */ 7.2f, },
444 /* 40 Mhz */ { 13.5f, /* SGI */ 15.0f, },
445 },
446
447 /* MCS 1 */
448 { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, },
449 /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, },
450 },
451
452 /* MCS 2 */
453 { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, },
454 /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, },
455 },
456
457 /* MCS 3 */
458 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, },
459 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, },
460 },
461
462 /* MCS 4 */
463 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, },
464 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, },
465 },
466
467 /* MCS 5 */
468 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
469 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
470 },
471
472 /* MCS 6 */
473 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, },
474 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, },
475 },
476
477 /* MCS 7 */
478 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
479 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
480 },
481
482 /* MCS 8 */
483 { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, },
484 /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, },
485 },
486
487 /* MCS 9 */
488 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, },
489 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, },
490 },
491
492 /* MCS 10 */
493 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, },
494 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, },
495 },
496
497 /* MCS 11 */
498 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
499 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
500 },
501
502 /* MCS 12 */
503 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
504 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
505 },
506
507 /* MCS 13 */
508 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, },
509 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, },
510 },
511
512 /* MCS 14 */
513 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
514 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
515 },
516
517 /* MCS 15 */
518 { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, },
519 /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, },
520 },
521
522 /* MCS 16 */
523 { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, },
524 /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, },
525 },
526
527 /* MCS 17 */
528 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, },
529 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, },
530 },
531
532 /* MCS 18 */
533 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, },
534 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, },
535 },
536
537 /* MCS 19 */
538 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
539 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
540 },
541
542 /* MCS 20 */
543 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
544 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
545 },
546
547 /* MCS 21 */
548 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, },
549 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, },
550 },
551
552 /* MCS 22 */
553 { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, },
554 /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, },
555 },
556
557 /* MCS 23 */
558 { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, },
559 /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, },
560 },
561
562 /* MCS 24 */
563 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, },
564 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, },
565 },
566
567 /* MCS 25 */
568 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
569 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
570 },
571
572 /* MCS 26 */
573 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
574 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
575 },
576
577 /* MCS 27 */
578 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, },
579 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, },
580 },
581
582 /* MCS 28 */
583 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, },
584 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, },
585 },
586
587 /* MCS 29 */
588 { /* 20 Mhz */ { 208.0f, /* SGI */ 231.1f, },
589 /* 40 Mhz */ { 432.0f, /* SGI */ 480.0f, },
590 },
591
592 /* MCS 30 */
593 { /* 20 Mhz */ { 234.0f, /* SGI */ 260.0f, },
594 /* 40 Mhz */ { 486.0f, /* SGI */ 540.0f, },
595 },
596
597 /* MCS 31 */
598 { /* 20 Mhz */ { 260.0f, /* SGI */ 288.9f, },
599 /* 40 Mhz */ { 540.0f, /* SGI */ 600.0f, },
600 },
601
602 /* MCS 32 */
603 { /* 20 Mhz */ { 0.0f, /* SGI */ 0.0f, }, /* not valid */
604 /* 40 Mhz */ { 6.0f, /* SGI */ 6.7f, },
605 },
606
607 /* MCS 33 */
608 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, },
609 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, },
610 },
611
612 /* MCS 34 */
613 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
614 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
615 },
616
617 /* MCS 35 */
618 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
619 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
620 },
621
622 /* MCS 36 */
623 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, },
624 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, },
625 },
626
627 /* MCS 37 */
628 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
629 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
630 },
631
632 /* MCS 38 */
633 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, },
634 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, },
635 },
636
637 /* MCS 39 */
638 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
639 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
640 },
641
642 /* MCS 40 */
643 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
644 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
645 },
646
647 /* MCS 41 */
648 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
649 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
650 },
651
652 /* MCS 42 */
653 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
654 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
655 },
656
657 /* MCS 43 */
658 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, },
659 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, },
660 },
661
662 /* MCS 44 */
663 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, },
664 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, },
665 },
666
667 /* MCS 45 */
668 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, },
669 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, },
670 },
671
672 /* MCS 46 */
673 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
674 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
675 },
676
677 /* MCS 47 */
678 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, },
679 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, },
680 },
681
682 /* MCS 48 */
683 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, },
684 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, },
685 },
686
687 /* MCS 49 */
688 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
689 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
690 },
691
692 /* MCS 50 */
693 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, },
694 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, },
695 },
696
697 /* MCS 51 */
698 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, },
699 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, },
700 },
701
702 /* MCS 52 */
703 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, },
704 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, },
705 },
706
707 /* MCS 53 */
708 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
709 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
710 },
711
712 /* MCS 54 */
713 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
714 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
715 },
716
717 /* MCS 55 */
718 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, },
719 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, },
720 },
721
722 /* MCS 56 */
723 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
724 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
725 },
726
727 /* MCS 57 */
728 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, },
729 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, },
730 },
731
732 /* MCS 58 */
733 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, },
734 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, },
735 },
736
737 /* MCS 59 */
738 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
739 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
740 },
741
742 /* MCS 60 */
743 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, },
744 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, },
745 },
746
747 /* MCS 61 */
748 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
749 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
750 },
751
752 /* MCS 62 */
753 { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, },
754 /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, },
755 },
756
757 /* MCS 63 */
758 { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, },
759 /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, },
760 },
761
762 /* MCS 64 */
763 { /* 20 Mhz */ { 143.0f, /* SGI */ 158.9f, },
764 /* 40 Mhz */ { 297.0f, /* SGI */ 330.0f, },
765 },
766
767 /* MCS 65 */
768 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, },
769 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, },
770 },
771
772 /* MCS 66 */
773 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
774 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
775 },
776
777 /* MCS 67 */
778 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, },
779 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, },
780 },
781
782 /* MCS 68 */
783 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, },
784 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, },
785 },
786
787 /* MCS 69 */
788 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, },
789 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, },
790 },
791
792 /* MCS 70 */
793 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, },
794 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, },
795 },
796
797 /* MCS 71 */
798 { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, },
799 /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, },
800 },
801
802 /* MCS 72 */
803 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, },
804 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, },
805 },
806
807 /* MCS 73 */
808 { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, },
809 /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, },
810 },
811
812 /* MCS 74 */
813 { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, },
814 /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, },
815 },
816
817 /* MCS 75 */
818 { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, },
819 /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, },
820 },
821
822 /* MCS 76 */
823 { /* 20 Mhz */ { 214.5f, /* SGI */ 238.3f, },
824 /* 40 Mhz */ { 445.5f, /* SGI */ 495.0f, },
825 },
826 };
827
828 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
829 #define NUM_AUTH_ALGS (sizeof(auth_alg_text) / sizeof(auth_alg_text[0]))
830
831 static const char *status_text[] = {
832 "Successful", /* 0 */
833 "Unspecified failure", /* 1 */
834 "Reserved", /* 2 */
835 "Reserved", /* 3 */
836 "Reserved", /* 4 */
837 "Reserved", /* 5 */
838 "Reserved", /* 6 */
839 "Reserved", /* 7 */
840 "Reserved", /* 8 */
841 "Reserved", /* 9 */
842 "Cannot Support all requested capabilities in the Capability "
843 "Information field", /* 10 */
844 "Reassociation denied due to inability to confirm that association "
845 "exists", /* 11 */
846 "Association denied due to reason outside the scope of the "
847 "standard", /* 12 */
848 "Responding station does not support the specified authentication "
849 "algorithm ", /* 13 */
850 "Received an Authentication frame with authentication transaction "
851 "sequence number out of expected sequence", /* 14 */
852 "Authentication rejected because of challenge failure", /* 15 */
853 "Authentication rejected due to timeout waiting for next frame in "
854 "sequence", /* 16 */
855 "Association denied because AP is unable to handle additional"
856 "associated stations", /* 17 */
857 "Association denied due to requesting station not supporting all of "
858 "the data rates in BSSBasicRateSet parameter", /* 18 */
859 "Association denied due to requesting station not supporting "
860 "short preamble operation", /* 19 */
861 "Association denied due to requesting station not supporting "
862 "PBCC encoding", /* 20 */
863 "Association denied due to requesting station not supporting "
864 "channel agility", /* 21 */
865 "Association request rejected because Spectrum Management "
866 "capability is required", /* 22 */
867 "Association request rejected because the information in the "
868 "Power Capability element is unacceptable", /* 23 */
869 "Association request rejected because the information in the "
870 "Supported Channels element is unacceptable", /* 24 */
871 "Association denied due to requesting station not supporting "
872 "short slot operation", /* 25 */
873 "Association denied due to requesting station not supporting "
874 "DSSS-OFDM operation", /* 26 */
875 "Association denied because the requested STA does not support HT "
876 "features", /* 27 */
877 "Reserved", /* 28 */
878 "Association denied because the requested STA does not support "
879 "the PCO transition time required by the AP", /* 29 */
880 "Reserved", /* 30 */
881 "Reserved", /* 31 */
882 "Unspecified, QoS-related failure", /* 32 */
883 "Association denied due to QAP having insufficient bandwidth "
884 "to handle another QSTA", /* 33 */
885 "Association denied due to excessive frame loss rates and/or "
886 "poor conditions on current operating channel", /* 34 */
887 "Association (with QBSS) denied due to requesting station not "
888 "supporting the QoS facility", /* 35 */
889 "Association denied due to requesting station not supporting "
890 "Block Ack", /* 36 */
891 "The request has been declined", /* 37 */
892 "The request has not been successful as one or more parameters "
893 "have invalid values", /* 38 */
894 "The TS has not been created because the request cannot be honored. "
895 "Try again with the suggested changes to the TSPEC", /* 39 */
896 "Invalid Information Element", /* 40 */
897 "Group Cipher is not valid", /* 41 */
898 "Pairwise Cipher is not valid", /* 42 */
899 "AKMP is not valid", /* 43 */
900 "Unsupported RSN IE version", /* 44 */
901 "Invalid RSN IE Capabilities", /* 45 */
902 "Cipher suite is rejected per security policy", /* 46 */
903 "The TS has not been created. However, the HC may be capable of "
904 "creating a TS, in response to a request, after the time indicated "
905 "in the TS Delay element", /* 47 */
906 "Direct Link is not allowed in the BSS by policy", /* 48 */
907 "Destination STA is not present within this QBSS.", /* 49 */
908 "The Destination STA is not a QSTA.", /* 50 */
909
910 };
911 #define NUM_STATUSES (sizeof(status_text) / sizeof(status_text[0]))
912
913 static const char *reason_text[] = {
914 "Reserved", /* 0 */
915 "Unspecified reason", /* 1 */
916 "Previous authentication no longer valid", /* 2 */
917 "Deauthenticated because sending station is leaving (or has left) "
918 "IBSS or ESS", /* 3 */
919 "Disassociated due to inactivity", /* 4 */
920 "Disassociated because AP is unable to handle all currently "
921 " associated stations", /* 5 */
922 "Class 2 frame received from nonauthenticated station", /* 6 */
923 "Class 3 frame received from nonassociated station", /* 7 */
924 "Disassociated because sending station is leaving "
925 "(or has left) BSS", /* 8 */
926 "Station requesting (re)association is not authenticated with "
927 "responding station", /* 9 */
928 "Disassociated because the information in the Power Capability "
929 "element is unacceptable", /* 10 */
930 "Disassociated because the information in the SupportedChannels "
931 "element is unacceptable", /* 11 */
932 "Invalid Information Element", /* 12 */
933 "Reserved", /* 13 */
934 "Michael MIC failure", /* 14 */
935 "4-Way Handshake timeout", /* 15 */
936 "Group key update timeout", /* 16 */
937 "Information element in 4-Way Handshake different from (Re)Association"
938 "Request/Probe Response/Beacon", /* 17 */
939 "Group Cipher is not valid", /* 18 */
940 "AKMP is not valid", /* 20 */
941 "Unsupported RSN IE version", /* 21 */
942 "Invalid RSN IE Capabilities", /* 22 */
943 "IEEE 802.1X Authentication failed", /* 23 */
944 "Cipher suite is rejected per security policy", /* 24 */
945 "Reserved", /* 25 */
946 "Reserved", /* 26 */
947 "Reserved", /* 27 */
948 "Reserved", /* 28 */
949 "Reserved", /* 29 */
950 "Reserved", /* 30 */
951 "TS deleted because QoS AP lacks sufficient bandwidth for this "
952 "QoS STA due to a change in BSS service characteristics or "
953 "operational mode (e.g. an HT BSS change from 40 MHz channel "
954 "to 20 MHz channel)", /* 31 */
955 "Disassociated for unspecified, QoS-related reason", /* 32 */
956 "Disassociated because QoS AP lacks sufficient bandwidth for this "
957 "QoS STA", /* 33 */
958 "Disassociated because of excessive number of frames that need to be "
959 "acknowledged, but are not acknowledged for AP transmissions "
960 "and/or poor channel conditions", /* 34 */
961 "Disassociated because STA is transmitting outside the limits "
962 "of its TXOPs", /* 35 */
963 "Requested from peer STA as the STA is leaving the BSS "
964 "(or resetting)", /* 36 */
965 "Requested from peer STA as it does not want to use the "
966 "mechanism", /* 37 */
967 "Requested from peer STA as the STA received frames using the "
968 "mechanism for which a set up is required", /* 38 */
969 "Requested from peer STA due to time out", /* 39 */
970 "Reserved", /* 40 */
971 "Reserved", /* 41 */
972 "Reserved", /* 42 */
973 "Reserved", /* 43 */
974 "Reserved", /* 44 */
975 "Peer STA does not support the requested cipher suite", /* 45 */
976 "Association denied due to requesting STA not supporting HT "
977 "features", /* 46 */
978 };
979 #define NUM_REASONS (sizeof(reason_text) / sizeof(reason_text[0]))
980
981 static int
982 wep_print(netdissect_options *ndo,
983 const u_char *p)
984 {
985 uint32_t iv;
986
987 ND_TCHECK_LEN(p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN);
988 iv = GET_LE_U_4(p);
989
990 ND_PRINT(" IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
991 IV_KEYID(iv));
992
993 return 1;
994 trunc:
995 return 0;
996 }
997
998 static int
999 parse_elements(netdissect_options *ndo,
1000 struct mgmt_body_t *pbody, const u_char *p, int offset,
1001 u_int length)
1002 {
1003 u_int elementlen;
1004 struct ssid_t ssid;
1005 struct challenge_t challenge;
1006 struct rates_t rates;
1007 struct ds_t ds;
1008 struct cf_t cf;
1009 struct tim_t tim;
1010
1011 /*
1012 * We haven't seen any elements yet.
1013 */
1014 pbody->challenge_present = 0;
1015 pbody->ssid_present = 0;
1016 pbody->rates_present = 0;
1017 pbody->ds_present = 0;
1018 pbody->cf_present = 0;
1019 pbody->tim_present = 0;
1020
1021 while (length != 0) {
1022 /* Make sure we at least have the element ID and length. */
1023 ND_TCHECK_2(p + offset);
1024 if (length < 2)
1025 goto trunc;
1026 elementlen = GET_U_1(p + offset + 1);
1027
1028 /* Make sure we have the entire element. */
1029 ND_TCHECK_LEN(p + offset + 2, elementlen);
1030 if (length < elementlen + 2)
1031 goto trunc;
1032
1033 switch (GET_U_1(p + offset)) {
1034 case E_SSID:
1035 memcpy(&ssid, p + offset, 2);
1036 offset += 2;
1037 length -= 2;
1038 if (ssid.length != 0) {
1039 if (ssid.length > sizeof(ssid.ssid) - 1)
1040 return 0;
1041 memcpy(&ssid.ssid, p + offset, ssid.length);
1042 offset += ssid.length;
1043 length -= ssid.length;
1044 }
1045 ssid.ssid[ssid.length] = '\0';
1046 /*
1047 * Present and not truncated.
1048 *
1049 * If we haven't already seen an SSID IE,
1050 * copy this one, otherwise ignore this one,
1051 * so we later report the first one we saw.
1052 */
1053 if (!pbody->ssid_present) {
1054 pbody->ssid = ssid;
1055 pbody->ssid_present = 1;
1056 }
1057 break;
1058 case E_CHALLENGE:
1059 memcpy(&challenge, p + offset, 2);
1060 offset += 2;
1061 length -= 2;
1062 if (challenge.length != 0) {
1063 if (challenge.length >
1064 sizeof(challenge.text) - 1)
1065 return 0;
1066 memcpy(&challenge.text, p + offset,
1067 challenge.length);
1068 offset += challenge.length;
1069 length -= challenge.length;
1070 }
1071 challenge.text[challenge.length] = '\0';
1072 /*
1073 * Present and not truncated.
1074 *
1075 * If we haven't already seen a challenge IE,
1076 * copy this one, otherwise ignore this one,
1077 * so we later report the first one we saw.
1078 */
1079 if (!pbody->challenge_present) {
1080 pbody->challenge = challenge;
1081 pbody->challenge_present = 1;
1082 }
1083 break;
1084 case E_RATES:
1085 memcpy(&rates, p + offset, 2);
1086 offset += 2;
1087 length -= 2;
1088 if (rates.length != 0) {
1089 if (rates.length > sizeof(rates.rate))
1090 return 0;
1091 memcpy(&rates.rate, p + offset, rates.length);
1092 offset += rates.length;
1093 length -= rates.length;
1094 }
1095 /*
1096 * Present and not truncated.
1097 *
1098 * If we haven't already seen a rates IE,
1099 * copy this one if it's not zero-length,
1100 * otherwise ignore this one, so we later
1101 * report the first one we saw.
1102 *
1103 * We ignore zero-length rates IEs as some
1104 * devices seem to put a zero-length rates
1105 * IE, followed by an SSID IE, followed by
1106 * a non-zero-length rates IE into frames,
1107 * even though IEEE Std 802.11-2007 doesn't
1108 * seem to indicate that a zero-length rates
1109 * IE is valid.
1110 */
1111 if (!pbody->rates_present && rates.length != 0) {
1112 pbody->rates = rates;
1113 pbody->rates_present = 1;
1114 }
1115 break;
1116 case E_DS:
1117 memcpy(&ds, p + offset, 2);
1118 offset += 2;
1119 length -= 2;
1120 if (ds.length != 1) {
1121 offset += ds.length;
1122 length -= ds.length;
1123 break;
1124 }
1125 ds.channel = GET_U_1(p + offset);
1126 offset += 1;
1127 length -= 1;
1128 /*
1129 * Present and not truncated.
1130 *
1131 * If we haven't already seen a DS IE,
1132 * copy this one, otherwise ignore this one,
1133 * so we later report the first one we saw.
1134 */
1135 if (!pbody->ds_present) {
1136 pbody->ds = ds;
1137 pbody->ds_present = 1;
1138 }
1139 break;
1140 case E_CF:
1141 memcpy(&cf, p + offset, 2);
1142 offset += 2;
1143 length -= 2;
1144 if (cf.length != 6) {
1145 offset += cf.length;
1146 length -= cf.length;
1147 break;
1148 }
1149 memcpy(&cf.count, p + offset, 6);
1150 offset += 6;
1151 length -= 6;
1152 /*
1153 * Present and not truncated.
1154 *
1155 * If we haven't already seen a CF IE,
1156 * copy this one, otherwise ignore this one,
1157 * so we later report the first one we saw.
1158 */
1159 if (!pbody->cf_present) {
1160 pbody->cf = cf;
1161 pbody->cf_present = 1;
1162 }
1163 break;
1164 case E_TIM:
1165 memcpy(&tim, p + offset, 2);
1166 offset += 2;
1167 length -= 2;
1168 if (tim.length <= 3U) {
1169 offset += tim.length;
1170 length -= tim.length;
1171 break;
1172 }
1173 if (tim.length - 3U > sizeof(tim.bitmap))
1174 return 0;
1175 memcpy(&tim.count, p + offset, 3);
1176 offset += 3;
1177 length -= 3;
1178
1179 memcpy(tim.bitmap, p + offset, tim.length - 3);
1180 offset += tim.length - 3;
1181 length -= tim.length - 3;
1182 /*
1183 * Present and not truncated.
1184 *
1185 * If we haven't already seen a TIM IE,
1186 * copy this one, otherwise ignore this one,
1187 * so we later report the first one we saw.
1188 */
1189 if (!pbody->tim_present) {
1190 pbody->tim = tim;
1191 pbody->tim_present = 1;
1192 }
1193 break;
1194 default:
1195 #if 0
1196 ND_PRINT("(1) unhandled element_id (%u) ",
1197 GET_U_1(p + offset));
1198 #endif
1199 offset += 2 + elementlen;
1200 length -= 2 + elementlen;
1201 break;
1202 }
1203 }
1204
1205 /* No problems found. */
1206 return 1;
1207 trunc:
1208 return 0;
1209 }
1210
1211 /*********************************************************************************
1212 * Print Handle functions for the management frame types
1213 *********************************************************************************/
1214
1215 static int
1216 handle_beacon(netdissect_options *ndo,
1217 const u_char *p, u_int length)
1218 {
1219 struct mgmt_body_t pbody;
1220 int offset = 0;
1221 int ret;
1222
1223 memset(&pbody, 0, sizeof(pbody));
1224
1225 ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1226 IEEE802_11_CAPINFO_LEN);
1227 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1228 IEEE802_11_CAPINFO_LEN)
1229 goto trunc;
1230 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1231 offset += IEEE802_11_TSTAMP_LEN;
1232 length -= IEEE802_11_TSTAMP_LEN;
1233 pbody.beacon_interval = GET_LE_U_2(p + offset);
1234 offset += IEEE802_11_BCNINT_LEN;
1235 length -= IEEE802_11_BCNINT_LEN;
1236 pbody.capability_info = GET_LE_U_2(p + offset);
1237 offset += IEEE802_11_CAPINFO_LEN;
1238 length -= IEEE802_11_CAPINFO_LEN;
1239
1240 ret = parse_elements(ndo, &pbody, p, offset, length);
1241
1242 PRINT_SSID(pbody);
1243 PRINT_RATES(pbody);
1244 ND_PRINT(" %s",
1245 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
1246 PRINT_DS_CHANNEL(pbody);
1247
1248 return ret;
1249 trunc:
1250 return 0;
1251 }
1252
1253 static int
1254 handle_assoc_request(netdissect_options *ndo,
1255 const u_char *p, u_int length)
1256 {
1257 struct mgmt_body_t pbody;
1258 int offset = 0;
1259 int ret;
1260
1261 memset(&pbody, 0, sizeof(pbody));
1262
1263 ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN);
1264 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
1265 goto trunc;
1266 pbody.capability_info = GET_LE_U_2(p);
1267 offset += IEEE802_11_CAPINFO_LEN;
1268 length -= IEEE802_11_CAPINFO_LEN;
1269 pbody.listen_interval = GET_LE_U_2(p + offset);
1270 offset += IEEE802_11_LISTENINT_LEN;
1271 length -= IEEE802_11_LISTENINT_LEN;
1272
1273 ret = parse_elements(ndo, &pbody, p, offset, length);
1274
1275 PRINT_SSID(pbody);
1276 PRINT_RATES(pbody);
1277 return ret;
1278 trunc:
1279 return 0;
1280 }
1281
1282 static int
1283 handle_assoc_response(netdissect_options *ndo,
1284 const u_char *p, u_int length)
1285 {
1286 struct mgmt_body_t pbody;
1287 int offset = 0;
1288 int ret;
1289
1290 memset(&pbody, 0, sizeof(pbody));
1291
1292 ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1293 IEEE802_11_AID_LEN);
1294 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1295 IEEE802_11_AID_LEN)
1296 goto trunc;
1297 pbody.capability_info = GET_LE_U_2(p);
1298 offset += IEEE802_11_CAPINFO_LEN;
1299 length -= IEEE802_11_CAPINFO_LEN;
1300 pbody.status_code = GET_LE_U_2(p + offset);
1301 offset += IEEE802_11_STATUS_LEN;
1302 length -= IEEE802_11_STATUS_LEN;
1303 pbody.aid = GET_LE_U_2(p + offset);
1304 offset += IEEE802_11_AID_LEN;
1305 length -= IEEE802_11_AID_LEN;
1306
1307 ret = parse_elements(ndo, &pbody, p, offset, length);
1308
1309 ND_PRINT(" AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 ,
1310 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
1311 (pbody.status_code < NUM_STATUSES
1312 ? status_text[pbody.status_code]
1313 : "n/a"));
1314
1315 return ret;
1316 trunc:
1317 return 0;
1318 }
1319
1320 static int
1321 handle_reassoc_request(netdissect_options *ndo,
1322 const u_char *p, u_int length)
1323 {
1324 struct mgmt_body_t pbody;
1325 int offset = 0;
1326 int ret;
1327
1328 memset(&pbody, 0, sizeof(pbody));
1329
1330 ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1331 IEEE802_11_AP_LEN);
1332 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1333 IEEE802_11_AP_LEN)
1334 goto trunc;
1335 pbody.capability_info = GET_LE_U_2(p);
1336 offset += IEEE802_11_CAPINFO_LEN;
1337 length -= IEEE802_11_CAPINFO_LEN;
1338 pbody.listen_interval = GET_LE_U_2(p + offset);
1339 offset += IEEE802_11_LISTENINT_LEN;
1340 length -= IEEE802_11_LISTENINT_LEN;
1341 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1342 offset += IEEE802_11_AP_LEN;
1343 length -= IEEE802_11_AP_LEN;
1344
1345 ret = parse_elements(ndo, &pbody, p, offset, length);
1346
1347 PRINT_SSID(pbody);
1348 ND_PRINT(" AP : %s", etheraddr_string(ndo, pbody.ap ));
1349
1350 return ret;
1351 trunc:
1352 return 0;
1353 }
1354
1355 static int
1356 handle_reassoc_response(netdissect_options *ndo,
1357 const u_char *p, u_int length)
1358 {
1359 /* Same as a Association Response */
1360 return handle_assoc_response(ndo, p, length);
1361 }
1362
1363 static int
1364 handle_probe_request(netdissect_options *ndo,
1365 const u_char *p, u_int length)
1366 {
1367 struct mgmt_body_t pbody;
1368 int offset = 0;
1369 int ret;
1370
1371 memset(&pbody, 0, sizeof(pbody));
1372
1373 ret = parse_elements(ndo, &pbody, p, offset, length);
1374
1375 PRINT_SSID(pbody);
1376 PRINT_RATES(pbody);
1377
1378 return ret;
1379 }
1380
1381 static int
1382 handle_probe_response(netdissect_options *ndo,
1383 const u_char *p, u_int length)
1384 {
1385 struct mgmt_body_t pbody;
1386 int offset = 0;
1387 int ret;
1388
1389 memset(&pbody, 0, sizeof(pbody));
1390
1391 ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1392 IEEE802_11_CAPINFO_LEN);
1393 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1394 IEEE802_11_CAPINFO_LEN)
1395 goto trunc;
1396 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1397 offset += IEEE802_11_TSTAMP_LEN;
1398 length -= IEEE802_11_TSTAMP_LEN;
1399 pbody.beacon_interval = GET_LE_U_2(p + offset);
1400 offset += IEEE802_11_BCNINT_LEN;
1401 length -= IEEE802_11_BCNINT_LEN;
1402 pbody.capability_info = GET_LE_U_2(p + offset);
1403 offset += IEEE802_11_CAPINFO_LEN;
1404 length -= IEEE802_11_CAPINFO_LEN;
1405
1406 ret = parse_elements(ndo, &pbody, p, offset, length);
1407
1408 PRINT_SSID(pbody);
1409 PRINT_RATES(pbody);
1410 PRINT_DS_CHANNEL(pbody);
1411
1412 return ret;
1413 trunc:
1414 return 0;
1415 }
1416
1417 static int
1418 handle_atim(void)
1419 {
1420 /* the frame body for ATIM is null. */
1421 return 1;
1422 }
1423
1424 static int
1425 handle_disassoc(netdissect_options *ndo,
1426 const u_char *p, u_int length)
1427 {
1428 struct mgmt_body_t pbody;
1429
1430 memset(&pbody, 0, sizeof(pbody));
1431
1432 ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN);
1433 if (length < IEEE802_11_REASON_LEN)
1434 goto trunc;
1435 pbody.reason_code = GET_LE_U_2(p);
1436
1437 ND_PRINT(": %s",
1438 (pbody.reason_code < NUM_REASONS)
1439 ? reason_text[pbody.reason_code]
1440 : "Reserved");
1441
1442 return 1;
1443 trunc:
1444 return 0;
1445 }
1446
1447 static int
1448 handle_auth(netdissect_options *ndo,
1449 const u_char *p, u_int length)
1450 {
1451 struct mgmt_body_t pbody;
1452 int offset = 0;
1453 int ret;
1454
1455 memset(&pbody, 0, sizeof(pbody));
1456
1457 ND_TCHECK_6(p);
1458 if (length < 6)
1459 goto trunc;
1460 pbody.auth_alg = GET_LE_U_2(p);
1461 offset += 2;
1462 length -= 2;
1463 pbody.auth_trans_seq_num = GET_LE_U_2(p + offset);
1464 offset += 2;
1465 length -= 2;
1466 pbody.status_code = GET_LE_U_2(p + offset);
1467 offset += 2;
1468 length -= 2;
1469
1470 ret = parse_elements(ndo, &pbody, p, offset, length);
1471
1472 if ((pbody.auth_alg == 1) &&
1473 ((pbody.auth_trans_seq_num == 2) ||
1474 (pbody.auth_trans_seq_num == 3))) {
1475 ND_PRINT(" (%s)-%x [Challenge Text] %s",
1476 (pbody.auth_alg < NUM_AUTH_ALGS)
1477 ? auth_alg_text[pbody.auth_alg]
1478 : "Reserved",
1479 pbody.auth_trans_seq_num,
1480 ((pbody.auth_trans_seq_num % 2)
1481 ? ((pbody.status_code < NUM_STATUSES)
1482 ? status_text[pbody.status_code]
1483 : "n/a") : ""));
1484 return ret;
1485 }
1486 ND_PRINT(" (%s)-%x: %s",
1487 (pbody.auth_alg < NUM_AUTH_ALGS)
1488 ? auth_alg_text[pbody.auth_alg]
1489 : "Reserved",
1490 pbody.auth_trans_seq_num,
1491 (pbody.auth_trans_seq_num % 2)
1492 ? ((pbody.status_code < NUM_STATUSES)
1493 ? status_text[pbody.status_code]
1494 : "n/a")
1495 : "");
1496
1497 return ret;
1498 trunc:
1499 return 0;
1500 }
1501
1502 static int
1503 handle_deauth(netdissect_options *ndo,
1504 const uint8_t *src, const u_char *p, u_int length)
1505 {
1506 struct mgmt_body_t pbody;
1507 const char *reason = NULL;
1508
1509 memset(&pbody, 0, sizeof(pbody));
1510
1511 ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN);
1512 if (length < IEEE802_11_REASON_LEN)
1513 goto trunc;
1514 pbody.reason_code = GET_LE_U_2(p);
1515
1516 reason = (pbody.reason_code < NUM_REASONS)
1517 ? reason_text[pbody.reason_code]
1518 : "Reserved";
1519
1520 if (ndo->ndo_eflag) {
1521 ND_PRINT(": %s", reason);
1522 } else {
1523 ND_PRINT(" (%s): %s", GET_ETHERADDR_STRING(src), reason);
1524 }
1525 return 1;
1526 trunc:
1527 return 0;
1528 }
1529
1530 #define PRINT_HT_ACTION(v) (\
1531 (v) == 0 ? ND_PRINT("TxChWidth"): \
1532 (v) == 1 ? ND_PRINT("MIMOPwrSave"): \
1533 ND_PRINT("Act#%u", (v)))
1534 #define PRINT_BA_ACTION(v) (\
1535 (v) == 0 ? ND_PRINT("ADDBA Request"): \
1536 (v) == 1 ? ND_PRINT("ADDBA Response"): \
1537 (v) == 2 ? ND_PRINT("DELBA"): \
1538 ND_PRINT("Act#%u", (v)))
1539 #define PRINT_MESHLINK_ACTION(v) (\
1540 (v) == 0 ? ND_PRINT("Request"): \
1541 (v) == 1 ? ND_PRINT("Report"): \
1542 ND_PRINT("Act#%u", (v)))
1543 #define PRINT_MESHPEERING_ACTION(v) (\
1544 (v) == 0 ? ND_PRINT("Open"): \
1545 (v) == 1 ? ND_PRINT("Confirm"): \
1546 (v) == 2 ? ND_PRINT("Close"): \
1547 ND_PRINT("Act#%u", (v)))
1548 #define PRINT_MESHPATH_ACTION(v) (\
1549 (v) == 0 ? ND_PRINT("Request"): \
1550 (v) == 1 ? ND_PRINT("Report"): \
1551 (v) == 2 ? ND_PRINT("Error"): \
1552 (v) == 3 ? ND_PRINT("RootAnnouncement"): \
1553 ND_PRINT("Act#%u", (v)))
1554
1555 #define PRINT_MESH_ACTION(v) (\
1556 (v) == 0 ? ND_PRINT("MeshLink"): \
1557 (v) == 1 ? ND_PRINT("HWMP"): \
1558 (v) == 2 ? ND_PRINT("Gate Announcement"): \
1559 (v) == 3 ? ND_PRINT("Congestion Control"): \
1560 (v) == 4 ? ND_PRINT("MCCA Setup Request"): \
1561 (v) == 5 ? ND_PRINT("MCCA Setup Reply"): \
1562 (v) == 6 ? ND_PRINT("MCCA Advertisement Request"): \
1563 (v) == 7 ? ND_PRINT("MCCA Advertisement"): \
1564 (v) == 8 ? ND_PRINT("MCCA Teardown"): \
1565 (v) == 9 ? ND_PRINT("TBTT Adjustment Request"): \
1566 (v) == 10 ? ND_PRINT("TBTT Adjustment Response"): \
1567 ND_PRINT("Act#%u", (v)))
1568 #define PRINT_MULTIHOP_ACTION(v) (\
1569 (v) == 0 ? ND_PRINT("Proxy Update"): \
1570 (v) == 1 ? ND_PRINT("Proxy Update Confirmation"): \
1571 ND_PRINT("Act#%u", (v)))
1572 #define PRINT_SELFPROT_ACTION(v) (\
1573 (v) == 1 ? ND_PRINT("Peering Open"): \
1574 (v) == 2 ? ND_PRINT("Peering Confirm"): \
1575 (v) == 3 ? ND_PRINT("Peering Close"): \
1576 (v) == 4 ? ND_PRINT("Group Key Inform"): \
1577 (v) == 5 ? ND_PRINT("Group Key Acknowledge"): \
1578 ND_PRINT("Act#%u", (v)))
1579
1580 static int
1581 handle_action(netdissect_options *ndo,
1582 const uint8_t *src, const u_char *p, u_int length)
1583 {
1584 ND_TCHECK_2(p);
1585 if (length < 2)
1586 goto trunc;
1587 if (ndo->ndo_eflag) {
1588 ND_PRINT(": ");
1589 } else {
1590 ND_PRINT(" (%s): ", GET_ETHERADDR_STRING(src));
1591 }
1592 switch (GET_U_1(p)) {
1593 case 0: ND_PRINT("Spectrum Management Act#%u", GET_U_1(p + 1)); break;
1594 case 1: ND_PRINT("QoS Act#%u", GET_U_1(p + 1)); break;
1595 case 2: ND_PRINT("DLS Act#%u", GET_U_1(p + 1)); break;
1596 case 3: ND_PRINT("BA "); PRINT_BA_ACTION(GET_U_1(p + 1)); break;
1597 case 7: ND_PRINT("HT "); PRINT_HT_ACTION(GET_U_1(p + 1)); break;
1598 case 13: ND_PRINT("MeshAction "); PRINT_MESH_ACTION(GET_U_1(p + 1)); break;
1599 case 14:
1600 ND_PRINT("MultiohopAction ");
1601 PRINT_MULTIHOP_ACTION(GET_U_1(p + 1)); break;
1602 case 15:
1603 ND_PRINT("SelfprotectAction ");
1604 PRINT_SELFPROT_ACTION(GET_U_1(p + 1)); break;
1605 case 127: ND_PRINT("Vendor Act#%u", GET_U_1(p + 1)); break;
1606 default:
1607 ND_PRINT("Reserved(%u) Act#%u", GET_U_1(p), GET_U_1(p + 1));
1608 break;
1609 }
1610 return 1;
1611 trunc:
1612 return 0;
1613 }
1614
1615
1616 /*********************************************************************************
1617 * Print Body funcs
1618 *********************************************************************************/
1619
1620
1621 static int
1622 mgmt_body_print(netdissect_options *ndo,
1623 uint16_t fc, const uint8_t *src, const u_char *p, u_int length)
1624 {
1625 ND_PRINT("%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc)));
1626
1627 /* There may be a problem w/ AP not having this bit set */
1628 if (FC_PROTECTED(fc))
1629 return wep_print(ndo, p);
1630 switch (FC_SUBTYPE(fc)) {
1631 case ST_ASSOC_REQUEST:
1632 return handle_assoc_request(ndo, p, length);
1633 case ST_ASSOC_RESPONSE:
1634 return handle_assoc_response(ndo, p, length);
1635 case ST_REASSOC_REQUEST:
1636 return handle_reassoc_request(ndo, p, length);
1637 case ST_REASSOC_RESPONSE:
1638 return handle_reassoc_response(ndo, p, length);
1639 case ST_PROBE_REQUEST:
1640 return handle_probe_request(ndo, p, length);
1641 case ST_PROBE_RESPONSE:
1642 return handle_probe_response(ndo, p, length);
1643 case ST_BEACON:
1644 return handle_beacon(ndo, p, length);
1645 case ST_ATIM:
1646 return handle_atim();
1647 case ST_DISASSOC:
1648 return handle_disassoc(ndo, p, length);
1649 case ST_AUTH:
1650 return handle_auth(ndo, p, length);
1651 case ST_DEAUTH:
1652 return handle_deauth(ndo, src, p, length);
1653 case ST_ACTION:
1654 return handle_action(ndo, src, p, length);
1655 default:
1656 return 1;
1657 }
1658 }
1659
1660
1661 /*********************************************************************************
1662 * Handles printing all the control frame types
1663 *********************************************************************************/
1664
1665 static int
1666 ctrl_body_print(netdissect_options *ndo,
1667 uint16_t fc, const u_char *p)
1668 {
1669 ND_PRINT("%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc)));
1670 switch (FC_SUBTYPE(fc)) {
1671 case CTRL_CONTROL_WRAPPER:
1672 /* XXX - requires special handling */
1673 break;
1674 case CTRL_BAR:
1675 ND_TCHECK_LEN(p, CTRL_BAR_HDRLEN);
1676 if (!ndo->ndo_eflag)
1677 ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1678 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
1679 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
1680 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
1681 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
1682 break;
1683 case CTRL_BA:
1684 ND_TCHECK_LEN(p, CTRL_BA_HDRLEN);
1685 if (!ndo->ndo_eflag)
1686 ND_PRINT(" RA:%s ",
1687 GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
1688 break;
1689 case CTRL_PS_POLL:
1690 ND_TCHECK_LEN(p, CTRL_PS_POLL_HDRLEN);
1691 ND_PRINT(" AID(%x)",
1692 GET_LE_U_2(((const struct ctrl_ps_poll_hdr_t *)p)->aid));
1693 break;
1694 case CTRL_RTS:
1695 ND_TCHECK_LEN(p, CTRL_RTS_HDRLEN);
1696 if (!ndo->ndo_eflag)
1697 ND_PRINT(" TA:%s ",
1698 GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
1699 break;
1700 case CTRL_CTS:
1701 ND_TCHECK_LEN(p, CTRL_CTS_HDRLEN);
1702 if (!ndo->ndo_eflag)
1703 ND_PRINT(" RA:%s ",
1704 GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
1705 break;
1706 case CTRL_ACK:
1707 ND_TCHECK_LEN(p, CTRL_ACK_HDRLEN);
1708 if (!ndo->ndo_eflag)
1709 ND_PRINT(" RA:%s ",
1710 GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
1711 break;
1712 case CTRL_CF_END:
1713 ND_TCHECK_LEN(p, CTRL_END_HDRLEN);
1714 if (!ndo->ndo_eflag)
1715 ND_PRINT(" RA:%s ",
1716 GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra));
1717 break;
1718 case CTRL_END_ACK:
1719 ND_TCHECK_LEN(p, CTRL_END_ACK_HDRLEN);
1720 if (!ndo->ndo_eflag)
1721 ND_PRINT(" RA:%s ",
1722 GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra));
1723 break;
1724 }
1725 return 1;
1726 trunc:
1727 return 0;
1728 }
1729
1730 /*
1731 * Data Frame - Address field contents
1732 *
1733 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1734 * 0 | 0 | DA | SA | BSSID | n/a
1735 * 0 | 1 | DA | BSSID | SA | n/a
1736 * 1 | 0 | BSSID | SA | DA | n/a
1737 * 1 | 1 | RA | TA | DA | SA
1738 */
1739
1740 /*
1741 * Function to get source and destination MAC addresses for a data frame.
1742 */
1743 static void
1744 get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp,
1745 const uint8_t **dstp)
1746 {
1747 #define ADDR1 (p + 4)
1748 #define ADDR2 (p + 10)
1749 #define ADDR3 (p + 16)
1750 #define ADDR4 (p + 24)
1751
1752 if (!FC_TO_DS(fc)) {
1753 if (!FC_FROM_DS(fc)) {
1754 /* not To DS and not From DS */
1755 *srcp = ADDR2;
1756 *dstp = ADDR1;
1757 } else {
1758 /* not To DS and From DS */
1759 *srcp = ADDR3;
1760 *dstp = ADDR1;
1761 }
1762 } else {
1763 if (!FC_FROM_DS(fc)) {
1764 /* From DS and not To DS */
1765 *srcp = ADDR2;
1766 *dstp = ADDR3;
1767 } else {
1768 /* To DS and From DS */
1769 *srcp = ADDR4;
1770 *dstp = ADDR3;
1771 }
1772 }
1773
1774 #undef ADDR1
1775 #undef ADDR2
1776 #undef ADDR3
1777 #undef ADDR4
1778 }
1779
1780 static void
1781 get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp)
1782 {
1783 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1784
1785 if (srcp != NULL)
1786 *srcp = hp->sa;
1787 if (dstp != NULL)
1788 *dstp = hp->da;
1789 }
1790
1791 /*
1792 * Print Header funcs
1793 */
1794
1795 static void
1796 data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1797 {
1798 u_int subtype = FC_SUBTYPE(fc);
1799
1800 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1801 DATA_FRAME_IS_QOS(subtype)) {
1802 ND_PRINT("CF ");
1803 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1804 if (DATA_FRAME_IS_CF_POLL(subtype))
1805 ND_PRINT("Ack/Poll");
1806 else
1807 ND_PRINT("Ack");
1808 } else {
1809 if (DATA_FRAME_IS_CF_POLL(subtype))
1810 ND_PRINT("Poll");
1811 }
1812 if (DATA_FRAME_IS_QOS(subtype))
1813 ND_PRINT("+QoS");
1814 ND_PRINT(" ");
1815 }
1816
1817 #define ADDR1 (p + 4)
1818 #define ADDR2 (p + 10)
1819 #define ADDR3 (p + 16)
1820 #define ADDR4 (p + 24)
1821
1822 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1823 ND_PRINT("DA:%s SA:%s BSSID:%s ",
1824 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1825 GET_ETHERADDR_STRING(ADDR3));
1826 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1827 ND_PRINT("DA:%s BSSID:%s SA:%s ",
1828 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1829 GET_ETHERADDR_STRING(ADDR3));
1830 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1831 ND_PRINT("BSSID:%s SA:%s DA:%s ",
1832 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1833 GET_ETHERADDR_STRING(ADDR3));
1834 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1835 ND_PRINT("RA:%s TA:%s DA:%s SA:%s ",
1836 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1837 GET_ETHERADDR_STRING(ADDR3), GET_ETHERADDR_STRING(ADDR4));
1838 }
1839
1840 #undef ADDR1
1841 #undef ADDR2
1842 #undef ADDR3
1843 #undef ADDR4
1844 }
1845
1846 static void
1847 mgmt_header_print(netdissect_options *ndo, const u_char *p)
1848 {
1849 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1850
1851 ND_PRINT("BSSID:%s DA:%s SA:%s ",
1852 GET_ETHERADDR_STRING((hp)->bssid), GET_ETHERADDR_STRING((hp)->da),
1853 GET_ETHERADDR_STRING((hp)->sa));
1854 }
1855
1856 static void
1857 ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1858 {
1859 switch (FC_SUBTYPE(fc)) {
1860 case CTRL_BAR:
1861 ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1862 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
1863 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
1864 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
1865 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
1866 break;
1867 case CTRL_BA:
1868 ND_PRINT("RA:%s ",
1869 GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
1870 break;
1871 case CTRL_PS_POLL:
1872 ND_PRINT("BSSID:%s TA:%s ",
1873 GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
1874 GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta));
1875 break;
1876 case CTRL_RTS:
1877 ND_PRINT("RA:%s TA:%s ",
1878 GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ra),
1879 GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
1880 break;
1881 case CTRL_CTS:
1882 ND_PRINT("RA:%s ",
1883 GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
1884 break;
1885 case CTRL_ACK:
1886 ND_PRINT("RA:%s ",
1887 GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
1888 break;
1889 case CTRL_CF_END:
1890 ND_PRINT("RA:%s BSSID:%s ",
1891 GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra),
1892 GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->bssid));
1893 break;
1894 case CTRL_END_ACK:
1895 ND_PRINT("RA:%s BSSID:%s ",
1896 GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra),
1897 GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid));
1898 break;
1899 default:
1900 /* We shouldn't get here - we should already have quit */
1901 break;
1902 }
1903 }
1904
1905 static int
1906 extract_header_length(netdissect_options *ndo,
1907 uint16_t fc)
1908 {
1909 int len;
1910
1911 switch (FC_TYPE(fc)) {
1912 case T_MGMT:
1913 return MGMT_HDRLEN;
1914 case T_CTRL:
1915 switch (FC_SUBTYPE(fc)) {
1916 case CTRL_CONTROL_WRAPPER:
1917 return CTRL_CONTROL_WRAPPER_HDRLEN;
1918 case CTRL_BAR:
1919 return CTRL_BAR_HDRLEN;
1920 case CTRL_BA:
1921 return CTRL_BA_HDRLEN;
1922 case CTRL_PS_POLL:
1923 return CTRL_PS_POLL_HDRLEN;
1924 case CTRL_RTS:
1925 return CTRL_RTS_HDRLEN;
1926 case CTRL_CTS:
1927 return CTRL_CTS_HDRLEN;
1928 case CTRL_ACK:
1929 return CTRL_ACK_HDRLEN;
1930 case CTRL_CF_END:
1931 return CTRL_END_HDRLEN;
1932 case CTRL_END_ACK:
1933 return CTRL_END_ACK_HDRLEN;
1934 default:
1935 ND_PRINT("unknown 802.11 ctrl frame subtype (%u)", FC_SUBTYPE(fc));
1936 return 0;
1937 }
1938 case T_DATA:
1939 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1940 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1941 len += 2;
1942 return len;
1943 default:
1944 ND_PRINT("unknown 802.11 frame type (%u)", FC_TYPE(fc));
1945 return 0;
1946 }
1947 }
1948
1949 static int
1950 extract_mesh_header_length(netdissect_options *ndo, const u_char *p)
1951 {
1952 return (GET_U_1(p) &~ 3) ? 0 : 6*(1 + (GET_U_1(p) & 3));
1953 }
1954
1955 /*
1956 * Print the 802.11 MAC header.
1957 */
1958 static void
1959 ieee_802_11_hdr_print(netdissect_options *ndo,
1960 uint16_t fc, const u_char *p, u_int hdrlen,
1961 u_int meshdrlen)
1962 {
1963 if (ndo->ndo_vflag) {
1964 if (FC_MORE_DATA(fc))
1965 ND_PRINT("More Data ");
1966 if (FC_MORE_FLAG(fc))
1967 ND_PRINT("More Fragments ");
1968 if (FC_POWER_MGMT(fc))
1969 ND_PRINT("Pwr Mgmt ");
1970 if (FC_RETRY(fc))
1971 ND_PRINT("Retry ");
1972 if (FC_ORDER(fc))
1973 ND_PRINT("Strictly Ordered ");
1974 if (FC_PROTECTED(fc))
1975 ND_PRINT("Protected ");
1976 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1977 ND_PRINT("%uus ",
1978 GET_LE_U_2(((const struct mgmt_header_t *)p)->duration));
1979 }
1980 if (meshdrlen != 0) {
1981 const struct meshcntl_t *mc =
1982 (const struct meshcntl_t *)(p + hdrlen - meshdrlen);
1983 u_int ae = GET_U_1(mc->flags) & 3;
1984
1985 ND_PRINT("MeshData (AE %u TTL %u seq %u", ae,
1986 GET_U_1(mc->ttl), GET_LE_U_4(mc->seq));
1987 if (ae > 0)
1988 ND_PRINT(" A4:%s", GET_ETHERADDR_STRING(mc->addr4));
1989 if (ae > 1)
1990 ND_PRINT(" A5:%s", GET_ETHERADDR_STRING(mc->addr5));
1991 if (ae > 2)
1992 ND_PRINT(" A6:%s", GET_ETHERADDR_STRING(mc->addr6));
1993 ND_PRINT(") ");
1994 }
1995
1996 switch (FC_TYPE(fc)) {
1997 case T_MGMT:
1998 mgmt_header_print(ndo, p);
1999 break;
2000 case T_CTRL:
2001 ctrl_header_print(ndo, fc, p);
2002 break;
2003 case T_DATA:
2004 data_header_print(ndo, fc, p);
2005 break;
2006 default:
2007 break;
2008 }
2009 }
2010
2011 static u_int
2012 ieee802_11_print(netdissect_options *ndo,
2013 const u_char *p, u_int length, u_int orig_caplen, int pad,
2014 u_int fcslen)
2015 {
2016 uint16_t fc;
2017 u_int caplen, hdrlen, meshdrlen;
2018 struct lladdr_info src, dst;
2019 int llc_hdrlen;
2020
2021 ndo->ndo_protocol = "802.11";
2022 caplen = orig_caplen;
2023 /* Remove FCS, if present */
2024 if (length < fcslen) {
2025 nd_print_trunc(ndo);
2026 return caplen;
2027 }
2028 length -= fcslen;
2029 if (caplen > length) {
2030 /* Amount of FCS in actual packet data, if any */
2031 fcslen = caplen - length;
2032 caplen -= fcslen;
2033 ndo->ndo_snapend -= fcslen;
2034 }
2035
2036 if (caplen < IEEE802_11_FC_LEN) {
2037 nd_print_trunc(ndo);
2038 return orig_caplen;
2039 }
2040
2041 fc = GET_LE_U_2(p);
2042 hdrlen = extract_header_length(ndo, fc);
2043 if (hdrlen == 0) {
2044 /* Unknown frame type or control frame subtype; quit. */
2045 return (0);
2046 }
2047 if (pad)
2048 hdrlen = roundup2(hdrlen, 4);
2049 if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
2050 DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
2051 if(!ND_TTEST_1(p + hdrlen)) {
2052 nd_print_trunc(ndo);
2053 return hdrlen;
2054 }
2055 meshdrlen = extract_mesh_header_length(ndo, p + hdrlen);
2056 hdrlen += meshdrlen;
2057 } else
2058 meshdrlen = 0;
2059
2060 if (caplen < hdrlen) {
2061 nd_print_trunc(ndo);
2062 return hdrlen;
2063 }
2064
2065 if (ndo->ndo_eflag)
2066 ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
2067
2068 /*
2069 * Go past the 802.11 header.
2070 */
2071 length -= hdrlen;
2072 caplen -= hdrlen;
2073 p += hdrlen;
2074
2075 src.addr_string = etheraddr_string;
2076 dst.addr_string = etheraddr_string;
2077 switch (FC_TYPE(fc)) {
2078 case T_MGMT:
2079 get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
2080 if (!mgmt_body_print(ndo, fc, src.addr, p, length)) {
2081 nd_print_trunc(ndo);
2082 return hdrlen;
2083 }
2084 break;
2085 case T_CTRL:
2086 if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
2087 nd_print_trunc(ndo);
2088 return hdrlen;
2089 }
2090 break;
2091 case T_DATA:
2092 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
2093 return hdrlen; /* no-data frame */
2094 /* There may be a problem w/ AP not having this bit set */
2095 if (FC_PROTECTED(fc)) {
2096 ND_PRINT("Data");
2097 if (!wep_print(ndo, p)) {
2098 nd_print_trunc(ndo);
2099 return hdrlen;
2100 }
2101 } else {
2102 get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr);
2103 llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
2104 if (llc_hdrlen < 0) {
2105 /*
2106 * Some kinds of LLC packet we cannot
2107 * handle intelligently
2108 */
2109 if (!ndo->ndo_suppress_default_print)
2110 ND_DEFAULTPRINT(p, caplen);
2111 llc_hdrlen = -llc_hdrlen;
2112 }
2113 hdrlen += llc_hdrlen;
2114 }
2115 break;
2116 default:
2117 /* We shouldn't get here - we should already have quit */
2118 break;
2119 }
2120
2121 return hdrlen;
2122 }
2123
2124 /*
2125 * This is the top level routine of the printer. 'p' points
2126 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
2127 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
2128 * is the number of bytes actually captured.
2129 */
2130 u_int
2131 ieee802_11_if_print(netdissect_options *ndo,
2132 const struct pcap_pkthdr *h, const u_char *p)
2133 {
2134 ndo->ndo_protocol = "802.11_if";
2135 return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
2136 }
2137
2138
2139 /* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
2140 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */
2141
2142 /*-
2143 * Copyright (c) 2003, 2004 David Young. All rights reserved.
2144 *
2145 * Redistribution and use in source and binary forms, with or without
2146 * modification, are permitted provided that the following conditions
2147 * are met:
2148 * 1. Redistributions of source code must retain the above copyright
2149 * notice, this list of conditions and the following disclaimer.
2150 * 2. Redistributions in binary form must reproduce the above copyright
2151 * notice, this list of conditions and the following disclaimer in the
2152 * documentation and/or other materials provided with the distribution.
2153 * 3. The name of David Young may not be used to endorse or promote
2154 * products derived from this software without specific prior
2155 * written permission.
2156 *
2157 * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
2158 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2159 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2160 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
2161 * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2162 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2163 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2164 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2165 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2166 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2167 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
2168 * OF SUCH DAMAGE.
2169 */
2170
2171 /* A generic radio capture format is desirable. It must be
2172 * rigidly defined (e.g., units for fields should be given),
2173 * and easily extensible.
2174 *
2175 * The following is an extensible radio capture format. It is
2176 * based on a bitmap indicating which fields are present.
2177 *
2178 * I am trying to describe precisely what the application programmer
2179 * should expect in the following, and for that reason I tell the
2180 * units and origin of each measurement (where it applies), or else I
2181 * use sufficiently weaselly language ("is a monotonically nondecreasing
2182 * function of...") that I cannot set false expectations for lawyerly
2183 * readers.
2184 */
2185
2186 /*
2187 * The radio capture header precedes the 802.11 header.
2188 *
2189 * Note well: all radiotap fields are little-endian.
2190 */
2191 struct ieee80211_radiotap_header {
2192 nd_uint8_t it_version; /* Version 0. Only increases
2193 * for drastic changes,
2194 * introduction of compatible
2195 * new fields does not count.
2196 */
2197 nd_uint8_t it_pad;
2198 nd_uint16_t it_len; /* length of the whole
2199 * header in bytes, including
2200 * it_version, it_pad,
2201 * it_len, and data fields.
2202 */
2203 nd_uint32_t it_present; /* A bitmap telling which
2204 * fields are present. Set bit 31
2205 * (0x80000000) to extend the
2206 * bitmap by another 32 bits.
2207 * Additional extensions are made
2208 * by setting bit 31.
2209 */
2210 };
2211
2212 /* Name Data type Units
2213 * ---- --------- -----
2214 *
2215 * IEEE80211_RADIOTAP_TSFT uint64_t microseconds
2216 *
2217 * Value in microseconds of the MAC's 64-bit 802.11 Time
2218 * Synchronization Function timer when the first bit of the
2219 * MPDU arrived at the MAC. For received frames, only.
2220 *
2221 * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap
2222 *
2223 * Tx/Rx frequency in MHz, followed by flags (see below).
2224 * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
2225 * represent an HT channel as there is not enough room in
2226 * the flags word.
2227 *
2228 * IEEE80211_RADIOTAP_FHSS uint16_t see below
2229 *
2230 * For frequency-hopping radios, the hop set (first byte)
2231 * and pattern (second byte).
2232 *
2233 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index
2234 *
2235 * Tx/Rx data rate. If bit 0x80 is set then it represents an
2236 * an MCS index and not an IEEE rate.
2237 *
2238 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
2239 * one milliwatt (dBm)
2240 *
2241 * RF signal power at the antenna, decibel difference from
2242 * one milliwatt.
2243 *
2244 * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
2245 * one milliwatt (dBm)
2246 *
2247 * RF noise power at the antenna, decibel difference from one
2248 * milliwatt.
2249 *
2250 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
2251 *
2252 * RF signal power at the antenna, decibel difference from an
2253 * arbitrary, fixed reference.
2254 *
2255 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
2256 *
2257 * RF noise power at the antenna, decibel difference from an
2258 * arbitrary, fixed reference point.
2259 *
2260 * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless
2261 *
2262 * Quality of Barker code lock. Unitless. Monotonically
2263 * nondecreasing with "better" lock strength. Called "Signal
2264 * Quality" in datasheets. (Is there a standard way to measure
2265 * this?)
2266 *
2267 * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless
2268 *
2269 * Transmit power expressed as unitless distance from max
2270 * power set at factory calibration. 0 is max power.
2271 * Monotonically nondecreasing with lower power levels.
2272 *
2273 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB)
2274 *
2275 * Transmit power expressed as decibel distance from max power
2276 * set at factory calibration. 0 is max power. Monotonically
2277 * nondecreasing with lower power levels.
2278 *
2279 * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
2280 * one milliwatt (dBm)
2281 *
2282 * Transmit power expressed as dBm (decibels from a 1 milliwatt
2283 * reference). This is the absolute power level measured at
2284 * the antenna port.
2285 *
2286 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap
2287 *
2288 * Properties of transmitted and received frames. See flags
2289 * defined below.
2290 *
2291 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
2292 *
2293 * Unitless indication of the Rx/Tx antenna for this packet.
2294 * The first antenna is antenna 0.
2295 *
2296 * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap
2297 *
2298 * Properties of received frames. See flags defined below.
2299 *
2300 * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap
2301 * uint16_t MHz
2302 * uint8_t channel number
2303 * uint8_t .5 dBm
2304 *
2305 * Extended channel specification: flags (see below) followed by
2306 * frequency in MHz, the corresponding IEEE channel number, and
2307 * finally the maximum regulatory transmit power cap in .5 dBm
2308 * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL
2309 * and only one of the two should be present.
2310 *
2311 * IEEE80211_RADIOTAP_MCS uint8_t known
2312 * uint8_t flags
2313 * uint8_t mcs
2314 *
2315 * Bitset indicating which fields have known values, followed
2316 * by bitset of flag values, followed by the MCS rate index as
2317 * in IEEE 802.11n.
2318 *
2319 *
2320 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless
2321 *
2322 * Contains the AMPDU information for the subframe.
2323 *
2324 * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16
2325 *
2326 * Contains VHT information about this frame.
2327 *
2328 * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
2329 * uint8_t OUI[3]
2330 * uint8_t subspace
2331 * uint16_t length
2332 *
2333 * The Vendor Namespace Field contains three sub-fields. The first
2334 * sub-field is 3 bytes long. It contains the vendor's IEEE 802
2335 * Organizationally Unique Identifier (OUI). The fourth byte is a
2336 * vendor-specific "namespace selector."
2337 *
2338 */
2339 enum ieee80211_radiotap_type {
2340 IEEE80211_RADIOTAP_TSFT = 0,
2341 IEEE80211_RADIOTAP_FLAGS = 1,
2342 IEEE80211_RADIOTAP_RATE = 2,
2343 IEEE80211_RADIOTAP_CHANNEL = 3,
2344 IEEE80211_RADIOTAP_FHSS = 4,
2345 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
2346 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
2347 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
2348 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
2349 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
2350 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
2351 IEEE80211_RADIOTAP_ANTENNA = 11,
2352 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
2353 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
2354 IEEE80211_RADIOTAP_RX_FLAGS = 14,
2355 /* NB: gap for netbsd definitions */
2356 IEEE80211_RADIOTAP_XCHANNEL = 18,
2357 IEEE80211_RADIOTAP_MCS = 19,
2358 IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
2359 IEEE80211_RADIOTAP_VHT = 21,
2360 IEEE80211_RADIOTAP_NAMESPACE = 29,
2361 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
2362 IEEE80211_RADIOTAP_EXT = 31
2363 };
2364
2365 /* channel attributes */
2366 #define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */
2367 #define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */
2368 #define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */
2369 #define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */
2370 #define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */
2371 #define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */
2372 #define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */
2373 #define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */
2374 #define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */
2375 #define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */
2376 #define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */
2377 #define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */
2378 #define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */
2379 #define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */
2380 #define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */
2381
2382 /* Useful combinations of channel characteristics, borrowed from Ethereal */
2383 #define IEEE80211_CHAN_A \
2384 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2385 #define IEEE80211_CHAN_B \
2386 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2387 #define IEEE80211_CHAN_G \
2388 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2389 #define IEEE80211_CHAN_TA \
2390 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
2391 #define IEEE80211_CHAN_TG \
2392 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO)
2393
2394
2395 /* For IEEE80211_RADIOTAP_FLAGS */
2396 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
2397 * during CFP
2398 */
2399 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
2400 * with short
2401 * preamble
2402 */
2403 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
2404 * with WEP encryption
2405 */
2406 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
2407 * with fragmentation
2408 */
2409 #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
2410 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
2411 * 802.11 header and payload
2412 * (to 32-bit boundary)
2413 */
2414 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */
2415
2416 /* For IEEE80211_RADIOTAP_RX_FLAGS */
2417 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
2418 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */
2419
2420 /* For IEEE80211_RADIOTAP_MCS known */
2421 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01
2422 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */
2423 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04
2424 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08
2425 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10
2426 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20
2427 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN 0x40
2428 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1 0x80
2429
2430 /* For IEEE80211_RADIOTAP_MCS flags */
2431 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03
2432 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0
2433 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1
2434 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2
2435 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3
2436 #define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */
2437 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08
2438 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
2439 #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60
2440 #define IEEE80211_RADIOTAP_MCS_STBC_1 1
2441 #define IEEE80211_RADIOTAP_MCS_STBC_2 2
2442 #define IEEE80211_RADIOTAP_MCS_STBC_3 3
2443 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5
2444 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0 0x80
2445
2446 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */
2447 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001
2448 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002
2449 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004
2450 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008
2451 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010
2452 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020
2453
2454 /* For IEEE80211_RADIOTAP_VHT known */
2455 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN 0x0001
2456 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN 0x0002
2457 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN 0x0004
2458 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN 0x0008
2459 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN 0x0010
2460 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN 0x0020
2461 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN 0x0040
2462 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN 0x0080
2463 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN 0x0100
2464
2465 /* For IEEE80211_RADIOTAP_VHT flags */
2466 #define IEEE80211_RADIOTAP_VHT_STBC 0x01
2467 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA 0x02
2468 #define IEEE80211_RADIOTAP_VHT_SHORT_GI 0x04
2469 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9 0x08
2470 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM 0x10
2471 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED 0x20
2472
2473 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK 0x1f
2474
2475 #define IEEE80211_RADIOTAP_VHT_NSS_MASK 0x0f
2476 #define IEEE80211_RADIOTAP_VHT_MCS_MASK 0xf0
2477 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT 4
2478
2479 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn 0x01
2480
2481 #define IEEE80211_CHAN_FHSS \
2482 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
2483 #define IEEE80211_CHAN_A \
2484 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2485 #define IEEE80211_CHAN_B \
2486 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2487 #define IEEE80211_CHAN_PUREG \
2488 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
2489 #define IEEE80211_CHAN_G \
2490 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2491
2492 #define IS_CHAN_FHSS(flags) \
2493 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
2494 #define IS_CHAN_A(flags) \
2495 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
2496 #define IS_CHAN_B(flags) \
2497 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
2498 #define IS_CHAN_PUREG(flags) \
2499 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
2500 #define IS_CHAN_G(flags) \
2501 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2502 #define IS_CHAN_ANYG(flags) \
2503 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
2504
2505 static void
2506 print_chaninfo(netdissect_options *ndo,
2507 uint16_t freq, int flags, int presentflags)
2508 {
2509 ND_PRINT("%u MHz", freq);
2510 if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) {
2511 /*
2512 * We have the MCS field, so this is 11n, regardless
2513 * of what the channel flags say.
2514 */
2515 ND_PRINT(" 11n");
2516 } else {
2517 if (IS_CHAN_FHSS(flags))
2518 ND_PRINT(" FHSS");
2519 if (IS_CHAN_A(flags)) {
2520 if (flags & IEEE80211_CHAN_HALF)
2521 ND_PRINT(" 11a/10Mhz");
2522 else if (flags & IEEE80211_CHAN_QUARTER)
2523 ND_PRINT(" 11a/5Mhz");
2524 else
2525 ND_PRINT(" 11a");
2526 }
2527 if (IS_CHAN_ANYG(flags)) {
2528 if (flags & IEEE80211_CHAN_HALF)
2529 ND_PRINT(" 11g/10Mhz");
2530 else if (flags & IEEE80211_CHAN_QUARTER)
2531 ND_PRINT(" 11g/5Mhz");
2532 else
2533 ND_PRINT(" 11g");
2534 } else if (IS_CHAN_B(flags))
2535 ND_PRINT(" 11b");
2536 if (flags & IEEE80211_CHAN_TURBO)
2537 ND_PRINT(" Turbo");
2538 }
2539 /*
2540 * These apply to 11n.
2541 */
2542 if (flags & IEEE80211_CHAN_HT20)
2543 ND_PRINT(" ht/20");
2544 else if (flags & IEEE80211_CHAN_HT40D)
2545 ND_PRINT(" ht/40-");
2546 else if (flags & IEEE80211_CHAN_HT40U)
2547 ND_PRINT(" ht/40+");
2548 ND_PRINT(" ");
2549 }
2550
2551 static int
2552 print_radiotap_field(netdissect_options *ndo,
2553 struct cpack_state *s, uint32_t bit, uint8_t *flagsp,
2554 uint32_t presentflags)
2555 {
2556 u_int i;
2557 int rc;
2558
2559 switch (bit) {
2560
2561 case IEEE80211_RADIOTAP_TSFT: {
2562 uint64_t tsft;
2563
2564 rc = cpack_uint64(ndo, s, &tsft);
2565 if (rc != 0)
2566 goto trunc;
2567 ND_PRINT("%" PRIu64 "us tsft ", tsft);
2568 break;
2569 }
2570
2571 case IEEE80211_RADIOTAP_FLAGS: {
2572 uint8_t flagsval;
2573
2574 rc = cpack_uint8(ndo, s, &flagsval);
2575 if (rc != 0)
2576 goto trunc;
2577 *flagsp = flagsval;
2578 if (flagsval & IEEE80211_RADIOTAP_F_CFP)
2579 ND_PRINT("cfp ");
2580 if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE)
2581 ND_PRINT("short preamble ");
2582 if (flagsval & IEEE80211_RADIOTAP_F_WEP)
2583 ND_PRINT("wep ");
2584 if (flagsval & IEEE80211_RADIOTAP_F_FRAG)
2585 ND_PRINT("fragmented ");
2586 if (flagsval & IEEE80211_RADIOTAP_F_BADFCS)
2587 ND_PRINT("bad-fcs ");
2588 break;
2589 }
2590
2591 case IEEE80211_RADIOTAP_RATE: {
2592 uint8_t rate;
2593
2594 rc = cpack_uint8(ndo, s, &rate);
2595 if (rc != 0)
2596 goto trunc;
2597 /*
2598 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2599 * Linux and AirPcap it does not. (What about
2600 * macOS, NetBSD, OpenBSD, and DragonFly BSD?)
2601 *
2602 * This is an issue either for proprietary extensions
2603 * to 11a or 11g, which do exist, or for 11n
2604 * implementations that stuff a rate value into
2605 * this field, which also appear to exist.
2606 *
2607 * We currently handle that by assuming that
2608 * if the 0x80 bit is set *and* the remaining
2609 * bits have a value between 0 and 15 it's
2610 * an MCS value, otherwise it's a rate. If
2611 * there are cases where systems that use
2612 * "0x80 + MCS index" for MCS indices > 15,
2613 * or stuff a rate value here between 64 and
2614 * 71.5 Mb/s in here, we'll need a preference
2615 * setting. Such rates do exist, e.g. 11n
2616 * MCS 7 at 20 MHz with a long guard interval.
2617 */
2618 if (rate >= 0x80 && rate <= 0x8f) {
2619 /*
2620 * XXX - we don't know the channel width
2621 * or guard interval length, so we can't
2622 * convert this to a data rate.
2623 *
2624 * If you want us to show a data rate,
2625 * use the MCS field, not the Rate field;
2626 * the MCS field includes not only the
2627 * MCS index, it also includes bandwidth
2628 * and guard interval information.
2629 *
2630 * XXX - can we get the channel width
2631 * from XChannel and the guard interval
2632 * information from Flags, at least on
2633 * FreeBSD?
2634 */
2635 ND_PRINT("MCS %u ", rate & 0x7f);
2636 } else
2637 ND_PRINT("%2.1f Mb/s ", .5 * rate);
2638 break;
2639 }
2640
2641 case IEEE80211_RADIOTAP_CHANNEL: {
2642 uint16_t frequency;
2643 uint16_t flags;
2644
2645 rc = cpack_uint16(ndo, s, &frequency);
2646 if (rc != 0)
2647 goto trunc;
2648 rc = cpack_uint16(ndo, s, &flags);
2649 if (rc != 0)
2650 goto trunc;
2651 /*
2652 * If CHANNEL and XCHANNEL are both present, skip
2653 * CHANNEL.
2654 */
2655 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2656 break;
2657 print_chaninfo(ndo, frequency, flags, presentflags);
2658 break;
2659 }
2660
2661 case IEEE80211_RADIOTAP_FHSS: {
2662 uint8_t hopset;
2663 uint8_t hoppat;
2664
2665 rc = cpack_uint8(ndo, s, &hopset);
2666 if (rc != 0)
2667 goto trunc;
2668 rc = cpack_uint8(ndo, s, &hoppat);
2669 if (rc != 0)
2670 goto trunc;
2671 ND_PRINT("fhset %u fhpat %u ", hopset, hoppat);
2672 break;
2673 }
2674
2675 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: {
2676 int8_t dbm_antsignal;
2677
2678 rc = cpack_int8(ndo, s, &dbm_antsignal);
2679 if (rc != 0)
2680 goto trunc;
2681 ND_PRINT("%ddBm signal ", dbm_antsignal);
2682 break;
2683 }
2684
2685 case IEEE80211_RADIOTAP_DBM_ANTNOISE: {
2686 int8_t dbm_antnoise;
2687
2688 rc = cpack_int8(ndo, s, &dbm_antnoise);
2689 if (rc != 0)
2690 goto trunc;
2691 ND_PRINT("%ddBm noise ", dbm_antnoise);
2692 break;
2693 }
2694
2695 case IEEE80211_RADIOTAP_LOCK_QUALITY: {
2696 uint16_t lock_quality;
2697
2698 rc = cpack_uint16(ndo, s, &lock_quality);
2699 if (rc != 0)
2700 goto trunc;
2701 ND_PRINT("%u sq ", lock_quality);
2702 break;
2703 }
2704
2705 case IEEE80211_RADIOTAP_TX_ATTENUATION: {
2706 int16_t tx_attenuation;
2707
2708 rc = cpack_int16(ndo, s, &tx_attenuation);
2709 if (rc != 0)
2710 goto trunc;
2711 ND_PRINT("%d tx power ", -tx_attenuation);
2712 break;
2713 }
2714
2715 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: {
2716 int8_t db_tx_attenuation;
2717
2718 rc = cpack_int8(ndo, s, &db_tx_attenuation);
2719 if (rc != 0)
2720 goto trunc;
2721 ND_PRINT("%ddB tx attenuation ", -db_tx_attenuation);
2722 break;
2723 }
2724
2725 case IEEE80211_RADIOTAP_DBM_TX_POWER: {
2726 int8_t dbm_tx_power;
2727
2728 rc = cpack_int8(ndo, s, &dbm_tx_power);
2729 if (rc != 0)
2730 goto trunc;
2731 ND_PRINT("%ddBm tx power ", dbm_tx_power);
2732 break;
2733 }
2734
2735 case IEEE80211_RADIOTAP_ANTENNA: {
2736 uint8_t antenna;
2737
2738 rc = cpack_uint8(ndo, s, &antenna);
2739 if (rc != 0)
2740 goto trunc;
2741 ND_PRINT("antenna %u ", antenna);
2742 break;
2743 }
2744
2745 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: {
2746 uint8_t db_antsignal;
2747
2748 rc = cpack_uint8(ndo, s, &db_antsignal);
2749 if (rc != 0)
2750 goto trunc;
2751 ND_PRINT("%udB signal ", db_antsignal);
2752 break;
2753 }
2754
2755 case IEEE80211_RADIOTAP_DB_ANTNOISE: {
2756 uint8_t db_antnoise;
2757
2758 rc = cpack_uint8(ndo, s, &db_antnoise);
2759 if (rc != 0)
2760 goto trunc;
2761 ND_PRINT("%udB noise ", db_antnoise);
2762 break;
2763 }
2764
2765 case IEEE80211_RADIOTAP_RX_FLAGS: {
2766 uint16_t rx_flags;
2767
2768 rc = cpack_uint16(ndo, s, &rx_flags);
2769 if (rc != 0)
2770 goto trunc;
2771 /* Do nothing for now */
2772 break;
2773 }
2774
2775 case IEEE80211_RADIOTAP_XCHANNEL: {
2776 uint32_t flags;
2777 uint16_t frequency;
2778 uint8_t channel;
2779 uint8_t maxpower;
2780
2781 rc = cpack_uint32(ndo, s, &flags);
2782 if (rc != 0)
2783 goto trunc;
2784 rc = cpack_uint16(ndo, s, &frequency);
2785 if (rc != 0)
2786 goto trunc;
2787 rc = cpack_uint8(ndo, s, &channel);
2788 if (rc != 0)
2789 goto trunc;
2790 rc = cpack_uint8(ndo, s, &maxpower);
2791 if (rc != 0)
2792 goto trunc;
2793 print_chaninfo(ndo, frequency, flags, presentflags);
2794 break;
2795 }
2796
2797 case IEEE80211_RADIOTAP_MCS: {
2798 uint8_t known;
2799 uint8_t flags;
2800 uint8_t mcs_index;
2801 static const char *ht_bandwidth[4] = {
2802 "20 MHz",
2803 "40 MHz",
2804 "20 MHz (L)",
2805 "20 MHz (U)"
2806 };
2807 float htrate;
2808
2809 rc = cpack_uint8(ndo, s, &known);
2810 if (rc != 0)
2811 goto trunc;
2812 rc = cpack_uint8(ndo, s, &flags);
2813 if (rc != 0)
2814 goto trunc;
2815 rc = cpack_uint8(ndo, s, &mcs_index);
2816 if (rc != 0)
2817 goto trunc;
2818 if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2819 /*
2820 * We know the MCS index.
2821 */
2822 if (mcs_index <= MAX_MCS_INDEX) {
2823 /*
2824 * And it's in-range.
2825 */
2826 if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2827 /*
2828 * And we know both the bandwidth and
2829 * the guard interval, so we can look
2830 * up the rate.
2831 */
2832 htrate =
2833 ieee80211_float_htrates
2834 [mcs_index]
2835 [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)]
2836 [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2837 } else {
2838 /*
2839 * We don't know both the bandwidth
2840 * and the guard interval, so we can
2841 * only report the MCS index.
2842 */
2843 htrate = 0.0;
2844 }
2845 } else {
2846 /*
2847 * The MCS value is out of range.
2848 */
2849 htrate = 0.0;
2850 }
2851 if (htrate != 0.0) {
2852 /*
2853 * We have the rate.
2854 * Print it.
2855 */
2856 ND_PRINT("%.1f Mb/s MCS %u ", htrate, mcs_index);
2857 } else {
2858 /*
2859 * We at least have the MCS index.
2860 * Print it.
2861 */
2862 ND_PRINT("MCS %u ", mcs_index);
2863 }
2864 }
2865 if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2866 ND_PRINT("%s ",
2867 ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
2868 }
2869 if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2870 ND_PRINT("%s GI ",
2871 (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2872 "short" : "long");
2873 }
2874 if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2875 ND_PRINT("%s ",
2876 (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2877 "greenfield" : "mixed");
2878 }
2879 if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2880 ND_PRINT("%s FEC ",
2881 (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2882 "LDPC" : "BCC");
2883 }
2884 if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
2885 ND_PRINT("RX-STBC%u ",
2886 (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
2887 }
2888 break;
2889 }
2890
2891 case IEEE80211_RADIOTAP_AMPDU_STATUS: {
2892 uint32_t reference_num;
2893 uint16_t flags;
2894 uint8_t delim_crc;
2895 uint8_t reserved;
2896
2897 rc = cpack_uint32(ndo, s, &reference_num);
2898 if (rc != 0)
2899 goto trunc;
2900 rc = cpack_uint16(ndo, s, &flags);
2901 if (rc != 0)
2902 goto trunc;
2903 rc = cpack_uint8(ndo, s, &delim_crc);
2904 if (rc != 0)
2905 goto trunc;
2906 rc = cpack_uint8(ndo, s, &reserved);
2907 if (rc != 0)
2908 goto trunc;
2909 /* Do nothing for now */
2910 break;
2911 }
2912
2913 case IEEE80211_RADIOTAP_VHT: {
2914 uint16_t known;
2915 uint8_t flags;
2916 uint8_t bandwidth;
2917 uint8_t mcs_nss[4];
2918 uint8_t coding;
2919 uint8_t group_id;
2920 uint16_t partial_aid;
2921 static const char *vht_bandwidth[32] = {
2922 "20 MHz",
2923 "40 MHz",
2924 "20 MHz (L)",
2925 "20 MHz (U)",
2926 "80 MHz",
2927 "80 MHz (L)",
2928 "80 MHz (U)",
2929 "80 MHz (LL)",
2930 "80 MHz (LU)",
2931 "80 MHz (UL)",
2932 "80 MHz (UU)",
2933 "160 MHz",
2934 "160 MHz (L)",
2935 "160 MHz (U)",
2936 "160 MHz (LL)",
2937 "160 MHz (LU)",
2938 "160 MHz (UL)",
2939 "160 MHz (UU)",
2940 "160 MHz (LLL)",
2941 "160 MHz (LLU)",
2942 "160 MHz (LUL)",
2943 "160 MHz (UUU)",
2944 "160 MHz (ULL)",
2945 "160 MHz (ULU)",
2946 "160 MHz (UUL)",
2947 "160 MHz (UUU)",
2948 "unknown (26)",
2949 "unknown (27)",
2950 "unknown (28)",
2951 "unknown (29)",
2952 "unknown (30)",
2953 "unknown (31)"
2954 };
2955
2956 rc = cpack_uint16(ndo, s, &known);
2957 if (rc != 0)
2958 goto trunc;
2959 rc = cpack_uint8(ndo, s, &flags);
2960 if (rc != 0)
2961 goto trunc;
2962 rc = cpack_uint8(ndo, s, &bandwidth);
2963 if (rc != 0)
2964 goto trunc;
2965 for (i = 0; i < 4; i++) {
2966 rc = cpack_uint8(ndo, s, &mcs_nss[i]);
2967 if (rc != 0)
2968 goto trunc;
2969 }
2970 rc = cpack_uint8(ndo, s, &coding);
2971 if (rc != 0)
2972 goto trunc;
2973 rc = cpack_uint8(ndo, s, &group_id);
2974 if (rc != 0)
2975 goto trunc;
2976 rc = cpack_uint16(ndo, s, &partial_aid);
2977 if (rc != 0)
2978 goto trunc;
2979 for (i = 0; i < 4; i++) {
2980 u_int nss, mcs;
2981 nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK;
2982 mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT;
2983
2984 if (nss == 0)
2985 continue;
2986
2987 ND_PRINT("User %u MCS %u ", i, mcs);
2988 ND_PRINT("%s FEC ",
2989 (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ?
2990 "LDPC" : "BCC");
2991 }
2992 if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) {
2993 ND_PRINT("%s ",
2994 vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]);
2995 }
2996 if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) {
2997 ND_PRINT("%s GI ",
2998 (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ?
2999 "short" : "long");
3000 }
3001 break;
3002 }
3003
3004 default:
3005 /* this bit indicates a field whose
3006 * size we do not know, so we cannot
3007 * proceed. Just print the bit number.
3008 */
3009 ND_PRINT("[bit %u] ", bit);
3010 return -1;
3011 }
3012
3013 return 0;
3014
3015 trunc:
3016 nd_print_trunc(ndo);
3017 return rc;
3018 }
3019
3020
3021 static int
3022 print_in_radiotap_namespace(netdissect_options *ndo,
3023 struct cpack_state *s, uint8_t *flags,
3024 uint32_t presentflags, int bit0)
3025 {
3026 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
3027 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
3028 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
3029 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
3030 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
3031 uint32_t present, next_present;
3032 int bitno;
3033 enum ieee80211_radiotap_type bit;
3034 int rc;
3035
3036 for (present = presentflags; present; present = next_present) {
3037 /*
3038 * Clear the least significant bit that is set.
3039 */
3040 next_present = present & (present - 1);
3041
3042 /*
3043 * Get the bit number, within this presence word,
3044 * of the remaining least significant bit that
3045 * is set.
3046 */
3047 bitno = BITNO_32(present ^ next_present);
3048
3049 /*
3050 * Stop if this is one of the "same meaning
3051 * in all presence flags" bits.
3052 */
3053 if (bitno >= IEEE80211_RADIOTAP_NAMESPACE)
3054 break;
3055
3056 /*
3057 * Get the radiotap bit number of that bit.
3058 */
3059 bit = (enum ieee80211_radiotap_type)(bit0 + bitno);
3060
3061 rc = print_radiotap_field(ndo, s, bit, flags, presentflags);
3062 if (rc != 0)
3063 return rc;
3064 }
3065
3066 return 0;
3067 }
3068
3069 u_int
3070 ieee802_11_radio_print(netdissect_options *ndo,
3071 const u_char *p, u_int length, u_int caplen)
3072 {
3073 #define BIT(n) (1U << n)
3074 #define IS_EXTENDED(__p) \
3075 (GET_LE_U_4(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
3076
3077 struct cpack_state cpacker;
3078 const struct ieee80211_radiotap_header *hdr;
3079 uint32_t presentflags;
3080 const nd_uint32_t *presentp, *last_presentp;
3081 int vendor_namespace;
3082 uint8_t vendor_oui[3];
3083 uint8_t vendor_subnamespace;
3084 uint16_t skip_length;
3085 int bit0;
3086 u_int len;
3087 uint8_t flags;
3088 int pad;
3089 u_int fcslen;
3090
3091 ndo->ndo_protocol = "802.11_radio";
3092 if (caplen < sizeof(*hdr)) {
3093 nd_print_trunc(ndo);
3094 return caplen;
3095 }
3096
3097 hdr = (const struct ieee80211_radiotap_header *)p;
3098
3099 len = GET_LE_U_2(hdr->it_len);
3100 if (len < sizeof(*hdr)) {
3101 /*
3102 * The length is the length of the entire header, so
3103 * it must be as large as the fixed-length part of
3104 * the header.
3105 */
3106 nd_print_trunc(ndo);
3107 return caplen;
3108 }
3109
3110 /*
3111 * If we don't have the entire radiotap header, just give up.
3112 */
3113 if (caplen < len) {
3114 nd_print_trunc(ndo);
3115 return caplen;
3116 }
3117 cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */
3118 cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
3119 for (last_presentp = &hdr->it_present;
3120 (const u_char*)(last_presentp + 1) <= p + len &&
3121 IS_EXTENDED(last_presentp);
3122 last_presentp++)
3123 cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
3124
3125 /* are there more bitmap extensions than bytes in header? */
3126 if ((const u_char*)(last_presentp + 1) > p + len) {
3127 nd_print_trunc(ndo);
3128 return caplen;
3129 }
3130
3131 /*
3132 * Start out at the beginning of the default radiotap namespace.
3133 */
3134 bit0 = 0;
3135 vendor_namespace = 0;
3136 memset(vendor_oui, 0, 3);
3137 vendor_subnamespace = 0;
3138 skip_length = 0;
3139 /* Assume no flags */
3140 flags = 0;
3141 /* Assume no Atheros padding between 802.11 header and body */
3142 pad = 0;
3143 /* Assume no FCS at end of frame */
3144 fcslen = 0;
3145 for (presentp = &hdr->it_present; presentp <= last_presentp;
3146 presentp++) {
3147 presentflags = GET_LE_U_4(presentp);
3148
3149 /*
3150 * If this is a vendor namespace, we don't handle it.
3151 */
3152 if (vendor_namespace) {
3153 /*
3154 * Skip past the stuff we don't understand.
3155 * If we add support for any vendor namespaces,
3156 * it'd be added here; use vendor_oui and
3157 * vendor_subnamespace to interpret the fields.
3158 */
3159 if (cpack_advance(&cpacker, skip_length) != 0) {
3160 /*
3161 * Ran out of space in the packet.
3162 */
3163 break;
3164 }
3165
3166 /*
3167 * We've skipped it all; nothing more to
3168 * skip.
3169 */
3170 skip_length = 0;
3171 } else {
3172 if (print_in_radiotap_namespace(ndo, &cpacker,
3173 &flags, presentflags, bit0) != 0) {
3174 /*
3175 * Fatal error - can't process anything
3176 * more in the radiotap header.
3177 */
3178 break;
3179 }
3180 }
3181
3182 /*
3183 * Handle the namespace switch bits; we've already handled
3184 * the extension bit in all but the last word above.
3185 */
3186 switch (presentflags &
3187 (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) {
3188
3189 case 0:
3190 /*
3191 * We're not changing namespaces.
3192 * advance to the next 32 bits in the current
3193 * namespace.
3194 */
3195 bit0 += 32;
3196 break;
3197
3198 case BIT(IEEE80211_RADIOTAP_NAMESPACE):
3199 /*
3200 * We're switching to the radiotap namespace.
3201 * Reset the presence-bitmap index to 0, and
3202 * reset the namespace to the default radiotap
3203 * namespace.
3204 */
3205 bit0 = 0;
3206 vendor_namespace = 0;
3207 memset(vendor_oui, 0, 3);
3208 vendor_subnamespace = 0;
3209 skip_length = 0;
3210 break;
3211
3212 case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE):
3213 /*
3214 * We're switching to a vendor namespace.
3215 * Reset the presence-bitmap index to 0,
3216 * note that we're in a vendor namespace,
3217 * and fetch the fields of the Vendor Namespace
3218 * item.
3219 */
3220 bit0 = 0;
3221 vendor_namespace = 1;
3222 if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) {
3223 nd_print_trunc(ndo);
3224 break;
3225 }
3226 if (cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) {
3227 nd_print_trunc(ndo);
3228 break;
3229 }
3230 if (cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) {
3231 nd_print_trunc(ndo);
3232 break;
3233 }
3234 if (cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) {
3235 nd_print_trunc(ndo);
3236 break;
3237 }
3238 if (cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) {
3239 nd_print_trunc(ndo);
3240 break;
3241 }
3242 if (cpack_uint16(ndo, &cpacker, &skip_length) != 0) {
3243 nd_print_trunc(ndo);
3244 break;
3245 }
3246 break;
3247
3248 default:
3249 /*
3250 * Illegal combination. The behavior in this
3251 * case is undefined by the radiotap spec; we
3252 * just ignore both bits.
3253 */
3254 break;
3255 }
3256 }
3257
3258 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
3259 pad = 1; /* Atheros padding */
3260 if (flags & IEEE80211_RADIOTAP_F_FCS)
3261 fcslen = 4; /* FCS at end of packet */
3262 return len + ieee802_11_print(ndo, p + len, length - len, caplen - len, pad,
3263 fcslen);
3264 #undef BITNO_32
3265 #undef BITNO_16
3266 #undef BITNO_8
3267 #undef BITNO_4
3268 #undef BITNO_2
3269 #undef BIT
3270 }
3271
3272 static u_int
3273 ieee802_11_radio_avs_print(netdissect_options *ndo,
3274 const u_char *p, u_int length, u_int caplen)
3275 {
3276 uint32_t caphdr_len;
3277
3278 ndo->ndo_protocol = "802.11_radio_avs";
3279 if (caplen < 8) {
3280 nd_print_trunc(ndo);
3281 return caplen;
3282 }
3283
3284 caphdr_len = GET_BE_U_4(p + 4);
3285 if (caphdr_len < 8) {
3286 /*
3287 * Yow! The capture header length is claimed not
3288 * to be large enough to include even the version
3289 * cookie or capture header length!
3290 */
3291 nd_print_trunc(ndo);
3292 return caplen;
3293 }
3294
3295 if (caplen < caphdr_len) {
3296 nd_print_trunc(ndo);
3297 return caplen;
3298 }
3299
3300 return caphdr_len + ieee802_11_print(ndo, p + caphdr_len,
3301 length - caphdr_len, caplen - caphdr_len, 0, 0);
3302 }
3303
3304 #define PRISM_HDR_LEN 144
3305
3306 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
3307 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
3308 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
3309
3310 /*
3311 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
3312 * containing information such as radio information, which we
3313 * currently ignore.
3314 *
3315 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
3316 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
3317 * (currently, on Linux, there's no ARPHRD_ type for
3318 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
3319 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
3320 * the AVS header, and the first 4 bytes of the header are used to
3321 * indicate whether it's a Prism header or an AVS header).
3322 */
3323 u_int
3324 prism_if_print(netdissect_options *ndo,
3325 const struct pcap_pkthdr *h, const u_char *p)
3326 {
3327 u_int caplen = h->caplen;
3328 u_int length = h->len;
3329 uint32_t msgcode;
3330
3331 ndo->ndo_protocol = "prism_if";
3332 if (caplen < 4) {
3333 nd_print_trunc(ndo);
3334 return caplen;
3335 }
3336
3337 msgcode = GET_BE_U_4(p);
3338 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
3339 msgcode == WLANCAP_MAGIC_COOKIE_V2)
3340 return ieee802_11_radio_avs_print(ndo, p, length, caplen);
3341
3342 if (caplen < PRISM_HDR_LEN) {
3343 nd_print_trunc(ndo);
3344 return caplen;
3345 }
3346
3347 return PRISM_HDR_LEN + ieee802_11_print(ndo, p + PRISM_HDR_LEN,
3348 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
3349 }
3350
3351 /*
3352 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
3353 * header, containing information such as radio information.
3354 */
3355 u_int
3356 ieee802_11_radio_if_print(netdissect_options *ndo,
3357 const struct pcap_pkthdr *h, const u_char *p)
3358 {
3359 ndo->ndo_protocol = "802.11_radio_if";
3360 return ieee802_11_radio_print(ndo, p, h->len, h->caplen);
3361 }
3362
3363 /*
3364 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
3365 * extra header, containing information such as radio information,
3366 * which we currently ignore.
3367 */
3368 u_int
3369 ieee802_11_radio_avs_if_print(netdissect_options *ndo,
3370 const struct pcap_pkthdr *h, const u_char *p)
3371 {
3372 ndo->ndo_protocol = "802.11_radio_avs_if";
3373 return ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen);
3374 }