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