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