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