]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
Handle very large -f files by rejecting them.
[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 memcpy(&ssid.ssid, p + offset, ssid.length);
1043 offset += ssid.length;
1044 length -= ssid.length;
1045 }
1046 ssid.ssid[ssid.length] = '\0';
1047 /*
1048 * Present and not truncated.
1049 *
1050 * If we haven't already seen an SSID IE,
1051 * copy this one, otherwise ignore this one,
1052 * so we later report the first one we saw.
1053 */
1054 if (!pbody->ssid_present) {
1055 pbody->ssid = ssid;
1056 pbody->ssid_present = 1;
1057 }
1058 break;
1059 case E_CHALLENGE:
1060 memcpy(&challenge, p + offset, 2);
1061 offset += 2;
1062 length -= 2;
1063 if (challenge.length != 0) {
1064 if (challenge.length >
1065 sizeof(challenge.text) - 1)
1066 return 0;
1067 memcpy(&challenge.text, p + offset,
1068 challenge.length);
1069 offset += challenge.length;
1070 length -= challenge.length;
1071 }
1072 challenge.text[challenge.length] = '\0';
1073 /*
1074 * Present and not truncated.
1075 *
1076 * If we haven't already seen a challenge IE,
1077 * copy this one, otherwise ignore this one,
1078 * so we later report the first one we saw.
1079 */
1080 if (!pbody->challenge_present) {
1081 pbody->challenge = challenge;
1082 pbody->challenge_present = 1;
1083 }
1084 break;
1085 case E_RATES:
1086 memcpy(&rates, p + offset, 2);
1087 offset += 2;
1088 length -= 2;
1089 if (rates.length != 0) {
1090 if (rates.length > sizeof rates.rate)
1091 return 0;
1092 memcpy(&rates.rate, p + offset, rates.length);
1093 offset += rates.length;
1094 length -= rates.length;
1095 }
1096 /*
1097 * Present and not truncated.
1098 *
1099 * If we haven't already seen a rates IE,
1100 * copy this one if it's not zero-length,
1101 * otherwise ignore this one, so we later
1102 * report the first one we saw.
1103 *
1104 * We ignore zero-length rates IEs as some
1105 * devices seem to put a zero-length rates
1106 * IE, followed by an SSID IE, followed by
1107 * a non-zero-length rates IE into frames,
1108 * even though IEEE Std 802.11-2007 doesn't
1109 * seem to indicate that a zero-length rates
1110 * IE is valid.
1111 */
1112 if (!pbody->rates_present && rates.length != 0) {
1113 pbody->rates = rates;
1114 pbody->rates_present = 1;
1115 }
1116 break;
1117 case E_DS:
1118 memcpy(&ds, p + offset, 2);
1119 offset += 2;
1120 length -= 2;
1121 if (ds.length != 1) {
1122 offset += ds.length;
1123 length -= ds.length;
1124 break;
1125 }
1126 ds.channel = *(p + offset);
1127 offset += 1;
1128 length -= 1;
1129 /*
1130 * Present and not truncated.
1131 *
1132 * If we haven't already seen a DS IE,
1133 * copy this one, otherwise ignore this one,
1134 * so we later report the first one we saw.
1135 */
1136 if (!pbody->ds_present) {
1137 pbody->ds = ds;
1138 pbody->ds_present = 1;
1139 }
1140 break;
1141 case E_CF:
1142 memcpy(&cf, p + offset, 2);
1143 offset += 2;
1144 length -= 2;
1145 if (cf.length != 6) {
1146 offset += cf.length;
1147 length -= cf.length;
1148 break;
1149 }
1150 memcpy(&cf.count, p + offset, 6);
1151 offset += 6;
1152 length -= 6;
1153 /*
1154 * Present and not truncated.
1155 *
1156 * If we haven't already seen a CF IE,
1157 * copy this one, otherwise ignore this one,
1158 * so we later report the first one we saw.
1159 */
1160 if (!pbody->cf_present) {
1161 pbody->cf = cf;
1162 pbody->cf_present = 1;
1163 }
1164 break;
1165 case E_TIM:
1166 memcpy(&tim, p + offset, 2);
1167 offset += 2;
1168 length -= 2;
1169 if (tim.length <= 3) {
1170 offset += tim.length;
1171 length -= tim.length;
1172 break;
1173 }
1174 if (tim.length - 3 > (int)sizeof tim.bitmap)
1175 return 0;
1176 memcpy(&tim.count, p + offset, 3);
1177 offset += 3;
1178 length -= 3;
1179
1180 memcpy(tim.bitmap, p + offset, tim.length - 3);
1181 offset += tim.length - 3;
1182 length -= tim.length - 3;
1183 /*
1184 * Present and not truncated.
1185 *
1186 * If we haven't already seen a TIM IE,
1187 * copy this one, otherwise ignore this one,
1188 * so we later report the first one we saw.
1189 */
1190 if (!pbody->tim_present) {
1191 pbody->tim = tim;
1192 pbody->tim_present = 1;
1193 }
1194 break;
1195 default:
1196 #if 0
1197 ND_PRINT((ndo, "(1) unhandled element_id (%d) ",
1198 *(p + offset)));
1199 #endif
1200 offset += 2 + elementlen;
1201 length -= 2 + elementlen;
1202 break;
1203 }
1204 }
1205
1206 /* No problems found. */
1207 return 1;
1208 }
1209
1210 /*********************************************************************************
1211 * Print Handle functions for the management frame types
1212 *********************************************************************************/
1213
1214 static int
1215 handle_beacon(netdissect_options *ndo,
1216 const u_char *p, u_int length)
1217 {
1218 struct mgmt_body_t pbody;
1219 int offset = 0;
1220 int ret;
1221
1222 memset(&pbody, 0, sizeof(pbody));
1223
1224 if (!ND_TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1225 IEEE802_11_CAPINFO_LEN))
1226 return 0;
1227 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1228 IEEE802_11_CAPINFO_LEN)
1229 return 0;
1230 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1231 offset += IEEE802_11_TSTAMP_LEN;
1232 length -= IEEE802_11_TSTAMP_LEN;
1233 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
1234 offset += IEEE802_11_BCNINT_LEN;
1235 length -= IEEE802_11_BCNINT_LEN;
1236 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
1237 offset += IEEE802_11_CAPINFO_LEN;
1238 length -= IEEE802_11_CAPINFO_LEN;
1239
1240 ret = parse_elements(ndo, &pbody, p, offset, length);
1241
1242 PRINT_SSID(pbody);
1243 PRINT_RATES(pbody);
1244 ND_PRINT((ndo, " %s",
1245 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"));
1246 PRINT_DS_CHANNEL(pbody);
1247
1248 return ret;
1249 }
1250
1251 static int
1252 handle_assoc_request(netdissect_options *ndo,
1253 const u_char *p, u_int length)
1254 {
1255 struct mgmt_body_t pbody;
1256 int offset = 0;
1257 int ret;
1258
1259 memset(&pbody, 0, sizeof(pbody));
1260
1261 if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
1262 return 0;
1263 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
1264 return 0;
1265 pbody.capability_info = EXTRACT_LE_16BITS(p);
1266 offset += IEEE802_11_CAPINFO_LEN;
1267 length -= IEEE802_11_CAPINFO_LEN;
1268 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
1269 offset += IEEE802_11_LISTENINT_LEN;
1270 length -= IEEE802_11_LISTENINT_LEN;
1271
1272 ret = parse_elements(ndo, &pbody, p, offset, length);
1273
1274 PRINT_SSID(pbody);
1275 PRINT_RATES(pbody);
1276 return ret;
1277 }
1278
1279 static int
1280 handle_assoc_response(netdissect_options *ndo,
1281 const u_char *p, u_int length)
1282 {
1283 struct mgmt_body_t pbody;
1284 int offset = 0;
1285 int ret;
1286
1287 memset(&pbody, 0, sizeof(pbody));
1288
1289 if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1290 IEEE802_11_AID_LEN))
1291 return 0;
1292 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1293 IEEE802_11_AID_LEN)
1294 return 0;
1295 pbody.capability_info = EXTRACT_LE_16BITS(p);
1296 offset += IEEE802_11_CAPINFO_LEN;
1297 length -= IEEE802_11_CAPINFO_LEN;
1298 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
1299 offset += IEEE802_11_STATUS_LEN;
1300 length -= IEEE802_11_STATUS_LEN;
1301 pbody.aid = EXTRACT_LE_16BITS(p+offset);
1302 offset += IEEE802_11_AID_LEN;
1303 length -= IEEE802_11_AID_LEN;
1304
1305 ret = parse_elements(ndo, &pbody, p, offset, length);
1306
1307 ND_PRINT((ndo, " AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 ,
1308 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
1309 (pbody.status_code < NUM_STATUSES
1310 ? status_text[pbody.status_code]
1311 : "n/a")));
1312
1313 return ret;
1314 }
1315
1316 static int
1317 handle_reassoc_request(netdissect_options *ndo,
1318 const u_char *p, u_int length)
1319 {
1320 struct mgmt_body_t pbody;
1321 int offset = 0;
1322 int ret;
1323
1324 memset(&pbody, 0, sizeof(pbody));
1325
1326 if (!ND_TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1327 IEEE802_11_AP_LEN))
1328 return 0;
1329 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1330 IEEE802_11_AP_LEN)
1331 return 0;
1332 pbody.capability_info = EXTRACT_LE_16BITS(p);
1333 offset += IEEE802_11_CAPINFO_LEN;
1334 length -= IEEE802_11_CAPINFO_LEN;
1335 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
1336 offset += IEEE802_11_LISTENINT_LEN;
1337 length -= IEEE802_11_LISTENINT_LEN;
1338 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1339 offset += IEEE802_11_AP_LEN;
1340 length -= IEEE802_11_AP_LEN;
1341
1342 ret = parse_elements(ndo, &pbody, p, offset, length);
1343
1344 PRINT_SSID(pbody);
1345 ND_PRINT((ndo, " AP : %s", etheraddr_string(ndo, pbody.ap )));
1346
1347 return ret;
1348 }
1349
1350 static int
1351 handle_reassoc_response(netdissect_options *ndo,
1352 const u_char *p, u_int length)
1353 {
1354 /* Same as a Association Reponse */
1355 return handle_assoc_response(ndo, p, length);
1356 }
1357
1358 static int
1359 handle_probe_request(netdissect_options *ndo,
1360 const u_char *p, u_int length)
1361 {
1362 struct mgmt_body_t pbody;
1363 int offset = 0;
1364 int ret;
1365
1366 memset(&pbody, 0, sizeof(pbody));
1367
1368 ret = parse_elements(ndo, &pbody, p, offset, length);
1369
1370 PRINT_SSID(pbody);
1371 PRINT_RATES(pbody);
1372
1373 return ret;
1374 }
1375
1376 static int
1377 handle_probe_response(netdissect_options *ndo,
1378 const u_char *p, u_int length)
1379 {
1380 struct mgmt_body_t pbody;
1381 int offset = 0;
1382 int ret;
1383
1384 memset(&pbody, 0, sizeof(pbody));
1385
1386 if (!ND_TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1387 IEEE802_11_CAPINFO_LEN))
1388 return 0;
1389 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1390 IEEE802_11_CAPINFO_LEN)
1391 return 0;
1392 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1393 offset += IEEE802_11_TSTAMP_LEN;
1394 length -= IEEE802_11_TSTAMP_LEN;
1395 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
1396 offset += IEEE802_11_BCNINT_LEN;
1397 length -= IEEE802_11_BCNINT_LEN;
1398 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
1399 offset += IEEE802_11_CAPINFO_LEN;
1400 length -= IEEE802_11_CAPINFO_LEN;
1401
1402 ret = parse_elements(ndo, &pbody, p, offset, length);
1403
1404 PRINT_SSID(pbody);
1405 PRINT_RATES(pbody);
1406 PRINT_DS_CHANNEL(pbody);
1407
1408 return ret;
1409 }
1410
1411 static int
1412 handle_atim(void)
1413 {
1414 /* the frame body for ATIM is null. */
1415 return 1;
1416 }
1417
1418 static int
1419 handle_disassoc(netdissect_options *ndo,
1420 const u_char *p, u_int length)
1421 {
1422 struct mgmt_body_t pbody;
1423
1424 memset(&pbody, 0, sizeof(pbody));
1425
1426 if (!ND_TTEST2(*p, IEEE802_11_REASON_LEN))
1427 return 0;
1428 if (length < IEEE802_11_REASON_LEN)
1429 return 0;
1430 pbody.reason_code = EXTRACT_LE_16BITS(p);
1431
1432 ND_PRINT((ndo, ": %s",
1433 (pbody.reason_code < NUM_REASONS)
1434 ? reason_text[pbody.reason_code]
1435 : "Reserved"));
1436
1437 return 1;
1438 }
1439
1440 static int
1441 handle_auth(netdissect_options *ndo,
1442 const u_char *p, u_int length)
1443 {
1444 struct mgmt_body_t pbody;
1445 int offset = 0;
1446 int ret;
1447
1448 memset(&pbody, 0, sizeof(pbody));
1449
1450 if (!ND_TTEST2(*p, 6))
1451 return 0;
1452 if (length < 6)
1453 return 0;
1454 pbody.auth_alg = EXTRACT_LE_16BITS(p);
1455 offset += 2;
1456 length -= 2;
1457 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
1458 offset += 2;
1459 length -= 2;
1460 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
1461 offset += 2;
1462 length -= 2;
1463
1464 ret = parse_elements(ndo, &pbody, p, offset, length);
1465
1466 if ((pbody.auth_alg == 1) &&
1467 ((pbody.auth_trans_seq_num == 2) ||
1468 (pbody.auth_trans_seq_num == 3))) {
1469 ND_PRINT((ndo, " (%s)-%x [Challenge Text] %s",
1470 (pbody.auth_alg < NUM_AUTH_ALGS)
1471 ? auth_alg_text[pbody.auth_alg]
1472 : "Reserved",
1473 pbody.auth_trans_seq_num,
1474 ((pbody.auth_trans_seq_num % 2)
1475 ? ((pbody.status_code < NUM_STATUSES)
1476 ? status_text[pbody.status_code]
1477 : "n/a") : "")));
1478 return ret;
1479 }
1480 ND_PRINT((ndo, " (%s)-%x: %s",
1481 (pbody.auth_alg < NUM_AUTH_ALGS)
1482 ? auth_alg_text[pbody.auth_alg]
1483 : "Reserved",
1484 pbody.auth_trans_seq_num,
1485 (pbody.auth_trans_seq_num % 2)
1486 ? ((pbody.status_code < NUM_STATUSES)
1487 ? status_text[pbody.status_code]
1488 : "n/a")
1489 : ""));
1490
1491 return ret;
1492 }
1493
1494 static int
1495 handle_deauth(netdissect_options *ndo,
1496 const uint8_t *src, const u_char *p, u_int length)
1497 {
1498 struct mgmt_body_t pbody;
1499 const char *reason = NULL;
1500
1501 memset(&pbody, 0, sizeof(pbody));
1502
1503 if (!ND_TTEST2(*p, IEEE802_11_REASON_LEN))
1504 return 0;
1505 if (length < IEEE802_11_REASON_LEN)
1506 return 0;
1507 pbody.reason_code = EXTRACT_LE_16BITS(p);
1508
1509 reason = (pbody.reason_code < NUM_REASONS)
1510 ? reason_text[pbody.reason_code]
1511 : "Reserved";
1512
1513 if (ndo->ndo_eflag) {
1514 ND_PRINT((ndo, ": %s", reason));
1515 } else {
1516 ND_PRINT((ndo, " (%s): %s", etheraddr_string(ndo, src), reason));
1517 }
1518 return 1;
1519 }
1520
1521 #define PRINT_HT_ACTION(v) (\
1522 (v) == 0 ? ND_PRINT((ndo, "TxChWidth")) : \
1523 (v) == 1 ? ND_PRINT((ndo, "MIMOPwrSave")) : \
1524 ND_PRINT((ndo, "Act#%d", (v))) \
1525 )
1526 #define PRINT_BA_ACTION(v) (\
1527 (v) == 0 ? ND_PRINT((ndo, "ADDBA Request")) : \
1528 (v) == 1 ? ND_PRINT((ndo, "ADDBA Response")) : \
1529 (v) == 2 ? ND_PRINT((ndo, "DELBA")) : \
1530 ND_PRINT((ndo, "Act#%d", (v))) \
1531 )
1532 #define PRINT_MESHLINK_ACTION(v) (\
1533 (v) == 0 ? ND_PRINT((ndo, "Request")) : \
1534 (v) == 1 ? ND_PRINT((ndo, "Report")) : \
1535 ND_PRINT((ndo, "Act#%d", (v))) \
1536 )
1537 #define PRINT_MESHPEERING_ACTION(v) (\
1538 (v) == 0 ? ND_PRINT((ndo, "Open")) : \
1539 (v) == 1 ? ND_PRINT((ndo, "Confirm")) : \
1540 (v) == 2 ? ND_PRINT((ndo, "Close")) : \
1541 ND_PRINT((ndo, "Act#%d", (v))) \
1542 )
1543 #define PRINT_MESHPATH_ACTION(v) (\
1544 (v) == 0 ? ND_PRINT((ndo, "Request")) : \
1545 (v) == 1 ? ND_PRINT((ndo, "Report")) : \
1546 (v) == 2 ? ND_PRINT((ndo, "Error")) : \
1547 (v) == 3 ? ND_PRINT((ndo, "RootAnnouncement")) : \
1548 ND_PRINT((ndo, "Act#%d", (v))) \
1549 )
1550
1551 #define PRINT_MESH_ACTION(v) (\
1552 (v) == 0 ? ND_PRINT((ndo, "MeshLink")) : \
1553 (v) == 1 ? ND_PRINT((ndo, "HWMP")) : \
1554 (v) == 2 ? ND_PRINT((ndo, "Gate Announcement")) : \
1555 (v) == 3 ? ND_PRINT((ndo, "Congestion Control")) : \
1556 (v) == 4 ? ND_PRINT((ndo, "MCCA Setup Request")) : \
1557 (v) == 5 ? ND_PRINT((ndo, "MCCA Setup Reply")) : \
1558 (v) == 6 ? ND_PRINT((ndo, "MCCA Advertisement Request")) : \
1559 (v) == 7 ? ND_PRINT((ndo, "MCCA Advertisement")) : \
1560 (v) == 8 ? ND_PRINT((ndo, "MCCA Teardown")) : \
1561 (v) == 9 ? ND_PRINT((ndo, "TBTT Adjustment Request")) : \
1562 (v) == 10 ? ND_PRINT((ndo, "TBTT Adjustment Response")) : \
1563 ND_PRINT((ndo, "Act#%d", (v))) \
1564 )
1565 #define PRINT_MULTIHOP_ACTION(v) (\
1566 (v) == 0 ? ND_PRINT((ndo, "Proxy Update")) : \
1567 (v) == 1 ? ND_PRINT((ndo, "Proxy Update Confirmation")) : \
1568 ND_PRINT((ndo, "Act#%d", (v))) \
1569 )
1570 #define PRINT_SELFPROT_ACTION(v) (\
1571 (v) == 1 ? ND_PRINT((ndo, "Peering Open")) : \
1572 (v) == 2 ? ND_PRINT((ndo, "Peering Confirm")) : \
1573 (v) == 3 ? ND_PRINT((ndo, "Peering Close")) : \
1574 (v) == 4 ? ND_PRINT((ndo, "Group Key Inform")) : \
1575 (v) == 5 ? ND_PRINT((ndo, "Group Key Acknowledge")) : \
1576 ND_PRINT((ndo, "Act#%d", (v))) \
1577 )
1578
1579 static int
1580 handle_action(netdissect_options *ndo,
1581 const uint8_t *src, const u_char *p, u_int length)
1582 {
1583 if (!ND_TTEST2(*p, 2))
1584 return 0;
1585 if (length < 2)
1586 return 0;
1587 if (ndo->ndo_eflag) {
1588 ND_PRINT((ndo, ": "));
1589 } else {
1590 ND_PRINT((ndo, " (%s): ", etheraddr_string(ndo, src)));
1591 }
1592 switch (p[0]) {
1593 case 0: ND_PRINT((ndo, "Spectrum Management Act#%d", p[1])); break;
1594 case 1: ND_PRINT((ndo, "QoS Act#%d", p[1])); break;
1595 case 2: ND_PRINT((ndo, "DLS Act#%d", p[1])); break;
1596 case 3: ND_PRINT((ndo, "BA ")); PRINT_BA_ACTION(p[1]); break;
1597 case 7: ND_PRINT((ndo, "HT ")); PRINT_HT_ACTION(p[1]); break;
1598 case 13: ND_PRINT((ndo, "MeshAction ")); PRINT_MESH_ACTION(p[1]); break;
1599 case 14:
1600 ND_PRINT((ndo, "MultiohopAction "));
1601 PRINT_MULTIHOP_ACTION(p[1]); break;
1602 case 15:
1603 ND_PRINT((ndo, "SelfprotectAction "));
1604 PRINT_SELFPROT_ACTION(p[1]); break;
1605 case 127: ND_PRINT((ndo, "Vendor Act#%d", p[1])); break;
1606 default:
1607 ND_PRINT((ndo, "Reserved(%d) Act#%d", p[0], p[1]));
1608 break;
1609 }
1610 return 1;
1611 }
1612
1613
1614 /*********************************************************************************
1615 * Print Body funcs
1616 *********************************************************************************/
1617
1618
1619 static int
1620 mgmt_body_print(netdissect_options *ndo,
1621 uint16_t fc, const uint8_t *src, const u_char *p, u_int length)
1622 {
1623 ND_PRINT((ndo, "%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc))));
1624
1625 /* There may be a problem w/ AP not having this bit set */
1626 if (FC_PROTECTED(fc))
1627 return wep_print(ndo, p);
1628 switch (FC_SUBTYPE(fc)) {
1629 case ST_ASSOC_REQUEST:
1630 return handle_assoc_request(ndo, p, length);
1631 case ST_ASSOC_RESPONSE:
1632 return handle_assoc_response(ndo, p, length);
1633 case ST_REASSOC_REQUEST:
1634 return handle_reassoc_request(ndo, p, length);
1635 case ST_REASSOC_RESPONSE:
1636 return handle_reassoc_response(ndo, p, length);
1637 case ST_PROBE_REQUEST:
1638 return handle_probe_request(ndo, p, length);
1639 case ST_PROBE_RESPONSE:
1640 return handle_probe_response(ndo, p, length);
1641 case ST_BEACON:
1642 return handle_beacon(ndo, p, length);
1643 case ST_ATIM:
1644 return handle_atim();
1645 case ST_DISASSOC:
1646 return handle_disassoc(ndo, p, length);
1647 case ST_AUTH:
1648 return handle_auth(ndo, p, length);
1649 case ST_DEAUTH:
1650 return handle_deauth(ndo, src, p, length);
1651 case ST_ACTION:
1652 return handle_action(ndo, src, p, length);
1653 default:
1654 return 1;
1655 }
1656 }
1657
1658
1659 /*********************************************************************************
1660 * Handles printing all the control frame types
1661 *********************************************************************************/
1662
1663 static int
1664 ctrl_body_print(netdissect_options *ndo,
1665 uint16_t fc, const u_char *p)
1666 {
1667 ND_PRINT((ndo, "%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc))));
1668 switch (FC_SUBTYPE(fc)) {
1669 case CTRL_CONTROL_WRAPPER:
1670 /* XXX - requires special handling */
1671 break;
1672 case CTRL_BAR:
1673 if (!ND_TTEST2(*p, CTRL_BAR_HDRLEN))
1674 return 0;
1675 if (!ndo->ndo_eflag)
1676 ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ",
1677 etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra),
1678 etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta),
1679 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)),
1680 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq))));
1681 break;
1682 case CTRL_BA:
1683 if (!ND_TTEST2(*p, CTRL_BA_HDRLEN))
1684 return 0;
1685 if (!ndo->ndo_eflag)
1686 ND_PRINT((ndo, " RA:%s ",
1687 etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra)));
1688 break;
1689 case CTRL_PS_POLL:
1690 if (!ND_TTEST2(*p, CTRL_PS_POLL_HDRLEN))
1691 return 0;
1692 ND_PRINT((ndo, " AID(%x)",
1693 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_hdr_t *)p)->aid))));
1694 break;
1695 case CTRL_RTS:
1696 if (!ND_TTEST2(*p, CTRL_RTS_HDRLEN))
1697 return 0;
1698 if (!ndo->ndo_eflag)
1699 ND_PRINT((ndo, " TA:%s ",
1700 etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta)));
1701 break;
1702 case CTRL_CTS:
1703 if (!ND_TTEST2(*p, CTRL_CTS_HDRLEN))
1704 return 0;
1705 if (!ndo->ndo_eflag)
1706 ND_PRINT((ndo, " RA:%s ",
1707 etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra)));
1708 break;
1709 case CTRL_ACK:
1710 if (!ND_TTEST2(*p, CTRL_ACK_HDRLEN))
1711 return 0;
1712 if (!ndo->ndo_eflag)
1713 ND_PRINT((ndo, " RA:%s ",
1714 etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra)));
1715 break;
1716 case CTRL_CF_END:
1717 if (!ND_TTEST2(*p, CTRL_END_HDRLEN))
1718 return 0;
1719 if (!ndo->ndo_eflag)
1720 ND_PRINT((ndo, " RA:%s ",
1721 etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra)));
1722 break;
1723 case CTRL_END_ACK:
1724 if (!ND_TTEST2(*p, CTRL_END_ACK_HDRLEN))
1725 return 0;
1726 if (!ndo->ndo_eflag)
1727 ND_PRINT((ndo, " RA:%s ",
1728 etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra)));
1729 break;
1730 }
1731 return 1;
1732 }
1733
1734 /*
1735 * Data Frame - Address field contents
1736 *
1737 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1738 * 0 | 0 | DA | SA | BSSID | n/a
1739 * 0 | 1 | DA | BSSID | SA | n/a
1740 * 1 | 0 | BSSID | SA | DA | n/a
1741 * 1 | 1 | RA | TA | DA | SA
1742 */
1743
1744 /*
1745 * Function to get source and destination MAC addresses for a data frame.
1746 */
1747 static void
1748 get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp,
1749 const uint8_t **dstp)
1750 {
1751 #define ADDR1 (p + 4)
1752 #define ADDR2 (p + 10)
1753 #define ADDR3 (p + 16)
1754 #define ADDR4 (p + 24)
1755
1756 if (!FC_TO_DS(fc)) {
1757 if (!FC_FROM_DS(fc)) {
1758 /* not To DS and not From DS */
1759 *srcp = ADDR2;
1760 *dstp = ADDR1;
1761 } else {
1762 /* not To DS and From DS */
1763 *srcp = ADDR3;
1764 *dstp = ADDR1;
1765 }
1766 } else {
1767 if (!FC_FROM_DS(fc)) {
1768 /* From DS and not To DS */
1769 *srcp = ADDR2;
1770 *dstp = ADDR3;
1771 } else {
1772 /* To DS and From DS */
1773 *srcp = ADDR4;
1774 *dstp = ADDR3;
1775 }
1776 }
1777
1778 #undef ADDR1
1779 #undef ADDR2
1780 #undef ADDR3
1781 #undef ADDR4
1782 }
1783
1784 static void
1785 get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp)
1786 {
1787 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1788
1789 if (srcp != NULL)
1790 *srcp = hp->sa;
1791 if (dstp != NULL)
1792 *dstp = hp->da;
1793 }
1794
1795 /*
1796 * Print Header funcs
1797 */
1798
1799 static void
1800 data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1801 {
1802 u_int subtype = FC_SUBTYPE(fc);
1803
1804 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1805 DATA_FRAME_IS_QOS(subtype)) {
1806 ND_PRINT((ndo, "CF "));
1807 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1808 if (DATA_FRAME_IS_CF_POLL(subtype))
1809 ND_PRINT((ndo, "Ack/Poll"));
1810 else
1811 ND_PRINT((ndo, "Ack"));
1812 } else {
1813 if (DATA_FRAME_IS_CF_POLL(subtype))
1814 ND_PRINT((ndo, "Poll"));
1815 }
1816 if (DATA_FRAME_IS_QOS(subtype))
1817 ND_PRINT((ndo, "+QoS"));
1818 ND_PRINT((ndo, " "));
1819 }
1820
1821 #define ADDR1 (p + 4)
1822 #define ADDR2 (p + 10)
1823 #define ADDR3 (p + 16)
1824 #define ADDR4 (p + 24)
1825
1826 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1827 ND_PRINT((ndo, "DA:%s SA:%s BSSID:%s ",
1828 etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1829 etheraddr_string(ndo, ADDR3)));
1830 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1831 ND_PRINT((ndo, "DA:%s BSSID:%s SA:%s ",
1832 etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1833 etheraddr_string(ndo, ADDR3)));
1834 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1835 ND_PRINT((ndo, "BSSID:%s SA:%s DA:%s ",
1836 etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1837 etheraddr_string(ndo, ADDR3)));
1838 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1839 ND_PRINT((ndo, "RA:%s TA:%s DA:%s SA:%s ",
1840 etheraddr_string(ndo, ADDR1), etheraddr_string(ndo, ADDR2),
1841 etheraddr_string(ndo, ADDR3), etheraddr_string(ndo, ADDR4)));
1842 }
1843
1844 #undef ADDR1
1845 #undef ADDR2
1846 #undef ADDR3
1847 #undef ADDR4
1848 }
1849
1850 static void
1851 mgmt_header_print(netdissect_options *ndo, const u_char *p)
1852 {
1853 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1854
1855 ND_PRINT((ndo, "BSSID:%s DA:%s SA:%s ",
1856 etheraddr_string(ndo, (hp)->bssid), etheraddr_string(ndo, (hp)->da),
1857 etheraddr_string(ndo, (hp)->sa)));
1858 }
1859
1860 static void
1861 ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1862 {
1863 switch (FC_SUBTYPE(fc)) {
1864 case CTRL_BAR:
1865 ND_PRINT((ndo, " RA:%s TA:%s CTL(%x) SEQ(%u) ",
1866 etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ra),
1867 etheraddr_string(ndo, ((const struct ctrl_bar_hdr_t *)p)->ta),
1868 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->ctl)),
1869 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_hdr_t *)p)->seq))));
1870 break;
1871 case CTRL_BA:
1872 ND_PRINT((ndo, "RA:%s ",
1873 etheraddr_string(ndo, ((const struct ctrl_ba_hdr_t *)p)->ra)));
1874 break;
1875 case CTRL_PS_POLL:
1876 ND_PRINT((ndo, "BSSID:%s TA:%s ",
1877 etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
1878 etheraddr_string(ndo, ((const struct ctrl_ps_poll_hdr_t *)p)->ta)));
1879 break;
1880 case CTRL_RTS:
1881 ND_PRINT((ndo, "RA:%s TA:%s ",
1882 etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ra),
1883 etheraddr_string(ndo, ((const struct ctrl_rts_hdr_t *)p)->ta)));
1884 break;
1885 case CTRL_CTS:
1886 ND_PRINT((ndo, "RA:%s ",
1887 etheraddr_string(ndo, ((const struct ctrl_cts_hdr_t *)p)->ra)));
1888 break;
1889 case CTRL_ACK:
1890 ND_PRINT((ndo, "RA:%s ",
1891 etheraddr_string(ndo, ((const struct ctrl_ack_hdr_t *)p)->ra)));
1892 break;
1893 case CTRL_CF_END:
1894 ND_PRINT((ndo, "RA:%s BSSID:%s ",
1895 etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->ra),
1896 etheraddr_string(ndo, ((const struct ctrl_end_hdr_t *)p)->bssid)));
1897 break;
1898 case CTRL_END_ACK:
1899 ND_PRINT((ndo, "RA:%s BSSID:%s ",
1900 etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->ra),
1901 etheraddr_string(ndo, ((const struct ctrl_end_ack_hdr_t *)p)->bssid)));
1902 break;
1903 default:
1904 /* We shouldn't get here - we should already have quit */
1905 break;
1906 }
1907 }
1908
1909 static int
1910 extract_header_length(netdissect_options *ndo,
1911 uint16_t fc)
1912 {
1913 int len;
1914
1915 switch (FC_TYPE(fc)) {
1916 case T_MGMT:
1917 return MGMT_HDRLEN;
1918 case T_CTRL:
1919 switch (FC_SUBTYPE(fc)) {
1920 case CTRL_CONTROL_WRAPPER:
1921 return CTRL_CONTROL_WRAPPER_HDRLEN;
1922 case CTRL_BAR:
1923 return CTRL_BAR_HDRLEN;
1924 case CTRL_BA:
1925 return CTRL_BA_HDRLEN;
1926 case CTRL_PS_POLL:
1927 return CTRL_PS_POLL_HDRLEN;
1928 case CTRL_RTS:
1929 return CTRL_RTS_HDRLEN;
1930 case CTRL_CTS:
1931 return CTRL_CTS_HDRLEN;
1932 case CTRL_ACK:
1933 return CTRL_ACK_HDRLEN;
1934 case CTRL_CF_END:
1935 return CTRL_END_HDRLEN;
1936 case CTRL_END_ACK:
1937 return CTRL_END_ACK_HDRLEN;
1938 default:
1939 ND_PRINT((ndo, "unknown 802.11 ctrl frame subtype (%d)", FC_SUBTYPE(fc)));
1940 return 0;
1941 }
1942 case T_DATA:
1943 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1944 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1945 len += 2;
1946 return len;
1947 default:
1948 ND_PRINT((ndo, "unknown 802.11 frame type (%d)", FC_TYPE(fc)));
1949 return 0;
1950 }
1951 }
1952
1953 static int
1954 extract_mesh_header_length(const u_char *p)
1955 {
1956 return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1957 }
1958
1959 /*
1960 * Print the 802.11 MAC header.
1961 */
1962 static void
1963 ieee_802_11_hdr_print(netdissect_options *ndo,
1964 uint16_t fc, const u_char *p, u_int hdrlen,
1965 u_int meshdrlen)
1966 {
1967 if (ndo->ndo_vflag) {
1968 if (FC_MORE_DATA(fc))
1969 ND_PRINT((ndo, "More Data "));
1970 if (FC_MORE_FLAG(fc))
1971 ND_PRINT((ndo, "More Fragments "));
1972 if (FC_POWER_MGMT(fc))
1973 ND_PRINT((ndo, "Pwr Mgmt "));
1974 if (FC_RETRY(fc))
1975 ND_PRINT((ndo, "Retry "));
1976 if (FC_ORDER(fc))
1977 ND_PRINT((ndo, "Strictly Ordered "));
1978 if (FC_PROTECTED(fc))
1979 ND_PRINT((ndo, "Protected "));
1980 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1981 ND_PRINT((ndo, "%dus ",
1982 EXTRACT_LE_16BITS(
1983 &((const struct mgmt_header_t *)p)->duration)));
1984 }
1985 if (meshdrlen != 0) {
1986 const struct meshcntl_t *mc =
1987 (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1988 int ae = mc->flags & 3;
1989
1990 ND_PRINT((ndo, "MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1991 EXTRACT_LE_32BITS(mc->seq)));
1992 if (ae > 0)
1993 ND_PRINT((ndo, " A4:%s", etheraddr_string(ndo, mc->addr4)));
1994 if (ae > 1)
1995 ND_PRINT((ndo, " A5:%s", etheraddr_string(ndo, mc->addr5)));
1996 if (ae > 2)
1997 ND_PRINT((ndo, " A6:%s", etheraddr_string(ndo, mc->addr6)));
1998 ND_PRINT((ndo, ") "));
1999 }
2000
2001 switch (FC_TYPE(fc)) {
2002 case T_MGMT:
2003 mgmt_header_print(ndo, p);
2004 break;
2005 case T_CTRL:
2006 ctrl_header_print(ndo, fc, p);
2007 break;
2008 case T_DATA:
2009 data_header_print(ndo, fc, p);
2010 break;
2011 default:
2012 break;
2013 }
2014 }
2015
2016 #ifndef roundup2
2017 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
2018 #endif
2019
2020 static const char tstr[] = "[|802.11]";
2021
2022 static u_int
2023 ieee802_11_print(netdissect_options *ndo,
2024 const u_char *p, u_int length, u_int orig_caplen, int pad,
2025 u_int fcslen)
2026 {
2027 uint16_t fc;
2028 u_int caplen, hdrlen, meshdrlen;
2029 struct lladdr_info src, dst;
2030 int llc_hdrlen;
2031
2032 caplen = orig_caplen;
2033 /* Remove FCS, if present */
2034 if (length < fcslen) {
2035 ND_PRINT((ndo, "%s", tstr));
2036 return caplen;
2037 }
2038 length -= fcslen;
2039 if (caplen > length) {
2040 /* Amount of FCS in actual packet data, if any */
2041 fcslen = caplen - length;
2042 caplen -= fcslen;
2043 ndo->ndo_snapend -= fcslen;
2044 }
2045
2046 if (caplen < IEEE802_11_FC_LEN) {
2047 ND_PRINT((ndo, "%s", tstr));
2048 return orig_caplen;
2049 }
2050
2051 fc = EXTRACT_LE_16BITS(p);
2052 hdrlen = extract_header_length(ndo, fc);
2053 if (hdrlen == 0) {
2054 /* Unknown frame type or control frame subtype; quit. */
2055 return (0);
2056 }
2057 if (pad)
2058 hdrlen = roundup2(hdrlen, 4);
2059 if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
2060 DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
2061 if (caplen < hdrlen + 1) {
2062 ND_PRINT((ndo, "%s", tstr));
2063 return hdrlen;
2064 }
2065 meshdrlen = extract_mesh_header_length(p+hdrlen);
2066 hdrlen += meshdrlen;
2067 } else
2068 meshdrlen = 0;
2069
2070 if (caplen < hdrlen) {
2071 ND_PRINT((ndo, "%s", tstr));
2072 return hdrlen;
2073 }
2074
2075 if (ndo->ndo_eflag)
2076 ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
2077
2078 /*
2079 * Go past the 802.11 header.
2080 */
2081 length -= hdrlen;
2082 caplen -= hdrlen;
2083 p += hdrlen;
2084
2085 src.addr_string = etheraddr_string;
2086 dst.addr_string = etheraddr_string;
2087 switch (FC_TYPE(fc)) {
2088 case T_MGMT:
2089 get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
2090 if (!mgmt_body_print(ndo, fc, src.addr, p, length)) {
2091 ND_PRINT((ndo, "%s", tstr));
2092 return hdrlen;
2093 }
2094 break;
2095 case T_CTRL:
2096 if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
2097 ND_PRINT((ndo, "%s", tstr));
2098 return hdrlen;
2099 }
2100 break;
2101 case T_DATA:
2102 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
2103 return hdrlen; /* no-data frame */
2104 /* There may be a problem w/ AP not having this bit set */
2105 if (FC_PROTECTED(fc)) {
2106 ND_PRINT((ndo, "Data"));
2107 if (!wep_print(ndo, p)) {
2108 ND_PRINT((ndo, "%s", tstr));
2109 return hdrlen;
2110 }
2111 } else {
2112 get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr);
2113 llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
2114 if (llc_hdrlen < 0) {
2115 /*
2116 * Some kinds of LLC packet we cannot
2117 * handle intelligently
2118 */
2119 if (!ndo->ndo_suppress_default_print)
2120 ND_DEFAULTPRINT(p, caplen);
2121 llc_hdrlen = -llc_hdrlen;
2122 }
2123 hdrlen += llc_hdrlen;
2124 }
2125 break;
2126 default:
2127 /* We shouldn't get here - we should already have quit */
2128 break;
2129 }
2130
2131 return hdrlen;
2132 }
2133
2134 /*
2135 * This is the top level routine of the printer. 'p' points
2136 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
2137 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
2138 * is the number of bytes actually captured.
2139 */
2140 u_int
2141 ieee802_11_if_print(netdissect_options *ndo,
2142 const struct pcap_pkthdr *h, const u_char *p)
2143 {
2144 return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
2145 }
2146
2147
2148 /* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
2149 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */
2150
2151 /*-
2152 * Copyright (c) 2003, 2004 David Young. All rights reserved.
2153 *
2154 * Redistribution and use in source and binary forms, with or without
2155 * modification, are permitted provided that the following conditions
2156 * are met:
2157 * 1. Redistributions of source code must retain the above copyright
2158 * notice, this list of conditions and the following disclaimer.
2159 * 2. Redistributions in binary form must reproduce the above copyright
2160 * notice, this list of conditions and the following disclaimer in the
2161 * documentation and/or other materials provided with the distribution.
2162 * 3. The name of David Young may not be used to endorse or promote
2163 * products derived from this software without specific prior
2164 * written permission.
2165 *
2166 * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
2167 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2168 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2169 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
2170 * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2171 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2172 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2173 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2174 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2175 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2176 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
2177 * OF SUCH DAMAGE.
2178 */
2179
2180 /* A generic radio capture format is desirable. It must be
2181 * rigidly defined (e.g., units for fields should be given),
2182 * and easily extensible.
2183 *
2184 * The following is an extensible radio capture format. It is
2185 * based on a bitmap indicating which fields are present.
2186 *
2187 * I am trying to describe precisely what the application programmer
2188 * should expect in the following, and for that reason I tell the
2189 * units and origin of each measurement (where it applies), or else I
2190 * use sufficiently weaselly language ("is a monotonically nondecreasing
2191 * function of...") that I cannot set false expectations for lawyerly
2192 * readers.
2193 */
2194
2195 /*
2196 * The radio capture header precedes the 802.11 header.
2197 *
2198 * Note well: all radiotap fields are little-endian.
2199 */
2200 struct ieee80211_radiotap_header {
2201 uint8_t it_version; /* Version 0. Only increases
2202 * for drastic changes,
2203 * introduction of compatible
2204 * new fields does not count.
2205 */
2206 uint8_t it_pad;
2207 uint16_t it_len; /* length of the whole
2208 * header in bytes, including
2209 * it_version, it_pad,
2210 * it_len, and data fields.
2211 */
2212 uint32_t it_present; /* A bitmap telling which
2213 * fields are present. Set bit 31
2214 * (0x80000000) to extend the
2215 * bitmap by another 32 bits.
2216 * Additional extensions are made
2217 * by setting bit 31.
2218 */
2219 };
2220
2221 /* Name Data type Units
2222 * ---- --------- -----
2223 *
2224 * IEEE80211_RADIOTAP_TSFT uint64_t microseconds
2225 *
2226 * Value in microseconds of the MAC's 64-bit 802.11 Time
2227 * Synchronization Function timer when the first bit of the
2228 * MPDU arrived at the MAC. For received frames, only.
2229 *
2230 * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap
2231 *
2232 * Tx/Rx frequency in MHz, followed by flags (see below).
2233 * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
2234 * represent an HT channel as there is not enough room in
2235 * the flags word.
2236 *
2237 * IEEE80211_RADIOTAP_FHSS uint16_t see below
2238 *
2239 * For frequency-hopping radios, the hop set (first byte)
2240 * and pattern (second byte).
2241 *
2242 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index
2243 *
2244 * Tx/Rx data rate. If bit 0x80 is set then it represents an
2245 * an MCS index and not an IEEE rate.
2246 *
2247 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
2248 * one milliwatt (dBm)
2249 *
2250 * RF signal power at the antenna, decibel difference from
2251 * one milliwatt.
2252 *
2253 * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
2254 * one milliwatt (dBm)
2255 *
2256 * RF noise power at the antenna, decibel difference from one
2257 * milliwatt.
2258 *
2259 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
2260 *
2261 * RF signal power at the antenna, decibel difference from an
2262 * arbitrary, fixed reference.
2263 *
2264 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
2265 *
2266 * RF noise power at the antenna, decibel difference from an
2267 * arbitrary, fixed reference point.
2268 *
2269 * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless
2270 *
2271 * Quality of Barker code lock. Unitless. Monotonically
2272 * nondecreasing with "better" lock strength. Called "Signal
2273 * Quality" in datasheets. (Is there a standard way to measure
2274 * this?)
2275 *
2276 * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless
2277 *
2278 * Transmit power expressed as unitless distance from max
2279 * power set at factory calibration. 0 is max power.
2280 * Monotonically nondecreasing with lower power levels.
2281 *
2282 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB)
2283 *
2284 * Transmit power expressed as decibel distance from max power
2285 * set at factory calibration. 0 is max power. Monotonically
2286 * nondecreasing with lower power levels.
2287 *
2288 * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
2289 * one milliwatt (dBm)
2290 *
2291 * Transmit power expressed as dBm (decibels from a 1 milliwatt
2292 * reference). This is the absolute power level measured at
2293 * the antenna port.
2294 *
2295 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap
2296 *
2297 * Properties of transmitted and received frames. See flags
2298 * defined below.
2299 *
2300 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
2301 *
2302 * Unitless indication of the Rx/Tx antenna for this packet.
2303 * The first antenna is antenna 0.
2304 *
2305 * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap
2306 *
2307 * Properties of received frames. See flags defined below.
2308 *
2309 * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap
2310 * uint16_t MHz
2311 * uint8_t channel number
2312 * uint8_t .5 dBm
2313 *
2314 * Extended channel specification: flags (see below) followed by
2315 * frequency in MHz, the corresponding IEEE channel number, and
2316 * finally the maximum regulatory transmit power cap in .5 dBm
2317 * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL
2318 * and only one of the two should be present.
2319 *
2320 * IEEE80211_RADIOTAP_MCS uint8_t known
2321 * uint8_t flags
2322 * uint8_t mcs
2323 *
2324 * Bitset indicating which fields have known values, followed
2325 * by bitset of flag values, followed by the MCS rate index as
2326 * in IEEE 802.11n.
2327 *
2328 *
2329 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless
2330 *
2331 * Contains the AMPDU information for the subframe.
2332 *
2333 * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16
2334 *
2335 * Contains VHT information about this frame.
2336 *
2337 * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
2338 * uint8_t OUI[3]
2339 * uint8_t subspace
2340 * uint16_t length
2341 *
2342 * The Vendor Namespace Field contains three sub-fields. The first
2343 * sub-field is 3 bytes long. It contains the vendor's IEEE 802
2344 * Organizationally Unique Identifier (OUI). The fourth byte is a
2345 * vendor-specific "namespace selector."
2346 *
2347 */
2348 enum ieee80211_radiotap_type {
2349 IEEE80211_RADIOTAP_TSFT = 0,
2350 IEEE80211_RADIOTAP_FLAGS = 1,
2351 IEEE80211_RADIOTAP_RATE = 2,
2352 IEEE80211_RADIOTAP_CHANNEL = 3,
2353 IEEE80211_RADIOTAP_FHSS = 4,
2354 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
2355 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
2356 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
2357 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
2358 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
2359 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
2360 IEEE80211_RADIOTAP_ANTENNA = 11,
2361 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
2362 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
2363 IEEE80211_RADIOTAP_RX_FLAGS = 14,
2364 /* NB: gap for netbsd definitions */
2365 IEEE80211_RADIOTAP_XCHANNEL = 18,
2366 IEEE80211_RADIOTAP_MCS = 19,
2367 IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
2368 IEEE80211_RADIOTAP_VHT = 21,
2369 IEEE80211_RADIOTAP_NAMESPACE = 29,
2370 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
2371 IEEE80211_RADIOTAP_EXT = 31
2372 };
2373
2374 /* channel attributes */
2375 #define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */
2376 #define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */
2377 #define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */
2378 #define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */
2379 #define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */
2380 #define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */
2381 #define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */
2382 #define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */
2383 #define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */
2384 #define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */
2385 #define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */
2386 #define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */
2387 #define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */
2388 #define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */
2389 #define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */
2390
2391 /* Useful combinations of channel characteristics, borrowed from Ethereal */
2392 #define IEEE80211_CHAN_A \
2393 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2394 #define IEEE80211_CHAN_B \
2395 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2396 #define IEEE80211_CHAN_G \
2397 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2398 #define IEEE80211_CHAN_TA \
2399 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
2400 #define IEEE80211_CHAN_TG \
2401 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO)
2402
2403
2404 /* For IEEE80211_RADIOTAP_FLAGS */
2405 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
2406 * during CFP
2407 */
2408 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
2409 * with short
2410 * preamble
2411 */
2412 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
2413 * with WEP encryption
2414 */
2415 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
2416 * with fragmentation
2417 */
2418 #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
2419 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
2420 * 802.11 header and payload
2421 * (to 32-bit boundary)
2422 */
2423 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */
2424
2425 /* For IEEE80211_RADIOTAP_RX_FLAGS */
2426 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
2427 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */
2428
2429 /* For IEEE80211_RADIOTAP_MCS known */
2430 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01
2431 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */
2432 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04
2433 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08
2434 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10
2435 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20
2436 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN 0x40
2437 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1 0x80
2438
2439 /* For IEEE80211_RADIOTAP_MCS flags */
2440 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03
2441 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0
2442 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1
2443 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2
2444 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3
2445 #define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */
2446 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08
2447 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
2448 #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60
2449 #define IEEE80211_RADIOTAP_MCS_STBC_1 1
2450 #define IEEE80211_RADIOTAP_MCS_STBC_2 2
2451 #define IEEE80211_RADIOTAP_MCS_STBC_3 3
2452 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5
2453 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0 0x80
2454
2455 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */
2456 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001
2457 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002
2458 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004
2459 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008
2460 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010
2461 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020
2462
2463 /* For IEEE80211_RADIOTAP_VHT known */
2464 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN 0x0001
2465 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN 0x0002
2466 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN 0x0004
2467 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN 0x0008
2468 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN 0x0010
2469 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN 0x0020
2470 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN 0x0040
2471 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN 0x0080
2472 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN 0x0100
2473
2474 /* For IEEE80211_RADIOTAP_VHT flags */
2475 #define IEEE80211_RADIOTAP_VHT_STBC 0x01
2476 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA 0x02
2477 #define IEEE80211_RADIOTAP_VHT_SHORT_GI 0x04
2478 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9 0x08
2479 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM 0x10
2480 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED 0x20
2481
2482 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK 0x1f
2483
2484 #define IEEE80211_RADIOTAP_VHT_NSS_MASK 0x0f
2485 #define IEEE80211_RADIOTAP_VHT_MCS_MASK 0xf0
2486 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT 4
2487
2488 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn 0x01
2489
2490 #define IEEE80211_CHAN_FHSS \
2491 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
2492 #define IEEE80211_CHAN_A \
2493 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2494 #define IEEE80211_CHAN_B \
2495 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2496 #define IEEE80211_CHAN_PUREG \
2497 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
2498 #define IEEE80211_CHAN_G \
2499 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2500
2501 #define IS_CHAN_FHSS(flags) \
2502 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
2503 #define IS_CHAN_A(flags) \
2504 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
2505 #define IS_CHAN_B(flags) \
2506 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
2507 #define IS_CHAN_PUREG(flags) \
2508 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
2509 #define IS_CHAN_G(flags) \
2510 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2511 #define IS_CHAN_ANYG(flags) \
2512 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
2513
2514 static void
2515 print_chaninfo(netdissect_options *ndo,
2516 uint16_t freq, int flags, int presentflags)
2517 {
2518 ND_PRINT((ndo, "%u MHz", freq));
2519 if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) {
2520 /*
2521 * We have the MCS field, so this is 11n, regardless
2522 * of what the channel flags say.
2523 */
2524 ND_PRINT((ndo, " 11n"));
2525 } else {
2526 if (IS_CHAN_FHSS(flags))
2527 ND_PRINT((ndo, " FHSS"));
2528 if (IS_CHAN_A(flags)) {
2529 if (flags & IEEE80211_CHAN_HALF)
2530 ND_PRINT((ndo, " 11a/10Mhz"));
2531 else if (flags & IEEE80211_CHAN_QUARTER)
2532 ND_PRINT((ndo, " 11a/5Mhz"));
2533 else
2534 ND_PRINT((ndo, " 11a"));
2535 }
2536 if (IS_CHAN_ANYG(flags)) {
2537 if (flags & IEEE80211_CHAN_HALF)
2538 ND_PRINT((ndo, " 11g/10Mhz"));
2539 else if (flags & IEEE80211_CHAN_QUARTER)
2540 ND_PRINT((ndo, " 11g/5Mhz"));
2541 else
2542 ND_PRINT((ndo, " 11g"));
2543 } else if (IS_CHAN_B(flags))
2544 ND_PRINT((ndo, " 11b"));
2545 if (flags & IEEE80211_CHAN_TURBO)
2546 ND_PRINT((ndo, " Turbo"));
2547 }
2548 /*
2549 * These apply to 11n.
2550 */
2551 if (flags & IEEE80211_CHAN_HT20)
2552 ND_PRINT((ndo, " ht/20"));
2553 else if (flags & IEEE80211_CHAN_HT40D)
2554 ND_PRINT((ndo, " ht/40-"));
2555 else if (flags & IEEE80211_CHAN_HT40U)
2556 ND_PRINT((ndo, " ht/40+"));
2557 ND_PRINT((ndo, " "));
2558 }
2559
2560 static int
2561 print_radiotap_field(netdissect_options *ndo,
2562 struct cpack_state *s, uint32_t bit, uint8_t *flagsp,
2563 uint32_t presentflags)
2564 {
2565 u_int i;
2566 int rc;
2567
2568 switch (bit) {
2569
2570 case IEEE80211_RADIOTAP_TSFT: {
2571 uint64_t tsft;
2572
2573 rc = cpack_uint64(s, &tsft);
2574 if (rc != 0)
2575 goto trunc;
2576 ND_PRINT((ndo, "%" PRIu64 "us tsft ", tsft));
2577 break;
2578 }
2579
2580 case IEEE80211_RADIOTAP_FLAGS: {
2581 uint8_t flagsval;
2582
2583 rc = cpack_uint8(s, &flagsval);
2584 if (rc != 0)
2585 goto trunc;
2586 *flagsp = flagsval;
2587 if (flagsval & IEEE80211_RADIOTAP_F_CFP)
2588 ND_PRINT((ndo, "cfp "));
2589 if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE)
2590 ND_PRINT((ndo, "short preamble "));
2591 if (flagsval & IEEE80211_RADIOTAP_F_WEP)
2592 ND_PRINT((ndo, "wep "));
2593 if (flagsval & IEEE80211_RADIOTAP_F_FRAG)
2594 ND_PRINT((ndo, "fragmented "));
2595 if (flagsval & IEEE80211_RADIOTAP_F_BADFCS)
2596 ND_PRINT((ndo, "bad-fcs "));
2597 break;
2598 }
2599
2600 case IEEE80211_RADIOTAP_RATE: {
2601 uint8_t rate;
2602
2603 rc = cpack_uint8(s, &rate);
2604 if (rc != 0)
2605 goto trunc;
2606 /*
2607 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2608 * Linux and AirPcap it does not. (What about
2609 * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
2610 *
2611 * This is an issue either for proprietary extensions
2612 * to 11a or 11g, which do exist, or for 11n
2613 * implementations that stuff a rate value into
2614 * this field, which also appear to exist.
2615 *
2616 * We currently handle that by assuming that
2617 * if the 0x80 bit is set *and* the remaining
2618 * bits have a value between 0 and 15 it's
2619 * an MCS value, otherwise it's a rate. If
2620 * there are cases where systems that use
2621 * "0x80 + MCS index" for MCS indices > 15,
2622 * or stuff a rate value here between 64 and
2623 * 71.5 Mb/s in here, we'll need a preference
2624 * setting. Such rates do exist, e.g. 11n
2625 * MCS 7 at 20 MHz with a long guard interval.
2626 */
2627 if (rate >= 0x80 && rate <= 0x8f) {
2628 /*
2629 * XXX - we don't know the channel width
2630 * or guard interval length, so we can't
2631 * convert this to a data rate.
2632 *
2633 * If you want us to show a data rate,
2634 * use the MCS field, not the Rate field;
2635 * the MCS field includes not only the
2636 * MCS index, it also includes bandwidth
2637 * and guard interval information.
2638 *
2639 * XXX - can we get the channel width
2640 * from XChannel and the guard interval
2641 * information from Flags, at least on
2642 * FreeBSD?
2643 */
2644 ND_PRINT((ndo, "MCS %u ", rate & 0x7f));
2645 } else
2646 ND_PRINT((ndo, "%2.1f Mb/s ", .5 * rate));
2647 break;
2648 }
2649
2650 case IEEE80211_RADIOTAP_CHANNEL: {
2651 uint16_t frequency;
2652 uint16_t flags;
2653
2654 rc = cpack_uint16(s, &frequency);
2655 if (rc != 0)
2656 goto trunc;
2657 rc = cpack_uint16(s, &flags);
2658 if (rc != 0)
2659 goto trunc;
2660 /*
2661 * If CHANNEL and XCHANNEL are both present, skip
2662 * CHANNEL.
2663 */
2664 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2665 break;
2666 print_chaninfo(ndo, frequency, flags, presentflags);
2667 break;
2668 }
2669
2670 case IEEE80211_RADIOTAP_FHSS: {
2671 uint8_t hopset;
2672 uint8_t hoppat;
2673
2674 rc = cpack_uint8(s, &hopset);
2675 if (rc != 0)
2676 goto trunc;
2677 rc = cpack_uint8(s, &hoppat);
2678 if (rc != 0)
2679 goto trunc;
2680 ND_PRINT((ndo, "fhset %d fhpat %d ", hopset, hoppat));
2681 break;
2682 }
2683
2684 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: {
2685 int8_t dbm_antsignal;
2686
2687 rc = cpack_int8(s, &dbm_antsignal);
2688 if (rc != 0)
2689 goto trunc;
2690 ND_PRINT((ndo, "%ddBm signal ", dbm_antsignal));
2691 break;
2692 }
2693
2694 case IEEE80211_RADIOTAP_DBM_ANTNOISE: {
2695 int8_t dbm_antnoise;
2696
2697 rc = cpack_int8(s, &dbm_antnoise);
2698 if (rc != 0)
2699 goto trunc;
2700 ND_PRINT((ndo, "%ddBm noise ", dbm_antnoise));
2701 break;
2702 }
2703
2704 case IEEE80211_RADIOTAP_LOCK_QUALITY: {
2705 uint16_t lock_quality;
2706
2707 rc = cpack_uint16(s, &lock_quality);
2708 if (rc != 0)
2709 goto trunc;
2710 ND_PRINT((ndo, "%u sq ", lock_quality));
2711 break;
2712 }
2713
2714 case IEEE80211_RADIOTAP_TX_ATTENUATION: {
2715 uint16_t tx_attenuation;
2716
2717 rc = cpack_uint16(s, &tx_attenuation);
2718 if (rc != 0)
2719 goto trunc;
2720 ND_PRINT((ndo, "%d tx power ", -(int)tx_attenuation));
2721 break;
2722 }
2723
2724 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: {
2725 uint8_t db_tx_attenuation;
2726
2727 rc = cpack_uint8(s, &db_tx_attenuation);
2728 if (rc != 0)
2729 goto trunc;
2730 ND_PRINT((ndo, "%ddB tx attenuation ", -(int)db_tx_attenuation));
2731 break;
2732 }
2733
2734 case IEEE80211_RADIOTAP_DBM_TX_POWER: {
2735 int8_t dbm_tx_power;
2736
2737 rc = cpack_int8(s, &dbm_tx_power);
2738 if (rc != 0)
2739 goto trunc;
2740 ND_PRINT((ndo, "%ddBm tx power ", dbm_tx_power));
2741 break;
2742 }
2743
2744 case IEEE80211_RADIOTAP_ANTENNA: {
2745 uint8_t antenna;
2746
2747 rc = cpack_uint8(s, &antenna);
2748 if (rc != 0)
2749 goto trunc;
2750 ND_PRINT((ndo, "antenna %u ", antenna));
2751 break;
2752 }
2753
2754 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: {
2755 uint8_t db_antsignal;
2756
2757 rc = cpack_uint8(s, &db_antsignal);
2758 if (rc != 0)
2759 goto trunc;
2760 ND_PRINT((ndo, "%ddB signal ", db_antsignal));
2761 break;
2762 }
2763
2764 case IEEE80211_RADIOTAP_DB_ANTNOISE: {
2765 uint8_t db_antnoise;
2766
2767 rc = cpack_uint8(s, &db_antnoise);
2768 if (rc != 0)
2769 goto trunc;
2770 ND_PRINT((ndo, "%ddB noise ", db_antnoise));
2771 break;
2772 }
2773
2774 case IEEE80211_RADIOTAP_RX_FLAGS: {
2775 uint16_t rx_flags;
2776
2777 rc = cpack_uint16(s, &rx_flags);
2778 if (rc != 0)
2779 goto trunc;
2780 /* Do nothing for now */
2781 break;
2782 }
2783
2784 case IEEE80211_RADIOTAP_XCHANNEL: {
2785 uint32_t flags;
2786 uint16_t frequency;
2787 uint8_t channel;
2788 uint8_t maxpower;
2789
2790 rc = cpack_uint32(s, &flags);
2791 if (rc != 0)
2792 goto trunc;
2793 rc = cpack_uint16(s, &frequency);
2794 if (rc != 0)
2795 goto trunc;
2796 rc = cpack_uint8(s, &channel);
2797 if (rc != 0)
2798 goto trunc;
2799 rc = cpack_uint8(s, &maxpower);
2800 if (rc != 0)
2801 goto trunc;
2802 print_chaninfo(ndo, frequency, flags, presentflags);
2803 break;
2804 }
2805
2806 case IEEE80211_RADIOTAP_MCS: {
2807 uint8_t known;
2808 uint8_t flags;
2809 uint8_t mcs_index;
2810 static const char *ht_bandwidth[4] = {
2811 "20 MHz",
2812 "40 MHz",
2813 "20 MHz (L)",
2814 "20 MHz (U)"
2815 };
2816 float htrate;
2817
2818 rc = cpack_uint8(s, &known);
2819 if (rc != 0)
2820 goto trunc;
2821 rc = cpack_uint8(s, &flags);
2822 if (rc != 0)
2823 goto trunc;
2824 rc = cpack_uint8(s, &mcs_index);
2825 if (rc != 0)
2826 goto trunc;
2827 if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2828 /*
2829 * We know the MCS index.
2830 */
2831 if (mcs_index <= MAX_MCS_INDEX) {
2832 /*
2833 * And it's in-range.
2834 */
2835 if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2836 /*
2837 * And we know both the bandwidth and
2838 * the guard interval, so we can look
2839 * up the rate.
2840 */
2841 htrate =
2842 ieee80211_float_htrates \
2843 [mcs_index] \
2844 [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
2845 [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2846 } else {
2847 /*
2848 * We don't know both the bandwidth
2849 * and the guard interval, so we can
2850 * only report the MCS index.
2851 */
2852 htrate = 0.0;
2853 }
2854 } else {
2855 /*
2856 * The MCS value is out of range.
2857 */
2858 htrate = 0.0;
2859 }
2860 if (htrate != 0.0) {
2861 /*
2862 * We have the rate.
2863 * Print it.
2864 */
2865 ND_PRINT((ndo, "%.1f Mb/s MCS %u ", htrate, mcs_index));
2866 } else {
2867 /*
2868 * We at least have the MCS index.
2869 * Print it.
2870 */
2871 ND_PRINT((ndo, "MCS %u ", mcs_index));
2872 }
2873 }
2874 if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
2875 ND_PRINT((ndo, "%s ",
2876 ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]));
2877 }
2878 if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
2879 ND_PRINT((ndo, "%s GI ",
2880 (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
2881 "short" : "long"));
2882 }
2883 if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
2884 ND_PRINT((ndo, "%s ",
2885 (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
2886 "greenfield" : "mixed"));
2887 }
2888 if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
2889 ND_PRINT((ndo, "%s FEC ",
2890 (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
2891 "LDPC" : "BCC"));
2892 }
2893 if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
2894 ND_PRINT((ndo, "RX-STBC%u ",
2895 (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT));
2896 }
2897 break;
2898 }
2899
2900 case IEEE80211_RADIOTAP_AMPDU_STATUS: {
2901 uint32_t reference_num;
2902 uint16_t flags;
2903 uint8_t delim_crc;
2904 uint8_t reserved;
2905
2906 rc = cpack_uint32(s, &reference_num);
2907 if (rc != 0)
2908 goto trunc;
2909 rc = cpack_uint16(s, &flags);
2910 if (rc != 0)
2911 goto trunc;
2912 rc = cpack_uint8(s, &delim_crc);
2913 if (rc != 0)
2914 goto trunc;
2915 rc = cpack_uint8(s, &reserved);
2916 if (rc != 0)
2917 goto trunc;
2918 /* Do nothing for now */
2919 break;
2920 }
2921
2922 case IEEE80211_RADIOTAP_VHT: {
2923 uint16_t known;
2924 uint8_t flags;
2925 uint8_t bandwidth;
2926 uint8_t mcs_nss[4];
2927 uint8_t coding;
2928 uint8_t group_id;
2929 uint16_t partial_aid;
2930 static const char *vht_bandwidth[32] = {
2931 "20 MHz",
2932 "40 MHz",
2933 "20 MHz (L)",
2934 "20 MHz (U)",
2935 "80 MHz",
2936 "80 MHz (L)",
2937 "80 MHz (U)",
2938 "80 MHz (LL)",
2939 "80 MHz (LU)",
2940 "80 MHz (UL)",
2941 "80 MHz (UU)",
2942 "160 MHz",
2943 "160 MHz (L)",
2944 "160 MHz (U)",
2945 "160 MHz (LL)",
2946 "160 MHz (LU)",
2947 "160 MHz (UL)",
2948 "160 MHz (UU)",
2949 "160 MHz (LLL)",
2950 "160 MHz (LLU)",
2951 "160 MHz (LUL)",
2952 "160 MHz (UUU)",
2953 "160 MHz (ULL)",
2954 "160 MHz (ULU)",
2955 "160 MHz (UUL)",
2956 "160 MHz (UUU)",
2957 "unknown (26)",
2958 "unknown (27)",
2959 "unknown (28)",
2960 "unknown (29)",
2961 "unknown (30)",
2962 "unknown (31)"
2963 };
2964
2965 rc = cpack_uint16(s, &known);
2966 if (rc != 0)
2967 goto trunc;
2968 rc = cpack_uint8(s, &flags);
2969 if (rc != 0)
2970 goto trunc;
2971 rc = cpack_uint8(s, &bandwidth);
2972 if (rc != 0)
2973 goto trunc;
2974 for (i = 0; i < 4; i++) {
2975 rc = cpack_uint8(s, &mcs_nss[i]);
2976 if (rc != 0)
2977 goto trunc;
2978 }
2979 rc = cpack_uint8(s, &coding);
2980 if (rc != 0)
2981 goto trunc;
2982 rc = cpack_uint8(s, &group_id);
2983 if (rc != 0)
2984 goto trunc;
2985 rc = cpack_uint16(s, &partial_aid);
2986 if (rc != 0)
2987 goto trunc;
2988 for (i = 0; i < 4; i++) {
2989 u_int nss, mcs;
2990 nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK;
2991 mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT;
2992
2993 if (nss == 0)
2994 continue;
2995
2996 ND_PRINT((ndo, "User %u MCS %u ", i, mcs));
2997 ND_PRINT((ndo, "%s FEC ",
2998 (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ?
2999 "LDPC" : "BCC"));
3000 }
3001 if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) {
3002 ND_PRINT((ndo, "%s ",
3003 vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]));
3004 }
3005 if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) {
3006 ND_PRINT((ndo, "%s GI ",
3007 (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ?
3008 "short" : "long"));
3009 }
3010 break;
3011 }
3012
3013 default:
3014 /* this bit indicates a field whose
3015 * size we do not know, so we cannot
3016 * proceed. Just print the bit number.
3017 */
3018 ND_PRINT((ndo, "[bit %u] ", bit));
3019 return -1;
3020 }
3021
3022 return 0;
3023
3024 trunc:
3025 ND_PRINT((ndo, "%s", tstr));
3026 return rc;
3027 }
3028
3029
3030 static int
3031 print_in_radiotap_namespace(netdissect_options *ndo,
3032 struct cpack_state *s, uint8_t *flags,
3033 uint32_t presentflags, int bit0)
3034 {
3035 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
3036 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
3037 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
3038 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
3039 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
3040 uint32_t present, next_present;
3041 int bitno;
3042 enum ieee80211_radiotap_type bit;
3043 int rc;
3044
3045 for (present = presentflags; present; present = next_present) {
3046 /*
3047 * Clear the least significant bit that is set.
3048 */
3049 next_present = present & (present - 1);
3050
3051 /*
3052 * Get the bit number, within this presence word,
3053 * of the remaining least significant bit that
3054 * is set.
3055 */
3056 bitno = BITNO_32(present ^ next_present);
3057
3058 /*
3059 * Stop if this is one of the "same meaning
3060 * in all presence flags" bits.
3061 */
3062 if (bitno >= IEEE80211_RADIOTAP_NAMESPACE)
3063 break;
3064
3065 /*
3066 * Get the radiotap bit number of that bit.
3067 */
3068 bit = (enum ieee80211_radiotap_type)(bit0 + bitno);
3069
3070 rc = print_radiotap_field(ndo, s, bit, flags, presentflags);
3071 if (rc != 0)
3072 return rc;
3073 }
3074
3075 return 0;
3076 }
3077
3078 u_int
3079 ieee802_11_radio_print(netdissect_options *ndo,
3080 const u_char *p, u_int length, u_int caplen)
3081 {
3082 #define BIT(n) (1U << n)
3083 #define IS_EXTENDED(__p) \
3084 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
3085
3086 struct cpack_state cpacker;
3087 const struct ieee80211_radiotap_header *hdr;
3088 uint32_t presentflags;
3089 const uint32_t *presentp, *last_presentp;
3090 int vendor_namespace;
3091 uint8_t vendor_oui[3];
3092 uint8_t vendor_subnamespace;
3093 uint16_t skip_length;
3094 int bit0;
3095 u_int len;
3096 uint8_t flags;
3097 int pad;
3098 u_int fcslen;
3099
3100 if (caplen < sizeof(*hdr)) {
3101 ND_PRINT((ndo, "%s", tstr));
3102 return caplen;
3103 }
3104
3105 hdr = (const struct ieee80211_radiotap_header *)p;
3106
3107 len = EXTRACT_LE_16BITS(&hdr->it_len);
3108 if (len < sizeof(*hdr)) {
3109 /*
3110 * The length is the length of the entire header, so
3111 * it must be as large as the fixed-length part of
3112 * the header.
3113 */
3114 ND_PRINT((ndo, "%s", tstr));
3115 return caplen;
3116 }
3117
3118 /*
3119 * If we don't have the entire radiotap header, just give up.
3120 */
3121 if (caplen < len) {
3122 ND_PRINT((ndo, "%s", tstr));
3123 return caplen;
3124 }
3125 cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */
3126 cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
3127 for (last_presentp = &hdr->it_present;
3128 (const u_char*)(last_presentp + 1) <= p + len &&
3129 IS_EXTENDED(last_presentp);
3130 last_presentp++)
3131 cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
3132
3133 /* are there more bitmap extensions than bytes in header? */
3134 if ((const u_char*)(last_presentp + 1) > p + len) {
3135 ND_PRINT((ndo, "%s", tstr));
3136 return caplen;
3137 }
3138
3139 /*
3140 * Start out at the beginning of the default radiotap namespace.
3141 */
3142 bit0 = 0;
3143 vendor_namespace = 0;
3144 memset(vendor_oui, 0, 3);
3145 vendor_subnamespace = 0;
3146 skip_length = 0;
3147 /* Assume no flags */
3148 flags = 0;
3149 /* Assume no Atheros padding between 802.11 header and body */
3150 pad = 0;
3151 /* Assume no FCS at end of frame */
3152 fcslen = 0;
3153 for (presentp = &hdr->it_present; presentp <= last_presentp;
3154 presentp++) {
3155 presentflags = EXTRACT_LE_32BITS(presentp);
3156
3157 /*
3158 * If this is a vendor namespace, we don't handle it.
3159 */
3160 if (vendor_namespace) {
3161 /*
3162 * Skip past the stuff we don't understand.
3163 * If we add support for any vendor namespaces,
3164 * it'd be added here; use vendor_oui and
3165 * vendor_subnamespace to interpret the fields.
3166 */
3167 if (cpack_advance(&cpacker, skip_length) != 0) {
3168 /*
3169 * Ran out of space in the packet.
3170 */
3171 break;
3172 }
3173
3174 /*
3175 * We've skipped it all; nothing more to
3176 * skip.
3177 */
3178 skip_length = 0;
3179 } else {
3180 if (print_in_radiotap_namespace(ndo, &cpacker,
3181 &flags, presentflags, bit0) != 0) {
3182 /*
3183 * Fatal error - can't process anything
3184 * more in the radiotap header.
3185 */
3186 break;
3187 }
3188 }
3189
3190 /*
3191 * Handle the namespace switch bits; we've already handled
3192 * the extension bit in all but the last word above.
3193 */
3194 switch (presentflags &
3195 (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) {
3196
3197 case 0:
3198 /*
3199 * We're not changing namespaces.
3200 * advance to the next 32 bits in the current
3201 * namespace.
3202 */
3203 bit0 += 32;
3204 break;
3205
3206 case BIT(IEEE80211_RADIOTAP_NAMESPACE):
3207 /*
3208 * We're switching to the radiotap namespace.
3209 * Reset the presence-bitmap index to 0, and
3210 * reset the namespace to the default radiotap
3211 * namespace.
3212 */
3213 bit0 = 0;
3214 vendor_namespace = 0;
3215 memset(vendor_oui, 0, 3);
3216 vendor_subnamespace = 0;
3217 skip_length = 0;
3218 break;
3219
3220 case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE):
3221 /*
3222 * We're switching to a vendor namespace.
3223 * Reset the presence-bitmap index to 0,
3224 * note that we're in a vendor namespace,
3225 * and fetch the fields of the Vendor Namespace
3226 * item.
3227 */
3228 bit0 = 0;
3229 vendor_namespace = 1;
3230 if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) {
3231 ND_PRINT((ndo, "%s", tstr));
3232 break;
3233 }
3234 if (cpack_uint8(&cpacker, &vendor_oui[0]) != 0) {
3235 ND_PRINT((ndo, "%s", tstr));
3236 break;
3237 }
3238 if (cpack_uint8(&cpacker, &vendor_oui[1]) != 0) {
3239 ND_PRINT((ndo, "%s", tstr));
3240 break;
3241 }
3242 if (cpack_uint8(&cpacker, &vendor_oui[2]) != 0) {
3243 ND_PRINT((ndo, "%s", tstr));
3244 break;
3245 }
3246 if (cpack_uint8(&cpacker, &vendor_subnamespace) != 0) {
3247 ND_PRINT((ndo, "%s", tstr));
3248 break;
3249 }
3250 if (cpack_uint16(&cpacker, &skip_length) != 0) {
3251 ND_PRINT((ndo, "%s", tstr));
3252 break;
3253 }
3254 break;
3255
3256 default:
3257 /*
3258 * Illegal combination. The behavior in this
3259 * case is undefined by the radiotap spec; we
3260 * just ignore both bits.
3261 */
3262 break;
3263 }
3264 }
3265
3266 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
3267 pad = 1; /* Atheros padding */
3268 if (flags & IEEE80211_RADIOTAP_F_FCS)
3269 fcslen = 4; /* FCS at end of packet */
3270 return len + ieee802_11_print(ndo, p + len, length - len, caplen - len, pad,
3271 fcslen);
3272 #undef BITNO_32
3273 #undef BITNO_16
3274 #undef BITNO_8
3275 #undef BITNO_4
3276 #undef BITNO_2
3277 #undef BIT
3278 }
3279
3280 static u_int
3281 ieee802_11_avs_radio_print(netdissect_options *ndo,
3282 const u_char *p, u_int length, u_int caplen)
3283 {
3284 uint32_t caphdr_len;
3285
3286 if (caplen < 8) {
3287 ND_PRINT((ndo, "%s", tstr));
3288 return caplen;
3289 }
3290
3291 caphdr_len = EXTRACT_32BITS(p + 4);
3292 if (caphdr_len < 8) {
3293 /*
3294 * Yow! The capture header length is claimed not
3295 * to be large enough to include even the version
3296 * cookie or capture header length!
3297 */
3298 ND_PRINT((ndo, "%s", tstr));
3299 return caplen;
3300 }
3301
3302 if (caplen < caphdr_len) {
3303 ND_PRINT((ndo, "%s", tstr));
3304 return caplen;
3305 }
3306
3307 return caphdr_len + ieee802_11_print(ndo, p + caphdr_len,
3308 length - caphdr_len, caplen - caphdr_len, 0, 0);
3309 }
3310
3311 #define PRISM_HDR_LEN 144
3312
3313 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
3314 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
3315 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
3316
3317 /*
3318 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
3319 * containing information such as radio information, which we
3320 * currently ignore.
3321 *
3322 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
3323 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
3324 * (currently, on Linux, there's no ARPHRD_ type for
3325 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
3326 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
3327 * the AVS header, and the first 4 bytes of the header are used to
3328 * indicate whether it's a Prism header or an AVS header).
3329 */
3330 u_int
3331 prism_if_print(netdissect_options *ndo,
3332 const struct pcap_pkthdr *h, const u_char *p)
3333 {
3334 u_int caplen = h->caplen;
3335 u_int length = h->len;
3336 uint32_t msgcode;
3337
3338 if (caplen < 4) {
3339 ND_PRINT((ndo, "%s", tstr));
3340 return caplen;
3341 }
3342
3343 msgcode = EXTRACT_32BITS(p);
3344 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
3345 msgcode == WLANCAP_MAGIC_COOKIE_V2)
3346 return ieee802_11_avs_radio_print(ndo, p, length, caplen);
3347
3348 if (caplen < PRISM_HDR_LEN) {
3349 ND_PRINT((ndo, "%s", tstr));
3350 return caplen;
3351 }
3352
3353 return PRISM_HDR_LEN + ieee802_11_print(ndo, p + PRISM_HDR_LEN,
3354 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
3355 }
3356
3357 /*
3358 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
3359 * header, containing information such as radio information.
3360 */
3361 u_int
3362 ieee802_11_radio_if_print(netdissect_options *ndo,
3363 const struct pcap_pkthdr *h, const u_char *p)
3364 {
3365 return ieee802_11_radio_print(ndo, p, h->len, h->caplen);
3366 }
3367
3368 /*
3369 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
3370 * extra header, containing information such as radio information,
3371 * which we currently ignore.
3372 */
3373 u_int
3374 ieee802_11_radio_avs_if_print(netdissect_options *ndo,
3375 const struct pcap_pkthdr *h, const u_char *p)
3376 {
3377 return ieee802_11_avs_radio_print(ndo, p, h->len, h->caplen);
3378 }