]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
Fix the handling of unknown tagged parameters in management frames.
[tcpdump] / print-802_11.c
1 /*
2 * Copyright (c) 2001
3 * Fortress Technologies, Inc. All rights reserved.
4 * Charlie Lenahan (clenahan@fortresstech.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23 #ifndef lint
24 static const char rcsid[] _U_ =
25 "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
26 #endif
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <tcpdump-stdinc.h>
33
34 #include <stdio.h>
35 #include <pcap.h>
36 #include <string.h>
37
38 #include "interface.h"
39 #include "addrtoname.h"
40 #include "ethertype.h"
41
42 #include "extract.h"
43
44 #include "cpack.h"
45
46 #include "ieee802_11.h"
47 #include "ieee802_11_radio.h"
48
49 #define PRINT_SSID(p) \
50 if (p.ssid_present) { \
51 printf(" ("); \
52 fn_print(p.ssid.ssid, NULL); \
53 printf(")"); \
54 }
55
56 #define PRINT_RATE(_sep, _r, _suf) \
57 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
58 #define PRINT_RATES(p) \
59 if (p.rates_present) { \
60 int z; \
61 const char *sep = " ["; \
62 for (z = 0; z < p.rates.length ; z++) { \
63 PRINT_RATE(sep, p.rates.rate[z], \
64 (p.rates.rate[z] & 0x80 ? "*" : "")); \
65 sep = " "; \
66 } \
67 if (p.rates.length != 0) \
68 printf(" Mbit]"); \
69 }
70
71 #define PRINT_DS_CHANNEL(p) \
72 if (p.ds_present) \
73 printf(" CH: %u", p.ds.channel); \
74 printf("%s", \
75 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
76
77 static const int ieee80211_htrates[16] = {
78 13, /* IFM_IEEE80211_MCS0 */
79 26, /* IFM_IEEE80211_MCS1 */
80 39, /* IFM_IEEE80211_MCS2 */
81 52, /* IFM_IEEE80211_MCS3 */
82 78, /* IFM_IEEE80211_MCS4 */
83 104, /* IFM_IEEE80211_MCS5 */
84 117, /* IFM_IEEE80211_MCS6 */
85 130, /* IFM_IEEE80211_MCS7 */
86 26, /* IFM_IEEE80211_MCS8 */
87 52, /* IFM_IEEE80211_MCS9 */
88 78, /* IFM_IEEE80211_MCS10 */
89 104, /* IFM_IEEE80211_MCS11 */
90 156, /* IFM_IEEE80211_MCS12 */
91 208, /* IFM_IEEE80211_MCS13 */
92 234, /* IFM_IEEE80211_MCS14 */
93 260, /* IFM_IEEE80211_MCS15 */
94 };
95 #define PRINT_HT_RATE(_sep, _r, _suf) \
96 printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf)
97
98 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
99 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
100
101 static const char *status_text[] = {
102 "Succesful", /* 0 */
103 "Unspecified failure", /* 1 */
104 "Reserved", /* 2 */
105 "Reserved", /* 3 */
106 "Reserved", /* 4 */
107 "Reserved", /* 5 */
108 "Reserved", /* 6 */
109 "Reserved", /* 7 */
110 "Reserved", /* 8 */
111 "Reserved", /* 9 */
112 "Cannot Support all requested capabilities in the Capability "
113 "Information field", /* 10 */
114 "Reassociation denied due to inability to confirm that association "
115 "exists", /* 11 */
116 "Association denied due to reason outside the scope of the "
117 "standard", /* 12 */
118 "Responding station does not support the specified authentication "
119 "algorithm ", /* 13 */
120 "Received an Authentication frame with authentication transaction "
121 "sequence number out of expected sequence", /* 14 */
122 "Authentication rejected because of challenge failure", /* 15 */
123 "Authentication rejected due to timeout waiting for next frame in "
124 "sequence", /* 16 */
125 "Association denied because AP is unable to handle additional"
126 "associated stations", /* 17 */
127 "Association denied due to requesting station not supporting all of "
128 "the data rates in BSSBasicRateSet parameter", /* 18 */
129 "Association denied due to requesting station not supporting "
130 "short preamble operation", /* 19 */
131 "Association denied due to requesting station not supporting "
132 "PBCC encoding", /* 20 */
133 "Association denied due to requesting station not supporting "
134 "channel agility", /* 21 */
135 "Association request rejected because Spectrum Management "
136 "capability is required", /* 22 */
137 "Association request rejected because the information in the "
138 "Power Capability element is unacceptable", /* 23 */
139 "Association request rejected because the information in the "
140 "Supported Channels element is unacceptable", /* 24 */
141 "Association denied due to requesting station not supporting "
142 "short slot operation", /* 25 */
143 "Association denied due to requesting station not supporting "
144 "DSSS-OFDM operation", /* 26 */
145 "Association denied because the requested STA does not support HT "
146 "features", /* 27 */
147 "Reserved", /* 28 */
148 "Association denied because the requested STA does not support "
149 "the PCO transition time required by the AP", /* 29 */
150 "Reserved", /* 30 */
151 "Reserved", /* 31 */
152 "Unspecified, QoS-related failure", /* 32 */
153 "Association denied due to QAP having insufficient bandwidth "
154 "to handle another QSTA", /* 33 */
155 "Association denied due to excessive frame loss rates and/or "
156 "poor conditions on current operating channel", /* 34 */
157 "Association (with QBSS) denied due to requesting station not "
158 "supporting the QoS facility", /* 35 */
159 "Association denied due to requesting station not supporting "
160 "Block Ack", /* 36 */
161 "The request has been declined", /* 37 */
162 "The request has not been successful as one or more parameters "
163 "have invalid values", /* 38 */
164 "The TS has not been created because the request cannot be honored. "
165 "However, a suggested TSPEC is provided so that the initiating QSTA"
166 "may attempt to set another TS with the suggested changes to the "
167 "TSPEC", /* 39 */
168 "Invalid Information Element", /* 40 */
169 "Group Cipher is not valid", /* 41 */
170 "Pairwise Cipher is not valid", /* 42 */
171 "AKMP is not valid", /* 43 */
172 "Unsupported RSN IE version", /* 44 */
173 "Invalid RSN IE Capabilities", /* 45 */
174 "Cipher suite is rejected per security policy", /* 46 */
175 "The TS has not been created. However, the HC may be capable of "
176 "creating a TS, in response to a request, after the time indicated "
177 "in the TS Delay element", /* 47 */
178 "Direct Link is not allowed in the BSS by policy", /* 48 */
179 "Destination STA is not present within this QBSS.", /* 49 */
180 "The Destination STA is not a QSTA.", /* 50 */
181
182 };
183 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
184
185 static const char *reason_text[] = {
186 "Reserved", /* 0 */
187 "Unspecified reason", /* 1 */
188 "Previous authentication no longer valid", /* 2 */
189 "Deauthenticated because sending station is leaving (or has left) "
190 "IBSS or ESS", /* 3 */
191 "Disassociated due to inactivity", /* 4 */
192 "Disassociated because AP is unable to handle all currently "
193 " associated stations", /* 5 */
194 "Class 2 frame received from nonauthenticated station", /* 6 */
195 "Class 3 frame received from nonassociated station", /* 7 */
196 "Disassociated because sending station is leaving "
197 "(or has left) BSS", /* 8 */
198 "Station requesting (re)association is not authenticated with "
199 "responding station", /* 9 */
200 "Disassociated because the information in the Power Capability "
201 "element is unacceptable", /* 10 */
202 "Disassociated because the information in the SupportedChannels "
203 "element is unacceptable", /* 11 */
204 "Invalid Information Element", /* 12 */
205 "Reserved", /* 13 */
206 "Michael MIC failure", /* 14 */
207 "4-Way Handshake timeout", /* 15 */
208 "Group key update timeout", /* 16 */
209 "Information element in 4-Way Handshake different from (Re)Association"
210 "Request/Probe Response/Beacon", /* 17 */
211 "Group Cipher is not valid", /* 18 */
212 "AKMP is not valid", /* 20 */
213 "Unsupported RSN IE version", /* 21 */
214 "Invalid RSN IE Capabilities", /* 22 */
215 "IEEE 802.1X Authentication failed", /* 23 */
216 "Cipher suite is rejected per security policy", /* 24 */
217 "Reserved", /* 25 */
218 "Reserved", /* 26 */
219 "Reserved", /* 27 */
220 "Reserved", /* 28 */
221 "Reserved", /* 29 */
222 "Reserved", /* 30 */
223 "TS deleted because QoS AP lacks sufficient bandwidth for this "
224 "QoS STA due to a change in BSS service characteristics or "
225 "operational mode (e.g. an HT BSS change from 40 MHz channel "
226 "to 20 MHz channel)", /* 31 */
227 "Disassociated for unspecified, QoS-related reason", /* 32 */
228 "Disassociated because QoS AP lacks sufficient bandwidth for this "
229 "QoS STA", /* 33 */
230 "Disassociated because of excessive number of frames that need to be "
231 "acknowledged, but are not acknowledged for AP transmissions "
232 "and/or poor channel conditions", /* 34 */
233 "Disassociated because STA is transmitting outside the limits "
234 "of its TXOPs", /* 35 */
235 "Requested from peer STA as the STA is leaving the BSS "
236 "(or resetting)", /* 36 */
237 "Requested from peer STA as it does not want to use the "
238 "mechanism", /* 37 */
239 "Requested from peer STA as the STA received frames using the "
240 "mechanism for which a set up is required", /* 38 */
241 "Requested from peer STA due to time out", /* 39 */
242 "Reserved", /* 40 */
243 "Reserved", /* 41 */
244 "Reserved", /* 42 */
245 "Reserved", /* 43 */
246 "Reserved", /* 44 */
247 "Peer STA does not support the requested cipher suite", /* 45 */
248 "Association denied due to requesting STA not supporting HT "
249 "features", /* 46 */
250 };
251 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
252
253 static int
254 wep_print(const u_char *p)
255 {
256 u_int32_t iv;
257
258 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
259 return 0;
260 iv = EXTRACT_LE_32BITS(p);
261
262 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
263 IV_KEYID(iv));
264
265 return 1;
266 }
267
268 static int
269 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
270 u_int length)
271 {
272 u_int elementlen;
273 struct ssid_t ssid;
274 struct challenge_t challenge;
275 struct rates_t rates;
276 struct ds_t ds;
277 struct cf_t cf;
278 struct tim_t tim;
279
280 /*
281 * We haven't seen any elements yet.
282 */
283 pbody->challenge_present = 0;
284 pbody->ssid_present = 0;
285 pbody->rates_present = 0;
286 pbody->ds_present = 0;
287 pbody->cf_present = 0;
288 pbody->tim_present = 0;
289
290 while (length != 0) {
291 if (!TTEST2(*(p + offset), 1))
292 return 0;
293 if (length < 1)
294 return 0;
295 switch (*(p + offset)) {
296 case E_SSID:
297 if (!TTEST2(*(p + offset), 2))
298 return 0;
299 if (length < 2)
300 return 0;
301 memcpy(&ssid, p + offset, 2);
302 offset += 2;
303 length -= 2;
304 if (ssid.length != 0) {
305 if (ssid.length > sizeof(ssid.ssid) - 1)
306 return 0;
307 if (!TTEST2(*(p + offset), ssid.length))
308 return 0;
309 if (length < ssid.length)
310 return 0;
311 memcpy(&ssid.ssid, p + offset, ssid.length);
312 offset += ssid.length;
313 length -= ssid.length;
314 }
315 ssid.ssid[ssid.length] = '\0';
316 /*
317 * Present and not truncated.
318 *
319 * If we haven't already seen an SSID IE,
320 * copy this one, otherwise ignore this one,
321 * so we later report the first one we saw.
322 */
323 if (!pbody->ssid_present) {
324 pbody->ssid = ssid;
325 pbody->ssid_present = 1;
326 }
327 break;
328 case E_CHALLENGE:
329 if (!TTEST2(*(p + offset), 2))
330 return 0;
331 if (length < 2)
332 return 0;
333 memcpy(&challenge, p + offset, 2);
334 offset += 2;
335 length -= 2;
336 if (challenge.length != 0) {
337 if (challenge.length >
338 sizeof(challenge.text) - 1)
339 return 0;
340 if (!TTEST2(*(p + offset), challenge.length))
341 return 0;
342 if (length < challenge.length)
343 return 0;
344 memcpy(&challenge.text, p + offset,
345 challenge.length);
346 offset += challenge.length;
347 length -= challenge.length;
348 }
349 challenge.text[challenge.length] = '\0';
350 /*
351 * Present and not truncated.
352 *
353 * If we haven't already seen a challenge IE,
354 * copy this one, otherwise ignore this one,
355 * so we later report the first one we saw.
356 */
357 if (!pbody->challenge_present) {
358 pbody->challenge = challenge;
359 pbody->challenge_present = 1;
360 }
361 break;
362 case E_RATES:
363 if (!TTEST2(*(p + offset), 2))
364 return 0;
365 if (length < 2)
366 return 0;
367 memcpy(&rates, p + offset, 2);
368 offset += 2;
369 length -= 2;
370 if (rates.length != 0) {
371 if (rates.length > sizeof rates.rate)
372 return 0;
373 if (!TTEST2(*(p + offset), rates.length))
374 return 0;
375 if (length < rates.length)
376 return 0;
377 memcpy(&rates.rate, p + offset, rates.length);
378 offset += rates.length;
379 length -= rates.length;
380 }
381 /*
382 * Present and not truncated.
383 *
384 * If we haven't already seen a rates IE,
385 * copy this one if it's not zero-length,
386 * otherwise ignore this one, so we later
387 * report the first one we saw.
388 *
389 * We ignore zero-length rates IEs as some
390 * devices seem to put a zero-length rates
391 * IE, followed by an SSID IE, followed by
392 * a non-zero-length rates IE into frames,
393 * even though IEEE Std 802.11-2007 doesn't
394 * seem to indicate that a zero-length rates
395 * IE is valid.
396 */
397 if (!pbody->rates_present && rates.length != 0) {
398 pbody->rates = rates;
399 pbody->rates_present = 1;
400 }
401 break;
402 case E_DS:
403 if (!TTEST2(*(p + offset), 3))
404 return 0;
405 if (length < 3)
406 return 0;
407 memcpy(&ds, p + offset, 3);
408 offset += 3;
409 length -= 3;
410 /*
411 * Present and not truncated.
412 *
413 * If we haven't already seen a DS IE,
414 * copy this one, otherwise ignore this one,
415 * so we later report the first one we saw.
416 */
417 if (!pbody->ds_present) {
418 pbody->ds = ds;
419 pbody->ds_present = 1;
420 }
421 break;
422 case E_CF:
423 if (!TTEST2(*(p + offset), 8))
424 return 0;
425 if (length < 8)
426 return 0;
427 memcpy(&cf, p + offset, 8);
428 offset += 8;
429 length -= 8;
430 /*
431 * Present and not truncated.
432 *
433 * If we haven't already seen a CF IE,
434 * copy this one, otherwise ignore this one,
435 * so we later report the first one we saw.
436 */
437 if (!pbody->cf_present) {
438 pbody->cf = cf;
439 pbody->cf_present = 1;
440 }
441 break;
442 case E_TIM:
443 if (!TTEST2(*(p + offset), 2))
444 return 0;
445 if (length < 2)
446 return 0;
447 memcpy(&tim, p + offset, 2);
448 offset += 2;
449 length -= 2;
450 if (!TTEST2(*(p + offset), 3))
451 return 0;
452 if (length < 3)
453 return 0;
454 memcpy(&tim.count, p + offset, 3);
455 offset += 3;
456 length -= 3;
457
458 if (tim.length <= 3)
459 break;
460 if (tim.length - 3 > (int)sizeof tim.bitmap)
461 return 0;
462 if (!TTEST2(*(p + offset), tim.length - 3))
463 return 0;
464 if (length < (u_int)(tim.length - 3))
465 return 0;
466 memcpy(tim.bitmap, p + (tim.length - 3),
467 (tim.length - 3));
468 offset += tim.length - 3;
469 length -= tim.length - 3;
470 /*
471 * Present and not truncated.
472 *
473 * If we haven't already seen a TIM IE,
474 * copy this one, otherwise ignore this one,
475 * so we later report the first one we saw.
476 */
477 if (!pbody->tim_present) {
478 pbody->tim = tim;
479 pbody->tim_present = 1;
480 }
481 break;
482 default:
483 #if 0
484 printf("(1) unhandled element_id (%d) ",
485 *(p + offset));
486 #endif
487 if (!TTEST2(*(p + offset), 2))
488 return 0;
489 if (length < 2)
490 return 0;
491 elementlen = *(p + offset + 1);
492 if (!TTEST2(*(p + offset + 2), elementlen))
493 return 0;
494 if (length < elementlen + 2)
495 return 0;
496 offset += elementlen + 2;
497 length -= elementlen + 2;
498 break;
499 }
500 }
501
502 /* No problems found. */
503 return 1;
504 }
505
506 /*********************************************************************************
507 * Print Handle functions for the management frame types
508 *********************************************************************************/
509
510 static int
511 handle_beacon(const u_char *p, u_int length)
512 {
513 struct mgmt_body_t pbody;
514 int offset = 0;
515 int ret;
516
517 memset(&pbody, 0, sizeof(pbody));
518
519 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
520 IEEE802_11_CAPINFO_LEN))
521 return 0;
522 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
523 IEEE802_11_CAPINFO_LEN)
524 return 0;
525 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
526 offset += IEEE802_11_TSTAMP_LEN;
527 length -= IEEE802_11_TSTAMP_LEN;
528 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
529 offset += IEEE802_11_BCNINT_LEN;
530 length -= IEEE802_11_BCNINT_LEN;
531 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
532 offset += IEEE802_11_CAPINFO_LEN;
533 length -= IEEE802_11_CAPINFO_LEN;
534
535 ret = parse_elements(&pbody, p, offset, length);
536
537 PRINT_SSID(pbody);
538 PRINT_RATES(pbody);
539 printf(" %s",
540 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
541 PRINT_DS_CHANNEL(pbody);
542
543 return ret;
544 }
545
546 static int
547 handle_assoc_request(const u_char *p, u_int length)
548 {
549 struct mgmt_body_t pbody;
550 int offset = 0;
551 int ret;
552
553 memset(&pbody, 0, sizeof(pbody));
554
555 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
556 return 0;
557 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
558 return 0;
559 pbody.capability_info = EXTRACT_LE_16BITS(p);
560 offset += IEEE802_11_CAPINFO_LEN;
561 length -= IEEE802_11_CAPINFO_LEN;
562 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
563 offset += IEEE802_11_LISTENINT_LEN;
564 length -= IEEE802_11_LISTENINT_LEN;
565
566 ret = parse_elements(&pbody, p, offset, length);
567
568 PRINT_SSID(pbody);
569 PRINT_RATES(pbody);
570 return ret;
571 }
572
573 static int
574 handle_assoc_response(const u_char *p, u_int length)
575 {
576 struct mgmt_body_t pbody;
577 int offset = 0;
578 int ret;
579
580 memset(&pbody, 0, sizeof(pbody));
581
582 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
583 IEEE802_11_AID_LEN))
584 return 0;
585 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
586 IEEE802_11_AID_LEN)
587 return 0;
588 pbody.capability_info = EXTRACT_LE_16BITS(p);
589 offset += IEEE802_11_CAPINFO_LEN;
590 length -= IEEE802_11_CAPINFO_LEN;
591 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
592 offset += IEEE802_11_STATUS_LEN;
593 length -= IEEE802_11_STATUS_LEN;
594 pbody.aid = EXTRACT_LE_16BITS(p+offset);
595 offset += IEEE802_11_AID_LEN;
596 length -= IEEE802_11_AID_LEN;
597
598 ret = parse_elements(&pbody, p, offset, length);
599
600 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
601 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
602 (pbody.status_code < NUM_STATUSES
603 ? status_text[pbody.status_code]
604 : "n/a"));
605
606 return ret;
607 }
608
609 static int
610 handle_reassoc_request(const u_char *p, u_int length)
611 {
612 struct mgmt_body_t pbody;
613 int offset = 0;
614 int ret;
615
616 memset(&pbody, 0, sizeof(pbody));
617
618 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
619 IEEE802_11_AP_LEN))
620 return 0;
621 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
622 IEEE802_11_AP_LEN)
623 return 0;
624 pbody.capability_info = EXTRACT_LE_16BITS(p);
625 offset += IEEE802_11_CAPINFO_LEN;
626 length -= IEEE802_11_CAPINFO_LEN;
627 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
628 offset += IEEE802_11_LISTENINT_LEN;
629 length -= IEEE802_11_LISTENINT_LEN;
630 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
631 offset += IEEE802_11_AP_LEN;
632 length -= IEEE802_11_AP_LEN;
633
634 ret = parse_elements(&pbody, p, offset, length);
635
636 PRINT_SSID(pbody);
637 printf(" AP : %s", etheraddr_string( pbody.ap ));
638
639 return ret;
640 }
641
642 static int
643 handle_reassoc_response(const u_char *p, u_int length)
644 {
645 /* Same as a Association Reponse */
646 return handle_assoc_response(p, length);
647 }
648
649 static int
650 handle_probe_request(const u_char *p, u_int length)
651 {
652 struct mgmt_body_t pbody;
653 int offset = 0;
654 int ret;
655
656 memset(&pbody, 0, sizeof(pbody));
657
658 ret = parse_elements(&pbody, p, offset, length);
659
660 PRINT_SSID(pbody);
661 PRINT_RATES(pbody);
662
663 return ret;
664 }
665
666 static int
667 handle_probe_response(const u_char *p, u_int length)
668 {
669 struct mgmt_body_t pbody;
670 int offset = 0;
671 int ret;
672
673 memset(&pbody, 0, sizeof(pbody));
674
675 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
676 IEEE802_11_CAPINFO_LEN))
677 return 0;
678 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
679 IEEE802_11_CAPINFO_LEN)
680 return 0;
681 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
682 offset += IEEE802_11_TSTAMP_LEN;
683 length -= IEEE802_11_TSTAMP_LEN;
684 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
685 offset += IEEE802_11_BCNINT_LEN;
686 length -= IEEE802_11_BCNINT_LEN;
687 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
688 offset += IEEE802_11_CAPINFO_LEN;
689 length -= IEEE802_11_CAPINFO_LEN;
690
691 ret = parse_elements(&pbody, p, offset, length);
692
693 PRINT_SSID(pbody);
694 PRINT_RATES(pbody);
695 PRINT_DS_CHANNEL(pbody);
696
697 return ret;
698 }
699
700 static int
701 handle_atim(void)
702 {
703 /* the frame body for ATIM is null. */
704 return 1;
705 }
706
707 static int
708 handle_disassoc(const u_char *p, u_int length)
709 {
710 struct mgmt_body_t pbody;
711
712 memset(&pbody, 0, sizeof(pbody));
713
714 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
715 return 0;
716 if (length < IEEE802_11_REASON_LEN)
717 return 0;
718 pbody.reason_code = EXTRACT_LE_16BITS(p);
719
720 printf(": %s",
721 (pbody.reason_code < NUM_REASONS)
722 ? reason_text[pbody.reason_code]
723 : "Reserved" );
724
725 return 1;
726 }
727
728 static int
729 handle_auth(const u_char *p, u_int length)
730 {
731 struct mgmt_body_t pbody;
732 int offset = 0;
733 int ret;
734
735 memset(&pbody, 0, sizeof(pbody));
736
737 if (!TTEST2(*p, 6))
738 return 0;
739 if (length < 6)
740 return 0;
741 pbody.auth_alg = EXTRACT_LE_16BITS(p);
742 offset += 2;
743 length -= 2;
744 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
745 offset += 2;
746 length -= 2;
747 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
748 offset += 2;
749 length -= 2;
750
751 ret = parse_elements(&pbody, p, offset, length);
752
753 if ((pbody.auth_alg == 1) &&
754 ((pbody.auth_trans_seq_num == 2) ||
755 (pbody.auth_trans_seq_num == 3))) {
756 printf(" (%s)-%x [Challenge Text] %s",
757 (pbody.auth_alg < NUM_AUTH_ALGS)
758 ? auth_alg_text[pbody.auth_alg]
759 : "Reserved",
760 pbody.auth_trans_seq_num,
761 ((pbody.auth_trans_seq_num % 2)
762 ? ((pbody.status_code < NUM_STATUSES)
763 ? status_text[pbody.status_code]
764 : "n/a") : ""));
765 return ret;
766 }
767 printf(" (%s)-%x: %s",
768 (pbody.auth_alg < NUM_AUTH_ALGS)
769 ? auth_alg_text[pbody.auth_alg]
770 : "Reserved",
771 pbody.auth_trans_seq_num,
772 (pbody.auth_trans_seq_num % 2)
773 ? ((pbody.status_code < NUM_STATUSES)
774 ? status_text[pbody.status_code]
775 : "n/a")
776 : "");
777
778 return ret;
779 }
780
781 static int
782 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
783 {
784 struct mgmt_body_t pbody;
785 int offset = 0;
786 const char *reason = NULL;
787
788 memset(&pbody, 0, sizeof(pbody));
789
790 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
791 return 0;
792 if (length < IEEE802_11_REASON_LEN)
793 return 0;
794 pbody.reason_code = EXTRACT_LE_16BITS(p);
795 offset += IEEE802_11_REASON_LEN;
796 length -= IEEE802_11_REASON_LEN;
797
798 reason = (pbody.reason_code < NUM_REASONS)
799 ? reason_text[pbody.reason_code]
800 : "Reserved";
801
802 if (eflag) {
803 printf(": %s", reason);
804 } else {
805 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
806 }
807 return 1;
808 }
809
810 #define PRINT_HT_ACTION(v) (\
811 (v) == 0 ? printf("TxChWidth") : \
812 (v) == 1 ? printf("MIMOPwrSave") : \
813 printf("Act#%d", (v)) \
814 )
815 #define PRINT_BA_ACTION(v) (\
816 (v) == 0 ? printf("ADDBA Request") : \
817 (v) == 1 ? printf("ADDBA Response") : \
818 (v) == 2 ? printf("DELBA") : \
819 printf("Act#%d", (v)) \
820 )
821 #define PRINT_MESHLINK_ACTION(v) (\
822 (v) == 0 ? printf("Request") : \
823 (v) == 1 ? printf("Report") : \
824 printf("Act#%d", (v)) \
825 )
826 #define PRINT_MESHPEERING_ACTION(v) (\
827 (v) == 0 ? printf("Open") : \
828 (v) == 1 ? printf("Confirm") : \
829 (v) == 2 ? printf("Close") : \
830 printf("Act#%d", (v)) \
831 )
832 #define PRINT_MESHPATH_ACTION(v) (\
833 (v) == 0 ? printf("Request") : \
834 (v) == 1 ? printf("Report") : \
835 (v) == 2 ? printf("Error") : \
836 (v) == 3 ? printf("RootAnnouncement") : \
837 printf("Act#%d", (v)) \
838 )
839
840 static int
841 handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
842 {
843 if (!TTEST2(*p, 2))
844 return 0;
845 if (length < 2)
846 return 0;
847 if (eflag) {
848 printf(": ");
849 } else {
850 printf(" (%s): ", etheraddr_string(pmh->sa));
851 }
852 switch (p[0]) {
853 case 0: printf("Spectrum Management Act#%d", p[1]); break;
854 case 1: printf("QoS Act#%d", p[1]); break;
855 case 2: printf("DLS Act#%d", p[1]); break;
856 case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
857 case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
858 case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
859 case 15: printf("Interwork Act#%d", p[1]); break;
860 case 16: printf("Resource Act#%d", p[1]); break;
861 case 17: printf("Proxy Act#%d", p[1]); break;
862 case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
863 case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
864 case 127: printf("Vendor Act#%d", p[1]); break;
865 default:
866 printf("Reserved(%d) Act#%d", p[0], p[1]);
867 break;
868 }
869 return 1;
870 }
871
872
873 /*********************************************************************************
874 * Print Body funcs
875 *********************************************************************************/
876
877
878 static int
879 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
880 const u_char *p, u_int length)
881 {
882 switch (FC_SUBTYPE(fc)) {
883 case ST_ASSOC_REQUEST:
884 printf("Assoc Request");
885 return handle_assoc_request(p, length);
886 case ST_ASSOC_RESPONSE:
887 printf("Assoc Response");
888 return handle_assoc_response(p, length);
889 case ST_REASSOC_REQUEST:
890 printf("ReAssoc Request");
891 return handle_reassoc_request(p, length);
892 case ST_REASSOC_RESPONSE:
893 printf("ReAssoc Response");
894 return handle_reassoc_response(p, length);
895 case ST_PROBE_REQUEST:
896 printf("Probe Request");
897 return handle_probe_request(p, length);
898 case ST_PROBE_RESPONSE:
899 printf("Probe Response");
900 return handle_probe_response(p, length);
901 case ST_BEACON:
902 printf("Beacon");
903 return handle_beacon(p, length);
904 case ST_ATIM:
905 printf("ATIM");
906 return handle_atim();
907 case ST_DISASSOC:
908 printf("Disassociation");
909 return handle_disassoc(p, length);
910 case ST_AUTH:
911 printf("Authentication");
912 if (!TTEST2(*p, 3))
913 return 0;
914 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
915 printf("Authentication (Shared-Key)-3 ");
916 return wep_print(p);
917 }
918 return handle_auth(p, length);
919 case ST_DEAUTH:
920 printf("DeAuthentication");
921 return handle_deauth(pmh, p, length);
922 break;
923 case ST_ACTION:
924 printf("Action");
925 return handle_action(pmh, p, length);
926 break;
927 default:
928 printf("Unhandled Management subtype(%x)",
929 FC_SUBTYPE(fc));
930 return 1;
931 }
932 }
933
934
935 /*********************************************************************************
936 * Handles printing all the control frame types
937 *********************************************************************************/
938
939 static int
940 ctrl_body_print(u_int16_t fc, const u_char *p)
941 {
942 switch (FC_SUBTYPE(fc)) {
943 case CTRL_CONTROL_WRAPPER:
944 printf("Control Wrapper");
945 /* XXX - requires special handling */
946 break;
947 case CTRL_BAR:
948 printf("BAR");
949 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
950 return 0;
951 if (!eflag)
952 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
953 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
954 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
955 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
956 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
957 break;
958 case CTRL_BA:
959 printf("BA");
960 if (!TTEST2(*p, CTRL_BA_HDRLEN))
961 return 0;
962 if (!eflag)
963 printf(" RA:%s ",
964 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
965 break;
966 case CTRL_PS_POLL:
967 printf("Power Save-Poll");
968 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
969 return 0;
970 printf(" AID(%x)",
971 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
972 break;
973 case CTRL_RTS:
974 printf("Request-To-Send");
975 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
976 return 0;
977 if (!eflag)
978 printf(" TA:%s ",
979 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
980 break;
981 case CTRL_CTS:
982 printf("Clear-To-Send");
983 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
984 return 0;
985 if (!eflag)
986 printf(" RA:%s ",
987 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
988 break;
989 case CTRL_ACK:
990 printf("Acknowledgment");
991 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
992 return 0;
993 if (!eflag)
994 printf(" RA:%s ",
995 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
996 break;
997 case CTRL_CF_END:
998 printf("CF-End");
999 if (!TTEST2(*p, CTRL_END_HDRLEN))
1000 return 0;
1001 if (!eflag)
1002 printf(" RA:%s ",
1003 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1004 break;
1005 case CTRL_END_ACK:
1006 printf("CF-End+CF-Ack");
1007 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1008 return 0;
1009 if (!eflag)
1010 printf(" RA:%s ",
1011 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1012 break;
1013 default:
1014 printf("Unknown Ctrl Subtype");
1015 }
1016 return 1;
1017 }
1018
1019 /*
1020 * Print Header funcs
1021 */
1022
1023 /*
1024 * Data Frame - Address field contents
1025 *
1026 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1027 * 0 | 0 | DA | SA | BSSID | n/a
1028 * 0 | 1 | DA | BSSID | SA | n/a
1029 * 1 | 0 | BSSID | SA | DA | n/a
1030 * 1 | 1 | RA | TA | DA | SA
1031 */
1032
1033 static void
1034 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1035 const u_int8_t **dstp)
1036 {
1037 u_int subtype = FC_SUBTYPE(fc);
1038
1039 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1040 DATA_FRAME_IS_QOS(subtype)) {
1041 printf("CF ");
1042 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1043 if (DATA_FRAME_IS_CF_POLL(subtype))
1044 printf("Ack/Poll");
1045 else
1046 printf("Ack");
1047 } else {
1048 if (DATA_FRAME_IS_CF_POLL(subtype))
1049 printf("Poll");
1050 }
1051 if (DATA_FRAME_IS_QOS(subtype))
1052 printf("+QoS");
1053 printf(" ");
1054 }
1055
1056 #define ADDR1 (p + 4)
1057 #define ADDR2 (p + 10)
1058 #define ADDR3 (p + 16)
1059 #define ADDR4 (p + 24)
1060
1061 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1062 if (srcp != NULL)
1063 *srcp = ADDR2;
1064 if (dstp != NULL)
1065 *dstp = ADDR1;
1066 if (!eflag)
1067 return;
1068 printf("DA:%s SA:%s BSSID:%s ",
1069 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1070 etheraddr_string(ADDR3));
1071 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1072 if (srcp != NULL)
1073 *srcp = ADDR3;
1074 if (dstp != NULL)
1075 *dstp = ADDR1;
1076 if (!eflag)
1077 return;
1078 printf("DA:%s BSSID:%s SA:%s ",
1079 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1080 etheraddr_string(ADDR3));
1081 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1082 if (srcp != NULL)
1083 *srcp = ADDR2;
1084 if (dstp != NULL)
1085 *dstp = ADDR3;
1086 if (!eflag)
1087 return;
1088 printf("BSSID:%s SA:%s DA:%s ",
1089 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1090 etheraddr_string(ADDR3));
1091 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1092 if (srcp != NULL)
1093 *srcp = ADDR4;
1094 if (dstp != NULL)
1095 *dstp = ADDR3;
1096 if (!eflag)
1097 return;
1098 printf("RA:%s TA:%s DA:%s SA:%s ",
1099 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1100 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1101 }
1102
1103 #undef ADDR1
1104 #undef ADDR2
1105 #undef ADDR3
1106 #undef ADDR4
1107 }
1108
1109 static void
1110 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1111 const u_int8_t **dstp)
1112 {
1113 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1114
1115 if (srcp != NULL)
1116 *srcp = hp->sa;
1117 if (dstp != NULL)
1118 *dstp = hp->da;
1119 if (!eflag)
1120 return;
1121
1122 printf("BSSID:%s DA:%s SA:%s ",
1123 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1124 etheraddr_string((hp)->sa));
1125 }
1126
1127 static void
1128 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1129 const u_int8_t **dstp)
1130 {
1131 if (srcp != NULL)
1132 *srcp = NULL;
1133 if (dstp != NULL)
1134 *dstp = NULL;
1135 if (!eflag)
1136 return;
1137
1138 switch (FC_SUBTYPE(fc)) {
1139 case CTRL_BAR:
1140 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1141 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1142 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1143 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1144 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1145 break;
1146 case CTRL_BA:
1147 printf("RA:%s ",
1148 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1149 break;
1150 case CTRL_PS_POLL:
1151 printf("BSSID:%s TA:%s ",
1152 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1153 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1154 break;
1155 case CTRL_RTS:
1156 printf("RA:%s TA:%s ",
1157 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1158 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1159 break;
1160 case CTRL_CTS:
1161 printf("RA:%s ",
1162 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1163 break;
1164 case CTRL_ACK:
1165 printf("RA:%s ",
1166 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1167 break;
1168 case CTRL_CF_END:
1169 printf("RA:%s BSSID:%s ",
1170 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1171 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1172 break;
1173 case CTRL_END_ACK:
1174 printf("RA:%s BSSID:%s ",
1175 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1176 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1177 break;
1178 default:
1179 printf("(H) Unknown Ctrl Subtype");
1180 break;
1181 }
1182 }
1183
1184 static int
1185 extract_header_length(u_int16_t fc)
1186 {
1187 int len;
1188
1189 switch (FC_TYPE(fc)) {
1190 case T_MGMT:
1191 return MGMT_HDRLEN;
1192 case T_CTRL:
1193 switch (FC_SUBTYPE(fc)) {
1194 case CTRL_BAR:
1195 return CTRL_BAR_HDRLEN;
1196 case CTRL_PS_POLL:
1197 return CTRL_PS_POLL_HDRLEN;
1198 case CTRL_RTS:
1199 return CTRL_RTS_HDRLEN;
1200 case CTRL_CTS:
1201 return CTRL_CTS_HDRLEN;
1202 case CTRL_ACK:
1203 return CTRL_ACK_HDRLEN;
1204 case CTRL_CF_END:
1205 return CTRL_END_HDRLEN;
1206 case CTRL_END_ACK:
1207 return CTRL_END_ACK_HDRLEN;
1208 default:
1209 return 0;
1210 }
1211 case T_DATA:
1212 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1213 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1214 len += 2;
1215 return len;
1216 default:
1217 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1218 return 0;
1219 }
1220 }
1221
1222 static int
1223 extract_mesh_header_length(const u_char *p)
1224 {
1225 return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1226 }
1227
1228 /*
1229 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1230 * to point to the source and destination MAC addresses in any case if
1231 * "srcp" and "dstp" aren't null.
1232 */
1233 static void
1234 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1235 u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1236 {
1237 if (vflag) {
1238 if (FC_MORE_DATA(fc))
1239 printf("More Data ");
1240 if (FC_MORE_FLAG(fc))
1241 printf("More Fragments ");
1242 if (FC_POWER_MGMT(fc))
1243 printf("Pwr Mgmt ");
1244 if (FC_RETRY(fc))
1245 printf("Retry ");
1246 if (FC_ORDER(fc))
1247 printf("Strictly Ordered ");
1248 if (FC_WEP(fc))
1249 printf("WEP Encrypted ");
1250 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1251 printf("%dus ",
1252 EXTRACT_LE_16BITS(
1253 &((const struct mgmt_header_t *)p)->duration));
1254 }
1255 if (meshdrlen != 0) {
1256 const struct meshcntl_t *mc =
1257 (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1258 int ae = mc->flags & 3;
1259
1260 printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1261 EXTRACT_LE_32BITS(mc->seq));
1262 if (ae > 0)
1263 printf(" A4:%s", etheraddr_string(mc->addr4));
1264 if (ae > 1)
1265 printf(" A5:%s", etheraddr_string(mc->addr5));
1266 if (ae > 2)
1267 printf(" A6:%s", etheraddr_string(mc->addr6));
1268 printf(") ");
1269 }
1270
1271 switch (FC_TYPE(fc)) {
1272 case T_MGMT:
1273 mgmt_header_print(p, srcp, dstp);
1274 break;
1275 case T_CTRL:
1276 ctrl_header_print(fc, p, srcp, dstp);
1277 break;
1278 case T_DATA:
1279 data_header_print(fc, p, srcp, dstp);
1280 break;
1281 default:
1282 printf("(header) unknown IEEE802.11 frame type (%d)",
1283 FC_TYPE(fc));
1284 *srcp = NULL;
1285 *dstp = NULL;
1286 break;
1287 }
1288 }
1289
1290 #ifndef roundup2
1291 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1292 #endif
1293
1294 static u_int
1295 ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1296 u_int fcslen)
1297 {
1298 u_int16_t fc;
1299 u_int caplen, hdrlen, meshdrlen;
1300 const u_int8_t *src, *dst;
1301 u_short extracted_ethertype;
1302
1303 caplen = orig_caplen;
1304 /* Remove FCS, if present */
1305 if (length < fcslen) {
1306 printf("[|802.11]");
1307 return caplen;
1308 }
1309 length -= fcslen;
1310 if (caplen > length) {
1311 /* Amount of FCS in actual packet data, if any */
1312 fcslen = caplen - length;
1313 caplen -= fcslen;
1314 snapend -= fcslen;
1315 }
1316
1317 if (caplen < IEEE802_11_FC_LEN) {
1318 printf("[|802.11]");
1319 return orig_caplen;
1320 }
1321
1322 fc = EXTRACT_LE_16BITS(p);
1323 hdrlen = extract_header_length(fc);
1324 if (pad)
1325 hdrlen = roundup2(hdrlen, 4);
1326 if (hflag && FC_TYPE(fc) == T_DATA &&
1327 DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1328 meshdrlen = extract_mesh_header_length(p+hdrlen);
1329 hdrlen += meshdrlen;
1330 } else
1331 meshdrlen = 0;
1332
1333
1334 if (caplen < hdrlen) {
1335 printf("[|802.11]");
1336 return hdrlen;
1337 }
1338
1339 ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1340
1341 /*
1342 * Go past the 802.11 header.
1343 */
1344 length -= hdrlen;
1345 caplen -= hdrlen;
1346 p += hdrlen;
1347
1348 switch (FC_TYPE(fc)) {
1349 case T_MGMT:
1350 if (!mgmt_body_print(fc,
1351 (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1352 printf("[|802.11]");
1353 return hdrlen;
1354 }
1355 break;
1356 case T_CTRL:
1357 if (!ctrl_body_print(fc, p - hdrlen)) {
1358 printf("[|802.11]");
1359 return hdrlen;
1360 }
1361 break;
1362 case T_DATA:
1363 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1364 return hdrlen; /* no-data frame */
1365 /* There may be a problem w/ AP not having this bit set */
1366 if (FC_WEP(fc)) {
1367 if (!wep_print(p)) {
1368 printf("[|802.11]");
1369 return hdrlen;
1370 }
1371 } else if (llc_print(p, length, caplen, dst, src,
1372 &extracted_ethertype) == 0) {
1373 /*
1374 * Some kinds of LLC packet we cannot
1375 * handle intelligently
1376 */
1377 if (!eflag)
1378 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1379 meshdrlen, NULL, NULL);
1380 if (extracted_ethertype)
1381 printf("(LLC %s) ",
1382 etherproto_string(
1383 htons(extracted_ethertype)));
1384 if (!suppress_default_print)
1385 default_print(p, caplen);
1386 }
1387 break;
1388 default:
1389 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1390 break;
1391 }
1392
1393 return hdrlen;
1394 }
1395
1396 /*
1397 * This is the top level routine of the printer. 'p' points
1398 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1399 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1400 * is the number of bytes actually captured.
1401 */
1402 u_int
1403 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1404 {
1405 return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1406 }
1407
1408 #define IEEE80211_CHAN_FHSS \
1409 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1410 #define IEEE80211_CHAN_A \
1411 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1412 #define IEEE80211_CHAN_B \
1413 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1414 #define IEEE80211_CHAN_PUREG \
1415 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1416 #define IEEE80211_CHAN_G \
1417 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1418
1419 #define IS_CHAN_FHSS(flags) \
1420 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1421 #define IS_CHAN_A(flags) \
1422 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1423 #define IS_CHAN_B(flags) \
1424 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1425 #define IS_CHAN_PUREG(flags) \
1426 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1427 #define IS_CHAN_G(flags) \
1428 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1429 #define IS_CHAN_ANYG(flags) \
1430 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1431
1432 static void
1433 print_chaninfo(int freq, int flags)
1434 {
1435 printf("%u MHz", freq);
1436 if (IS_CHAN_FHSS(flags))
1437 printf(" FHSS");
1438 if (IS_CHAN_A(flags)) {
1439 if (flags & IEEE80211_CHAN_HALF)
1440 printf(" 11a/10Mhz");
1441 else if (flags & IEEE80211_CHAN_QUARTER)
1442 printf(" 11a/5Mhz");
1443 else
1444 printf(" 11a");
1445 }
1446 if (IS_CHAN_ANYG(flags)) {
1447 if (flags & IEEE80211_CHAN_HALF)
1448 printf(" 11g/10Mhz");
1449 else if (flags & IEEE80211_CHAN_QUARTER)
1450 printf(" 11g/5Mhz");
1451 else
1452 printf(" 11g");
1453 } else if (IS_CHAN_B(flags))
1454 printf(" 11b");
1455 if (flags & IEEE80211_CHAN_TURBO)
1456 printf(" Turbo");
1457 if (flags & IEEE80211_CHAN_HT20)
1458 printf(" ht/20");
1459 else if (flags & IEEE80211_CHAN_HT40D)
1460 printf(" ht/40-");
1461 else if (flags & IEEE80211_CHAN_HT40U)
1462 printf(" ht/40+");
1463 printf(" ");
1464 }
1465
1466 static int
1467 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags)
1468 {
1469 union {
1470 int8_t i8;
1471 u_int8_t u8;
1472 int16_t i16;
1473 u_int16_t u16;
1474 u_int32_t u32;
1475 u_int64_t u64;
1476 } u, u2, u3, u4;
1477 int rc;
1478
1479 switch (bit) {
1480 case IEEE80211_RADIOTAP_FLAGS:
1481 rc = cpack_uint8(s, &u.u8);
1482 if (rc != 0)
1483 break;
1484 *flags = u.u8;
1485 break;
1486 case IEEE80211_RADIOTAP_RATE:
1487 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1488 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1489 case IEEE80211_RADIOTAP_ANTENNA:
1490 rc = cpack_uint8(s, &u.u8);
1491 break;
1492 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1493 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1494 rc = cpack_int8(s, &u.i8);
1495 break;
1496 case IEEE80211_RADIOTAP_CHANNEL:
1497 rc = cpack_uint16(s, &u.u16);
1498 if (rc != 0)
1499 break;
1500 rc = cpack_uint16(s, &u2.u16);
1501 break;
1502 case IEEE80211_RADIOTAP_FHSS:
1503 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1504 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1505 rc = cpack_uint16(s, &u.u16);
1506 break;
1507 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1508 rc = cpack_uint8(s, &u.u8);
1509 break;
1510 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1511 rc = cpack_int8(s, &u.i8);
1512 break;
1513 case IEEE80211_RADIOTAP_TSFT:
1514 rc = cpack_uint64(s, &u.u64);
1515 break;
1516 case IEEE80211_RADIOTAP_XCHANNEL:
1517 rc = cpack_uint32(s, &u.u32);
1518 if (rc != 0)
1519 break;
1520 rc = cpack_uint16(s, &u2.u16);
1521 if (rc != 0)
1522 break;
1523 rc = cpack_uint8(s, &u3.u8);
1524 if (rc != 0)
1525 break;
1526 rc = cpack_uint8(s, &u4.u8);
1527 break;
1528 default:
1529 /* this bit indicates a field whose
1530 * size we do not know, so we cannot
1531 * proceed. Just print the bit number.
1532 */
1533 printf("[bit %u] ", bit);
1534 return -1;
1535 }
1536
1537 if (rc != 0) {
1538 printf("[|802.11]");
1539 return rc;
1540 }
1541
1542 switch (bit) {
1543 case IEEE80211_RADIOTAP_CHANNEL:
1544 print_chaninfo(u.u16, u2.u16);
1545 break;
1546 case IEEE80211_RADIOTAP_FHSS:
1547 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1548 break;
1549 case IEEE80211_RADIOTAP_RATE:
1550 if (u.u8 & 0x80)
1551 PRINT_HT_RATE("", u.u8, " Mb/s ");
1552 else
1553 PRINT_RATE("", u.u8, " Mb/s ");
1554 break;
1555 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1556 printf("%ddB signal ", u.i8);
1557 break;
1558 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1559 printf("%ddB noise ", u.i8);
1560 break;
1561 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1562 printf("%ddB signal ", u.u8);
1563 break;
1564 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1565 printf("%ddB noise ", u.u8);
1566 break;
1567 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1568 printf("%u sq ", u.u16);
1569 break;
1570 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1571 printf("%d tx power ", -(int)u.u16);
1572 break;
1573 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1574 printf("%ddB tx power ", -(int)u.u8);
1575 break;
1576 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1577 printf("%ddBm tx power ", u.i8);
1578 break;
1579 case IEEE80211_RADIOTAP_FLAGS:
1580 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1581 printf("cfp ");
1582 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1583 printf("short preamble ");
1584 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1585 printf("wep ");
1586 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1587 printf("fragmented ");
1588 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1589 printf("bad-fcs ");
1590 break;
1591 case IEEE80211_RADIOTAP_ANTENNA:
1592 printf("antenna %d ", u.u8);
1593 break;
1594 case IEEE80211_RADIOTAP_TSFT:
1595 printf("%" PRIu64 "us tsft ", u.u64);
1596 break;
1597 case IEEE80211_RADIOTAP_XCHANNEL:
1598 print_chaninfo(u2.u16, u.u32);
1599 break;
1600 }
1601 return 0;
1602 }
1603
1604 static u_int
1605 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1606 {
1607 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1608 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1609 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1610 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1611 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1612 #define BIT(n) (1U << n)
1613 #define IS_EXTENDED(__p) \
1614 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1615
1616 struct cpack_state cpacker;
1617 struct ieee80211_radiotap_header *hdr;
1618 u_int32_t present, next_present;
1619 u_int32_t *presentp, *last_presentp;
1620 enum ieee80211_radiotap_type bit;
1621 int bit0;
1622 const u_char *iter;
1623 u_int len;
1624 u_int8_t flags;
1625 int pad;
1626 u_int fcslen;
1627
1628 if (caplen < sizeof(*hdr)) {
1629 printf("[|802.11]");
1630 return caplen;
1631 }
1632
1633 hdr = (struct ieee80211_radiotap_header *)p;
1634
1635 len = EXTRACT_LE_16BITS(&hdr->it_len);
1636
1637 if (caplen < len) {
1638 printf("[|802.11]");
1639 return caplen;
1640 }
1641 for (last_presentp = &hdr->it_present;
1642 IS_EXTENDED(last_presentp) &&
1643 (u_char*)(last_presentp + 1) <= p + len;
1644 last_presentp++);
1645
1646 /* are there more bitmap extensions than bytes in header? */
1647 if (IS_EXTENDED(last_presentp)) {
1648 printf("[|802.11]");
1649 return caplen;
1650 }
1651
1652 iter = (u_char*)(last_presentp + 1);
1653
1654 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1655 /* XXX */
1656 printf("[|802.11]");
1657 return caplen;
1658 }
1659
1660 /* Assume no flags */
1661 flags = 0;
1662 /* Assume no Atheros padding between 802.11 header and body */
1663 pad = 0;
1664 /* Assume no FCS at end of frame */
1665 fcslen = 0;
1666 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1667 presentp++, bit0 += 32) {
1668 for (present = EXTRACT_LE_32BITS(presentp); present;
1669 present = next_present) {
1670 /* clear the least significant bit that is set */
1671 next_present = present & (present - 1);
1672
1673 /* extract the least significant bit that is set */
1674 bit = (enum ieee80211_radiotap_type)
1675 (bit0 + BITNO_32(present ^ next_present));
1676
1677 if (print_radiotap_field(&cpacker, bit, &flags) != 0)
1678 goto out;
1679 }
1680 }
1681
1682 out:
1683 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
1684 pad = 1; /* Atheros padding */
1685 if (flags & IEEE80211_RADIOTAP_F_FCS)
1686 fcslen = 4; /* FCS at end of packet */
1687 return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
1688 fcslen);
1689 #undef BITNO_32
1690 #undef BITNO_16
1691 #undef BITNO_8
1692 #undef BITNO_4
1693 #undef BITNO_2
1694 #undef BIT
1695 }
1696
1697 static u_int
1698 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1699 {
1700 u_int32_t caphdr_len;
1701
1702 if (caplen < 8) {
1703 printf("[|802.11]");
1704 return caplen;
1705 }
1706
1707 caphdr_len = EXTRACT_32BITS(p + 4);
1708 if (caphdr_len < 8) {
1709 /*
1710 * Yow! The capture header length is claimed not
1711 * to be large enough to include even the version
1712 * cookie or capture header length!
1713 */
1714 printf("[|802.11]");
1715 return caplen;
1716 }
1717
1718 if (caplen < caphdr_len) {
1719 printf("[|802.11]");
1720 return caplen;
1721 }
1722
1723 return caphdr_len + ieee802_11_print(p + caphdr_len,
1724 length - caphdr_len, caplen - caphdr_len, 0, 0);
1725 }
1726
1727 #define PRISM_HDR_LEN 144
1728
1729 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1730 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1731 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
1732
1733 /*
1734 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1735 * containing information such as radio information, which we
1736 * currently ignore.
1737 *
1738 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1739 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1740 * (currently, on Linux, there's no ARPHRD_ type for
1741 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1742 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1743 * the AVS header, and the first 4 bytes of the header are used to
1744 * indicate whether it's a Prism header or an AVS header).
1745 */
1746 u_int
1747 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1748 {
1749 u_int caplen = h->caplen;
1750 u_int length = h->len;
1751 u_int32_t msgcode;
1752
1753 if (caplen < 4) {
1754 printf("[|802.11]");
1755 return caplen;
1756 }
1757
1758 msgcode = EXTRACT_32BITS(p);
1759 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
1760 msgcode == WLANCAP_MAGIC_COOKIE_V2)
1761 return ieee802_11_avs_radio_print(p, length, caplen);
1762
1763 if (caplen < PRISM_HDR_LEN) {
1764 printf("[|802.11]");
1765 return caplen;
1766 }
1767
1768 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1769 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
1770 }
1771
1772 /*
1773 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1774 * header, containing information such as radio information.
1775 */
1776 u_int
1777 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1778 {
1779 return ieee802_11_radio_print(p, h->len, h->caplen);
1780 }
1781
1782 /*
1783 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1784 * extra header, containing information such as radio information,
1785 * which we currently ignore.
1786 */
1787 u_int
1788 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
1789 {
1790 return ieee802_11_avs_radio_print(p, h->len, h->caplen);
1791 }