]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
Fix the pointer tests in the non-ndoified TTEST2() macro as well.
[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 struct ssid_t ssid;
273 struct challenge_t challenge;
274 struct rates_t rates;
275 struct ds_t ds;
276 struct cf_t cf;
277 struct tim_t tim;
278
279 /*
280 * We haven't seen any elements yet.
281 */
282 pbody->challenge_present = 0;
283 pbody->ssid_present = 0;
284 pbody->rates_present = 0;
285 pbody->ds_present = 0;
286 pbody->cf_present = 0;
287 pbody->tim_present = 0;
288
289 while (length != 0) {
290 if (!TTEST2(*(p + offset), 1))
291 return 0;
292 if (length < 1)
293 return 0;
294 switch (*(p + offset)) {
295 case E_SSID:
296 if (!TTEST2(*(p + offset), 2))
297 return 0;
298 if (length < 2)
299 return 0;
300 memcpy(&ssid, p + offset, 2);
301 offset += 2;
302 length -= 2;
303 if (ssid.length != 0) {
304 if (ssid.length > sizeof(ssid.ssid) - 1)
305 return 0;
306 if (!TTEST2(*(p + offset), ssid.length))
307 return 0;
308 if (length < ssid.length)
309 return 0;
310 memcpy(&ssid.ssid, p + offset, ssid.length);
311 offset += ssid.length;
312 length -= ssid.length;
313 }
314 ssid.ssid[ssid.length] = '\0';
315 /*
316 * Present and not truncated.
317 *
318 * If we haven't already seen an SSID IE,
319 * copy this one, otherwise ignore this one,
320 * so we later report the first one we saw.
321 */
322 if (!pbody->ssid_present) {
323 pbody->ssid = ssid;
324 pbody->ssid_present = 1;
325 }
326 break;
327 case E_CHALLENGE:
328 if (!TTEST2(*(p + offset), 2))
329 return 0;
330 if (length < 2)
331 return 0;
332 memcpy(&challenge, p + offset, 2);
333 offset += 2;
334 length -= 2;
335 if (challenge.length != 0) {
336 if (challenge.length >
337 sizeof(challenge.text) - 1)
338 return 0;
339 if (!TTEST2(*(p + offset), challenge.length))
340 return 0;
341 if (length < challenge.length)
342 return 0;
343 memcpy(&challenge.text, p + offset,
344 challenge.length);
345 offset += challenge.length;
346 length -= challenge.length;
347 }
348 challenge.text[challenge.length] = '\0';
349 /*
350 * Present and not truncated.
351 *
352 * If we haven't already seen a challenge IE,
353 * copy this one, otherwise ignore this one,
354 * so we later report the first one we saw.
355 */
356 if (!pbody->challenge_present) {
357 pbody->challenge = challenge;
358 pbody->challenge_present = 1;
359 }
360 break;
361 case E_RATES:
362 if (!TTEST2(*(p + offset), 2))
363 return 0;
364 if (length < 2)
365 return 0;
366 memcpy(&rates, p + offset, 2);
367 offset += 2;
368 length -= 2;
369 if (rates.length != 0) {
370 if (rates.length > sizeof rates.rate)
371 return 0;
372 if (!TTEST2(*(p + offset), rates.length))
373 return 0;
374 if (length < rates.length)
375 return 0;
376 memcpy(&rates.rate, p + offset, rates.length);
377 offset += rates.length;
378 length -= rates.length;
379 }
380 /*
381 * Present and not truncated.
382 *
383 * If we haven't already seen a rates IE,
384 * copy this one if it's not zero-length,
385 * otherwise ignore this one, so we later
386 * report the first one we saw.
387 *
388 * We ignore zero-length rates IEs as some
389 * devices seem to put a zero-length rates
390 * IE, followed by an SSID IE, followed by
391 * a non-zero-length rates IE into frames,
392 * even though IEEE Std 802.11-2007 doesn't
393 * seem to indicate that a zero-length rates
394 * IE is valid.
395 */
396 if (!pbody->rates_present && rates.length != 0) {
397 pbody->rates = rates;
398 pbody->rates_present = 1;
399 }
400 break;
401 case E_DS:
402 if (!TTEST2(*(p + offset), 3))
403 return 0;
404 if (length < 3)
405 return 0;
406 memcpy(&ds, p + offset, 3);
407 offset += 3;
408 length -= 3;
409 /*
410 * Present and not truncated.
411 *
412 * If we haven't already seen a DS IE,
413 * copy this one, otherwise ignore this one,
414 * so we later report the first one we saw.
415 */
416 if (!pbody->ds_present) {
417 pbody->ds = ds;
418 pbody->ds_present = 1;
419 }
420 break;
421 case E_CF:
422 if (!TTEST2(*(p + offset), 8))
423 return 0;
424 if (length < 8)
425 return 0;
426 memcpy(&cf, p + offset, 8);
427 offset += 8;
428 length -= 8;
429 /*
430 * Present and not truncated.
431 *
432 * If we haven't already seen a CF IE,
433 * copy this one, otherwise ignore this one,
434 * so we later report the first one we saw.
435 */
436 if (!pbody->cf_present) {
437 pbody->cf = cf;
438 pbody->cf_present = 1;
439 }
440 break;
441 case E_TIM:
442 if (!TTEST2(*(p + offset), 2))
443 return 0;
444 if (length < 2)
445 return 0;
446 memcpy(&tim, p + offset, 2);
447 offset += 2;
448 length -= 2;
449 if (!TTEST2(*(p + offset), 3))
450 return 0;
451 if (length < 3)
452 return 0;
453 memcpy(&tim.count, p + offset, 3);
454 offset += 3;
455 length -= 3;
456
457 if (tim.length <= 3)
458 break;
459 if (tim.length - 3 > (int)sizeof tim.bitmap)
460 return 0;
461 if (!TTEST2(*(p + offset), tim.length - 3))
462 return 0;
463 if (length < (u_int)(tim.length - 3))
464 return 0;
465 memcpy(tim.bitmap, p + (tim.length - 3),
466 (tim.length - 3));
467 offset += tim.length - 3;
468 length -= tim.length - 3;
469 /*
470 * Present and not truncated.
471 *
472 * If we haven't already seen a TIM IE,
473 * copy this one, otherwise ignore this one,
474 * so we later report the first one we saw.
475 */
476 if (!pbody->tim_present) {
477 pbody->tim = tim;
478 pbody->tim_present = 1;
479 }
480 break;
481 default:
482 #if 0
483 printf("(1) unhandled element_id (%d) ",
484 *(p + offset));
485 #endif
486 if (!TTEST2(*(p + offset), 2))
487 return 0;
488 if (length < 2)
489 return 0;
490 if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
491 return 0;
492 if (length < (u_int)(*(p + offset + 1) + 2))
493 return 0;
494 offset += *(p + offset + 1) + 2;
495 length -= *(p + offset + 1) + 2;
496 break;
497 }
498 }
499
500 /* No problems found. */
501 return 1;
502 }
503
504 /*********************************************************************************
505 * Print Handle functions for the management frame types
506 *********************************************************************************/
507
508 static int
509 handle_beacon(const u_char *p, u_int length)
510 {
511 struct mgmt_body_t pbody;
512 int offset = 0;
513 int ret;
514
515 memset(&pbody, 0, sizeof(pbody));
516
517 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
518 IEEE802_11_CAPINFO_LEN))
519 return 0;
520 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
521 IEEE802_11_CAPINFO_LEN)
522 return 0;
523 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
524 offset += IEEE802_11_TSTAMP_LEN;
525 length -= IEEE802_11_TSTAMP_LEN;
526 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
527 offset += IEEE802_11_BCNINT_LEN;
528 length -= IEEE802_11_BCNINT_LEN;
529 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
530 offset += IEEE802_11_CAPINFO_LEN;
531 length -= IEEE802_11_CAPINFO_LEN;
532
533 ret = parse_elements(&pbody, p, offset, length);
534
535 PRINT_SSID(pbody);
536 PRINT_RATES(pbody);
537 printf(" %s",
538 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
539 PRINT_DS_CHANNEL(pbody);
540
541 return ret;
542 }
543
544 static int
545 handle_assoc_request(const u_char *p, u_int length)
546 {
547 struct mgmt_body_t pbody;
548 int offset = 0;
549 int ret;
550
551 memset(&pbody, 0, sizeof(pbody));
552
553 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
554 return 0;
555 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
556 return 0;
557 pbody.capability_info = EXTRACT_LE_16BITS(p);
558 offset += IEEE802_11_CAPINFO_LEN;
559 length -= IEEE802_11_CAPINFO_LEN;
560 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
561 offset += IEEE802_11_LISTENINT_LEN;
562 length -= IEEE802_11_LISTENINT_LEN;
563
564 ret = parse_elements(&pbody, p, offset, length);
565
566 PRINT_SSID(pbody);
567 PRINT_RATES(pbody);
568 return ret;
569 }
570
571 static int
572 handle_assoc_response(const u_char *p, u_int length)
573 {
574 struct mgmt_body_t pbody;
575 int offset = 0;
576 int ret;
577
578 memset(&pbody, 0, sizeof(pbody));
579
580 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
581 IEEE802_11_AID_LEN))
582 return 0;
583 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
584 IEEE802_11_AID_LEN)
585 return 0;
586 pbody.capability_info = EXTRACT_LE_16BITS(p);
587 offset += IEEE802_11_CAPINFO_LEN;
588 length -= IEEE802_11_CAPINFO_LEN;
589 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
590 offset += IEEE802_11_STATUS_LEN;
591 length -= IEEE802_11_STATUS_LEN;
592 pbody.aid = EXTRACT_LE_16BITS(p+offset);
593 offset += IEEE802_11_AID_LEN;
594 length -= IEEE802_11_AID_LEN;
595
596 ret = parse_elements(&pbody, p, offset, length);
597
598 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
599 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
600 (pbody.status_code < NUM_STATUSES
601 ? status_text[pbody.status_code]
602 : "n/a"));
603
604 return ret;
605 }
606
607 static int
608 handle_reassoc_request(const u_char *p, u_int length)
609 {
610 struct mgmt_body_t pbody;
611 int offset = 0;
612 int ret;
613
614 memset(&pbody, 0, sizeof(pbody));
615
616 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
617 IEEE802_11_AP_LEN))
618 return 0;
619 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
620 IEEE802_11_AP_LEN)
621 return 0;
622 pbody.capability_info = EXTRACT_LE_16BITS(p);
623 offset += IEEE802_11_CAPINFO_LEN;
624 length -= IEEE802_11_CAPINFO_LEN;
625 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
626 offset += IEEE802_11_LISTENINT_LEN;
627 length -= IEEE802_11_LISTENINT_LEN;
628 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
629 offset += IEEE802_11_AP_LEN;
630 length -= IEEE802_11_AP_LEN;
631
632 ret = parse_elements(&pbody, p, offset, length);
633
634 PRINT_SSID(pbody);
635 printf(" AP : %s", etheraddr_string( pbody.ap ));
636
637 return ret;
638 }
639
640 static int
641 handle_reassoc_response(const u_char *p, u_int length)
642 {
643 /* Same as a Association Reponse */
644 return handle_assoc_response(p, length);
645 }
646
647 static int
648 handle_probe_request(const u_char *p, u_int length)
649 {
650 struct mgmt_body_t pbody;
651 int offset = 0;
652 int ret;
653
654 memset(&pbody, 0, sizeof(pbody));
655
656 ret = parse_elements(&pbody, p, offset, length);
657
658 PRINT_SSID(pbody);
659 PRINT_RATES(pbody);
660
661 return ret;
662 }
663
664 static int
665 handle_probe_response(const u_char *p, u_int length)
666 {
667 struct mgmt_body_t pbody;
668 int offset = 0;
669 int ret;
670
671 memset(&pbody, 0, sizeof(pbody));
672
673 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
674 IEEE802_11_CAPINFO_LEN))
675 return 0;
676 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
677 IEEE802_11_CAPINFO_LEN)
678 return 0;
679 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
680 offset += IEEE802_11_TSTAMP_LEN;
681 length -= IEEE802_11_TSTAMP_LEN;
682 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
683 offset += IEEE802_11_BCNINT_LEN;
684 length -= IEEE802_11_BCNINT_LEN;
685 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
686 offset += IEEE802_11_CAPINFO_LEN;
687 length -= IEEE802_11_CAPINFO_LEN;
688
689 ret = parse_elements(&pbody, p, offset, length);
690
691 PRINT_SSID(pbody);
692 PRINT_RATES(pbody);
693 PRINT_DS_CHANNEL(pbody);
694
695 return ret;
696 }
697
698 static int
699 handle_atim(void)
700 {
701 /* the frame body for ATIM is null. */
702 return 1;
703 }
704
705 static int
706 handle_disassoc(const u_char *p, u_int length)
707 {
708 struct mgmt_body_t pbody;
709
710 memset(&pbody, 0, sizeof(pbody));
711
712 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
713 return 0;
714 if (length < IEEE802_11_REASON_LEN)
715 return 0;
716 pbody.reason_code = EXTRACT_LE_16BITS(p);
717
718 printf(": %s",
719 (pbody.reason_code < NUM_REASONS)
720 ? reason_text[pbody.reason_code]
721 : "Reserved" );
722
723 return 1;
724 }
725
726 static int
727 handle_auth(const u_char *p, u_int length)
728 {
729 struct mgmt_body_t pbody;
730 int offset = 0;
731 int ret;
732
733 memset(&pbody, 0, sizeof(pbody));
734
735 if (!TTEST2(*p, 6))
736 return 0;
737 if (length < 6)
738 return 0;
739 pbody.auth_alg = EXTRACT_LE_16BITS(p);
740 offset += 2;
741 length -= 2;
742 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
743 offset += 2;
744 length -= 2;
745 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
746 offset += 2;
747 length -= 2;
748
749 ret = parse_elements(&pbody, p, offset, length);
750
751 if ((pbody.auth_alg == 1) &&
752 ((pbody.auth_trans_seq_num == 2) ||
753 (pbody.auth_trans_seq_num == 3))) {
754 printf(" (%s)-%x [Challenge Text] %s",
755 (pbody.auth_alg < NUM_AUTH_ALGS)
756 ? auth_alg_text[pbody.auth_alg]
757 : "Reserved",
758 pbody.auth_trans_seq_num,
759 ((pbody.auth_trans_seq_num % 2)
760 ? ((pbody.status_code < NUM_STATUSES)
761 ? status_text[pbody.status_code]
762 : "n/a") : ""));
763 return ret;
764 }
765 printf(" (%s)-%x: %s",
766 (pbody.auth_alg < NUM_AUTH_ALGS)
767 ? auth_alg_text[pbody.auth_alg]
768 : "Reserved",
769 pbody.auth_trans_seq_num,
770 (pbody.auth_trans_seq_num % 2)
771 ? ((pbody.status_code < NUM_STATUSES)
772 ? status_text[pbody.status_code]
773 : "n/a")
774 : "");
775
776 return ret;
777 }
778
779 static int
780 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
781 {
782 struct mgmt_body_t pbody;
783 int offset = 0;
784 const char *reason = NULL;
785
786 memset(&pbody, 0, sizeof(pbody));
787
788 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
789 return 0;
790 if (length < IEEE802_11_REASON_LEN)
791 return 0;
792 pbody.reason_code = EXTRACT_LE_16BITS(p);
793 offset += IEEE802_11_REASON_LEN;
794 length -= IEEE802_11_REASON_LEN;
795
796 reason = (pbody.reason_code < NUM_REASONS)
797 ? reason_text[pbody.reason_code]
798 : "Reserved";
799
800 if (eflag) {
801 printf(": %s", reason);
802 } else {
803 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
804 }
805 return 1;
806 }
807
808 #define PRINT_HT_ACTION(v) (\
809 (v) == 0 ? printf("TxChWidth") : \
810 (v) == 1 ? printf("MIMOPwrSave") : \
811 printf("Act#%d", (v)) \
812 )
813 #define PRINT_BA_ACTION(v) (\
814 (v) == 0 ? printf("ADDBA Request") : \
815 (v) == 1 ? printf("ADDBA Response") : \
816 (v) == 2 ? printf("DELBA") : \
817 printf("Act#%d", (v)) \
818 )
819 #define PRINT_MESHLINK_ACTION(v) (\
820 (v) == 0 ? printf("Request") : \
821 (v) == 1 ? printf("Report") : \
822 printf("Act#%d", (v)) \
823 )
824 #define PRINT_MESHPEERING_ACTION(v) (\
825 (v) == 0 ? printf("Open") : \
826 (v) == 1 ? printf("Confirm") : \
827 (v) == 2 ? printf("Close") : \
828 printf("Act#%d", (v)) \
829 )
830 #define PRINT_MESHPATH_ACTION(v) (\
831 (v) == 0 ? printf("Request") : \
832 (v) == 1 ? printf("Report") : \
833 (v) == 2 ? printf("Error") : \
834 (v) == 3 ? printf("RootAnnouncement") : \
835 printf("Act#%d", (v)) \
836 )
837
838 static int
839 handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
840 {
841 if (!TTEST2(*p, 2))
842 return 0;
843 if (length < 2)
844 return 0;
845 if (eflag) {
846 printf(": ");
847 } else {
848 printf(" (%s): ", etheraddr_string(pmh->sa));
849 }
850 switch (p[0]) {
851 case 0: printf("Spectrum Management Act#%d", p[1]); break;
852 case 1: printf("QoS Act#%d", p[1]); break;
853 case 2: printf("DLS Act#%d", p[1]); break;
854 case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
855 case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
856 case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
857 case 15: printf("Interwork Act#%d", p[1]); break;
858 case 16: printf("Resource Act#%d", p[1]); break;
859 case 17: printf("Proxy Act#%d", p[1]); break;
860 case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
861 case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
862 case 127: printf("Vendor Act#%d", p[1]); break;
863 default:
864 printf("Reserved(%d) Act#%d", p[0], p[1]);
865 break;
866 }
867 return 1;
868 }
869
870
871 /*********************************************************************************
872 * Print Body funcs
873 *********************************************************************************/
874
875
876 static int
877 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
878 const u_char *p, u_int length)
879 {
880 switch (FC_SUBTYPE(fc)) {
881 case ST_ASSOC_REQUEST:
882 printf("Assoc Request");
883 return handle_assoc_request(p, length);
884 case ST_ASSOC_RESPONSE:
885 printf("Assoc Response");
886 return handle_assoc_response(p, length);
887 case ST_REASSOC_REQUEST:
888 printf("ReAssoc Request");
889 return handle_reassoc_request(p, length);
890 case ST_REASSOC_RESPONSE:
891 printf("ReAssoc Response");
892 return handle_reassoc_response(p, length);
893 case ST_PROBE_REQUEST:
894 printf("Probe Request");
895 return handle_probe_request(p, length);
896 case ST_PROBE_RESPONSE:
897 printf("Probe Response");
898 return handle_probe_response(p, length);
899 case ST_BEACON:
900 printf("Beacon");
901 return handle_beacon(p, length);
902 case ST_ATIM:
903 printf("ATIM");
904 return handle_atim();
905 case ST_DISASSOC:
906 printf("Disassociation");
907 return handle_disassoc(p, length);
908 case ST_AUTH:
909 printf("Authentication");
910 if (!TTEST2(*p, 3))
911 return 0;
912 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
913 printf("Authentication (Shared-Key)-3 ");
914 return wep_print(p);
915 }
916 return handle_auth(p, length);
917 case ST_DEAUTH:
918 printf("DeAuthentication");
919 return handle_deauth(pmh, p, length);
920 break;
921 case ST_ACTION:
922 printf("Action");
923 return handle_action(pmh, p, length);
924 break;
925 default:
926 printf("Unhandled Management subtype(%x)",
927 FC_SUBTYPE(fc));
928 return 1;
929 }
930 }
931
932
933 /*********************************************************************************
934 * Handles printing all the control frame types
935 *********************************************************************************/
936
937 static int
938 ctrl_body_print(u_int16_t fc, const u_char *p)
939 {
940 switch (FC_SUBTYPE(fc)) {
941 case CTRL_CONTROL_WRAPPER:
942 printf("Control Wrapper");
943 /* XXX - requires special handling */
944 break;
945 case CTRL_BAR:
946 printf("BAR");
947 if (!TTEST2(*p, CTRL_BAR_HDRLEN))
948 return 0;
949 if (!eflag)
950 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
951 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
952 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
953 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
954 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
955 break;
956 case CTRL_BA:
957 printf("BA");
958 if (!TTEST2(*p, CTRL_BA_HDRLEN))
959 return 0;
960 if (!eflag)
961 printf(" RA:%s ",
962 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
963 break;
964 case CTRL_PS_POLL:
965 printf("Power Save-Poll");
966 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
967 return 0;
968 printf(" AID(%x)",
969 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
970 break;
971 case CTRL_RTS:
972 printf("Request-To-Send");
973 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
974 return 0;
975 if (!eflag)
976 printf(" TA:%s ",
977 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
978 break;
979 case CTRL_CTS:
980 printf("Clear-To-Send");
981 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
982 return 0;
983 if (!eflag)
984 printf(" RA:%s ",
985 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
986 break;
987 case CTRL_ACK:
988 printf("Acknowledgment");
989 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
990 return 0;
991 if (!eflag)
992 printf(" RA:%s ",
993 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
994 break;
995 case CTRL_CF_END:
996 printf("CF-End");
997 if (!TTEST2(*p, CTRL_END_HDRLEN))
998 return 0;
999 if (!eflag)
1000 printf(" RA:%s ",
1001 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
1002 break;
1003 case CTRL_END_ACK:
1004 printf("CF-End+CF-Ack");
1005 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
1006 return 0;
1007 if (!eflag)
1008 printf(" RA:%s ",
1009 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
1010 break;
1011 default:
1012 printf("Unknown Ctrl Subtype");
1013 }
1014 return 1;
1015 }
1016
1017 /*
1018 * Print Header funcs
1019 */
1020
1021 /*
1022 * Data Frame - Address field contents
1023 *
1024 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1025 * 0 | 0 | DA | SA | BSSID | n/a
1026 * 0 | 1 | DA | BSSID | SA | n/a
1027 * 1 | 0 | BSSID | SA | DA | n/a
1028 * 1 | 1 | RA | TA | DA | SA
1029 */
1030
1031 static void
1032 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1033 const u_int8_t **dstp)
1034 {
1035 u_int subtype = FC_SUBTYPE(fc);
1036
1037 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1038 DATA_FRAME_IS_QOS(subtype)) {
1039 printf("CF ");
1040 if (DATA_FRAME_IS_CF_ACK(subtype)) {
1041 if (DATA_FRAME_IS_CF_POLL(subtype))
1042 printf("Ack/Poll");
1043 else
1044 printf("Ack");
1045 } else {
1046 if (DATA_FRAME_IS_CF_POLL(subtype))
1047 printf("Poll");
1048 }
1049 if (DATA_FRAME_IS_QOS(subtype))
1050 printf("+QoS");
1051 printf(" ");
1052 }
1053
1054 #define ADDR1 (p + 4)
1055 #define ADDR2 (p + 10)
1056 #define ADDR3 (p + 16)
1057 #define ADDR4 (p + 24)
1058
1059 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1060 if (srcp != NULL)
1061 *srcp = ADDR2;
1062 if (dstp != NULL)
1063 *dstp = ADDR1;
1064 if (!eflag)
1065 return;
1066 printf("DA:%s SA:%s BSSID:%s ",
1067 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1068 etheraddr_string(ADDR3));
1069 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1070 if (srcp != NULL)
1071 *srcp = ADDR3;
1072 if (dstp != NULL)
1073 *dstp = ADDR1;
1074 if (!eflag)
1075 return;
1076 printf("DA:%s BSSID:%s SA:%s ",
1077 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1078 etheraddr_string(ADDR3));
1079 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1080 if (srcp != NULL)
1081 *srcp = ADDR2;
1082 if (dstp != NULL)
1083 *dstp = ADDR3;
1084 if (!eflag)
1085 return;
1086 printf("BSSID:%s SA:%s DA:%s ",
1087 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1088 etheraddr_string(ADDR3));
1089 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1090 if (srcp != NULL)
1091 *srcp = ADDR4;
1092 if (dstp != NULL)
1093 *dstp = ADDR3;
1094 if (!eflag)
1095 return;
1096 printf("RA:%s TA:%s DA:%s SA:%s ",
1097 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
1098 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
1099 }
1100
1101 #undef ADDR1
1102 #undef ADDR2
1103 #undef ADDR3
1104 #undef ADDR4
1105 }
1106
1107 static void
1108 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
1109 const u_int8_t **dstp)
1110 {
1111 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1112
1113 if (srcp != NULL)
1114 *srcp = hp->sa;
1115 if (dstp != NULL)
1116 *dstp = hp->da;
1117 if (!eflag)
1118 return;
1119
1120 printf("BSSID:%s DA:%s SA:%s ",
1121 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
1122 etheraddr_string((hp)->sa));
1123 }
1124
1125 static void
1126 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
1127 const u_int8_t **dstp)
1128 {
1129 if (srcp != NULL)
1130 *srcp = NULL;
1131 if (dstp != NULL)
1132 *dstp = NULL;
1133 if (!eflag)
1134 return;
1135
1136 switch (FC_SUBTYPE(fc)) {
1137 case CTRL_BAR:
1138 printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1139 etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
1140 etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
1141 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
1142 EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
1143 break;
1144 case CTRL_BA:
1145 printf("RA:%s ",
1146 etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
1147 break;
1148 case CTRL_PS_POLL:
1149 printf("BSSID:%s TA:%s ",
1150 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
1151 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
1152 break;
1153 case CTRL_RTS:
1154 printf("RA:%s TA:%s ",
1155 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
1156 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
1157 break;
1158 case CTRL_CTS:
1159 printf("RA:%s ",
1160 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
1161 break;
1162 case CTRL_ACK:
1163 printf("RA:%s ",
1164 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
1165 break;
1166 case CTRL_CF_END:
1167 printf("RA:%s BSSID:%s ",
1168 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
1169 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
1170 break;
1171 case CTRL_END_ACK:
1172 printf("RA:%s BSSID:%s ",
1173 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
1174 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
1175 break;
1176 default:
1177 printf("(H) Unknown Ctrl Subtype");
1178 break;
1179 }
1180 }
1181
1182 static int
1183 extract_header_length(u_int16_t fc)
1184 {
1185 int len;
1186
1187 switch (FC_TYPE(fc)) {
1188 case T_MGMT:
1189 return MGMT_HDRLEN;
1190 case T_CTRL:
1191 switch (FC_SUBTYPE(fc)) {
1192 case CTRL_BAR:
1193 return CTRL_BAR_HDRLEN;
1194 case CTRL_PS_POLL:
1195 return CTRL_PS_POLL_HDRLEN;
1196 case CTRL_RTS:
1197 return CTRL_RTS_HDRLEN;
1198 case CTRL_CTS:
1199 return CTRL_CTS_HDRLEN;
1200 case CTRL_ACK:
1201 return CTRL_ACK_HDRLEN;
1202 case CTRL_CF_END:
1203 return CTRL_END_HDRLEN;
1204 case CTRL_END_ACK:
1205 return CTRL_END_ACK_HDRLEN;
1206 default:
1207 return 0;
1208 }
1209 case T_DATA:
1210 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
1211 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
1212 len += 2;
1213 return len;
1214 default:
1215 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
1216 return 0;
1217 }
1218 }
1219
1220 static int
1221 extract_mesh_header_length(const u_char *p)
1222 {
1223 return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
1224 }
1225
1226 /*
1227 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
1228 * to point to the source and destination MAC addresses in any case if
1229 * "srcp" and "dstp" aren't null.
1230 */
1231 static void
1232 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
1233 u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
1234 {
1235 if (vflag) {
1236 if (FC_MORE_DATA(fc))
1237 printf("More Data ");
1238 if (FC_MORE_FLAG(fc))
1239 printf("More Fragments ");
1240 if (FC_POWER_MGMT(fc))
1241 printf("Pwr Mgmt ");
1242 if (FC_RETRY(fc))
1243 printf("Retry ");
1244 if (FC_ORDER(fc))
1245 printf("Strictly Ordered ");
1246 if (FC_WEP(fc))
1247 printf("WEP Encrypted ");
1248 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
1249 printf("%dus ",
1250 EXTRACT_LE_16BITS(
1251 &((const struct mgmt_header_t *)p)->duration));
1252 }
1253 if (meshdrlen != 0) {
1254 const struct meshcntl_t *mc =
1255 (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
1256 int ae = mc->flags & 3;
1257
1258 printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
1259 EXTRACT_LE_32BITS(mc->seq));
1260 if (ae > 0)
1261 printf(" A4:%s", etheraddr_string(mc->addr4));
1262 if (ae > 1)
1263 printf(" A5:%s", etheraddr_string(mc->addr5));
1264 if (ae > 2)
1265 printf(" A6:%s", etheraddr_string(mc->addr6));
1266 printf(") ");
1267 }
1268
1269 switch (FC_TYPE(fc)) {
1270 case T_MGMT:
1271 mgmt_header_print(p, srcp, dstp);
1272 break;
1273 case T_CTRL:
1274 ctrl_header_print(fc, p, srcp, dstp);
1275 break;
1276 case T_DATA:
1277 data_header_print(fc, p, srcp, dstp);
1278 break;
1279 default:
1280 printf("(header) unknown IEEE802.11 frame type (%d)",
1281 FC_TYPE(fc));
1282 *srcp = NULL;
1283 *dstp = NULL;
1284 break;
1285 }
1286 }
1287
1288 #ifndef roundup2
1289 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1290 #endif
1291
1292 static u_int
1293 ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
1294 u_int fcslen)
1295 {
1296 u_int16_t fc;
1297 u_int caplen, hdrlen, meshdrlen;
1298 const u_int8_t *src, *dst;
1299 u_short extracted_ethertype;
1300
1301 caplen = orig_caplen;
1302 /* Remove FCS, if present */
1303 if (length < fcslen) {
1304 printf("[|802.11]");
1305 return caplen;
1306 }
1307 length -= fcslen;
1308 if (caplen > length) {
1309 /* Amount of FCS in actual packet data, if any */
1310 fcslen = caplen - length;
1311 caplen -= fcslen;
1312 snapend -= fcslen;
1313 }
1314
1315 if (caplen < IEEE802_11_FC_LEN) {
1316 printf("[|802.11]");
1317 return orig_caplen;
1318 }
1319
1320 fc = EXTRACT_LE_16BITS(p);
1321 hdrlen = extract_header_length(fc);
1322 if (pad)
1323 hdrlen = roundup2(hdrlen, 4);
1324 if (hflag && FC_TYPE(fc) == T_DATA &&
1325 DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1326 meshdrlen = extract_mesh_header_length(p+hdrlen);
1327 hdrlen += meshdrlen;
1328 } else
1329 meshdrlen = 0;
1330
1331
1332 if (caplen < hdrlen) {
1333 printf("[|802.11]");
1334 return hdrlen;
1335 }
1336
1337 ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1338
1339 /*
1340 * Go past the 802.11 header.
1341 */
1342 length -= hdrlen;
1343 caplen -= hdrlen;
1344 p += hdrlen;
1345
1346 switch (FC_TYPE(fc)) {
1347 case T_MGMT:
1348 if (!mgmt_body_print(fc,
1349 (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1350 printf("[|802.11]");
1351 return hdrlen;
1352 }
1353 break;
1354 case T_CTRL:
1355 if (!ctrl_body_print(fc, p - hdrlen)) {
1356 printf("[|802.11]");
1357 return hdrlen;
1358 }
1359 break;
1360 case T_DATA:
1361 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1362 return hdrlen; /* no-data frame */
1363 /* There may be a problem w/ AP not having this bit set */
1364 if (FC_WEP(fc)) {
1365 if (!wep_print(p)) {
1366 printf("[|802.11]");
1367 return hdrlen;
1368 }
1369 } else if (llc_print(p, length, caplen, dst, src,
1370 &extracted_ethertype) == 0) {
1371 /*
1372 * Some kinds of LLC packet we cannot
1373 * handle intelligently
1374 */
1375 if (!eflag)
1376 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1377 meshdrlen, NULL, NULL);
1378 if (extracted_ethertype)
1379 printf("(LLC %s) ",
1380 etherproto_string(
1381 htons(extracted_ethertype)));
1382 if (!suppress_default_print)
1383 default_print(p, caplen);
1384 }
1385 break;
1386 default:
1387 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1388 break;
1389 }
1390
1391 return hdrlen;
1392 }
1393
1394 /*
1395 * This is the top level routine of the printer. 'p' points
1396 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1397 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1398 * is the number of bytes actually captured.
1399 */
1400 u_int
1401 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1402 {
1403 return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1404 }
1405
1406 #define IEEE80211_CHAN_FHSS \
1407 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1408 #define IEEE80211_CHAN_A \
1409 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1410 #define IEEE80211_CHAN_B \
1411 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1412 #define IEEE80211_CHAN_PUREG \
1413 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1414 #define IEEE80211_CHAN_G \
1415 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1416
1417 #define IS_CHAN_FHSS(flags) \
1418 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1419 #define IS_CHAN_A(flags) \
1420 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1421 #define IS_CHAN_B(flags) \
1422 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1423 #define IS_CHAN_PUREG(flags) \
1424 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1425 #define IS_CHAN_G(flags) \
1426 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1427 #define IS_CHAN_ANYG(flags) \
1428 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1429
1430 static void
1431 print_chaninfo(int freq, int flags)
1432 {
1433 printf("%u MHz", freq);
1434 if (IS_CHAN_FHSS(flags))
1435 printf(" FHSS");
1436 if (IS_CHAN_A(flags)) {
1437 if (flags & IEEE80211_CHAN_HALF)
1438 printf(" 11a/10Mhz");
1439 else if (flags & IEEE80211_CHAN_QUARTER)
1440 printf(" 11a/5Mhz");
1441 else
1442 printf(" 11a");
1443 }
1444 if (IS_CHAN_ANYG(flags)) {
1445 if (flags & IEEE80211_CHAN_HALF)
1446 printf(" 11g/10Mhz");
1447 else if (flags & IEEE80211_CHAN_QUARTER)
1448 printf(" 11g/5Mhz");
1449 else
1450 printf(" 11g");
1451 } else if (IS_CHAN_B(flags))
1452 printf(" 11b");
1453 if (flags & IEEE80211_CHAN_TURBO)
1454 printf(" Turbo");
1455 if (flags & IEEE80211_CHAN_HT20)
1456 printf(" ht/20");
1457 else if (flags & IEEE80211_CHAN_HT40D)
1458 printf(" ht/40-");
1459 else if (flags & IEEE80211_CHAN_HT40U)
1460 printf(" ht/40+");
1461 printf(" ");
1462 }
1463
1464 static int
1465 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags)
1466 {
1467 union {
1468 int8_t i8;
1469 u_int8_t u8;
1470 int16_t i16;
1471 u_int16_t u16;
1472 u_int32_t u32;
1473 u_int64_t u64;
1474 } u, u2, u3, u4;
1475 int rc;
1476
1477 switch (bit) {
1478 case IEEE80211_RADIOTAP_FLAGS:
1479 rc = cpack_uint8(s, &u.u8);
1480 *flags = u.u8;
1481 break;
1482 case IEEE80211_RADIOTAP_RATE:
1483 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1484 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1485 case IEEE80211_RADIOTAP_ANTENNA:
1486 rc = cpack_uint8(s, &u.u8);
1487 break;
1488 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1489 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1490 rc = cpack_int8(s, &u.i8);
1491 break;
1492 case IEEE80211_RADIOTAP_CHANNEL:
1493 rc = cpack_uint16(s, &u.u16);
1494 if (rc != 0)
1495 break;
1496 rc = cpack_uint16(s, &u2.u16);
1497 break;
1498 case IEEE80211_RADIOTAP_FHSS:
1499 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1500 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1501 rc = cpack_uint16(s, &u.u16);
1502 break;
1503 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1504 rc = cpack_uint8(s, &u.u8);
1505 break;
1506 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1507 rc = cpack_int8(s, &u.i8);
1508 break;
1509 case IEEE80211_RADIOTAP_TSFT:
1510 rc = cpack_uint64(s, &u.u64);
1511 break;
1512 case IEEE80211_RADIOTAP_XCHANNEL:
1513 rc = cpack_uint32(s, &u.u32);
1514 if (rc != 0)
1515 break;
1516 rc = cpack_uint16(s, &u2.u16);
1517 if (rc != 0)
1518 break;
1519 rc = cpack_uint8(s, &u3.u8);
1520 if (rc != 0)
1521 break;
1522 rc = cpack_uint8(s, &u4.u8);
1523 break;
1524 default:
1525 /* this bit indicates a field whose
1526 * size we do not know, so we cannot
1527 * proceed. Just print the bit number.
1528 */
1529 printf("[bit %u] ", bit);
1530 return -1;
1531 }
1532
1533 if (rc != 0) {
1534 printf("[|802.11]");
1535 return rc;
1536 }
1537
1538 switch (bit) {
1539 case IEEE80211_RADIOTAP_CHANNEL:
1540 print_chaninfo(u.u16, u2.u16);
1541 break;
1542 case IEEE80211_RADIOTAP_FHSS:
1543 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1544 break;
1545 case IEEE80211_RADIOTAP_RATE:
1546 if (u.u8 & 0x80)
1547 PRINT_HT_RATE("", u.u8, " Mb/s ");
1548 else
1549 PRINT_RATE("", u.u8, " Mb/s ");
1550 break;
1551 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1552 printf("%ddB signal ", u.i8);
1553 break;
1554 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1555 printf("%ddB noise ", u.i8);
1556 break;
1557 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1558 printf("%ddB signal ", u.u8);
1559 break;
1560 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1561 printf("%ddB noise ", u.u8);
1562 break;
1563 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1564 printf("%u sq ", u.u16);
1565 break;
1566 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1567 printf("%d tx power ", -(int)u.u16);
1568 break;
1569 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1570 printf("%ddB tx power ", -(int)u.u8);
1571 break;
1572 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1573 printf("%ddBm tx power ", u.i8);
1574 break;
1575 case IEEE80211_RADIOTAP_FLAGS:
1576 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1577 printf("cfp ");
1578 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1579 printf("short preamble ");
1580 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1581 printf("wep ");
1582 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1583 printf("fragmented ");
1584 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1585 printf("bad-fcs ");
1586 break;
1587 case IEEE80211_RADIOTAP_ANTENNA:
1588 printf("antenna %d ", u.u8);
1589 break;
1590 case IEEE80211_RADIOTAP_TSFT:
1591 printf("%" PRIu64 "us tsft ", u.u64);
1592 break;
1593 case IEEE80211_RADIOTAP_XCHANNEL:
1594 print_chaninfo(u2.u16, u.u32);
1595 break;
1596 }
1597 return 0;
1598 }
1599
1600 static u_int
1601 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1602 {
1603 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1604 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1605 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1606 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1607 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1608 #define BIT(n) (1U << n)
1609 #define IS_EXTENDED(__p) \
1610 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1611
1612 struct cpack_state cpacker;
1613 struct ieee80211_radiotap_header *hdr;
1614 u_int32_t present, next_present;
1615 u_int32_t *presentp, *last_presentp;
1616 enum ieee80211_radiotap_type bit;
1617 int bit0;
1618 const u_char *iter;
1619 u_int len;
1620 u_int8_t flags;
1621 int pad;
1622 u_int fcslen;
1623
1624 if (caplen < sizeof(*hdr)) {
1625 printf("[|802.11]");
1626 return caplen;
1627 }
1628
1629 hdr = (struct ieee80211_radiotap_header *)p;
1630
1631 len = EXTRACT_LE_16BITS(&hdr->it_len);
1632
1633 if (caplen < len) {
1634 printf("[|802.11]");
1635 return caplen;
1636 }
1637 for (last_presentp = &hdr->it_present;
1638 IS_EXTENDED(last_presentp) &&
1639 (u_char*)(last_presentp + 1) <= p + len;
1640 last_presentp++);
1641
1642 /* are there more bitmap extensions than bytes in header? */
1643 if (IS_EXTENDED(last_presentp)) {
1644 printf("[|802.11]");
1645 return caplen;
1646 }
1647
1648 iter = (u_char*)(last_presentp + 1);
1649
1650 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1651 /* XXX */
1652 printf("[|802.11]");
1653 return caplen;
1654 }
1655
1656 /* Assume no flags */
1657 flags = 0;
1658 /* Assume no Atheros padding between 802.11 header and body */
1659 pad = 0;
1660 /* Assume no FCS at end of frame */
1661 fcslen = 0;
1662 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1663 presentp++, bit0 += 32) {
1664 for (present = EXTRACT_LE_32BITS(presentp); present;
1665 present = next_present) {
1666 /* clear the least significant bit that is set */
1667 next_present = present & (present - 1);
1668
1669 /* extract the least significant bit that is set */
1670 bit = (enum ieee80211_radiotap_type)
1671 (bit0 + BITNO_32(present ^ next_present));
1672
1673 if (print_radiotap_field(&cpacker, bit, &flags) != 0)
1674 goto out;
1675 }
1676 }
1677
1678 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
1679 pad = 1; /* Atheros padding */
1680 if (flags & IEEE80211_RADIOTAP_F_FCS)
1681 fcslen = 4; /* FCS at end of packet */
1682 out:
1683 return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
1684 fcslen);
1685 #undef BITNO_32
1686 #undef BITNO_16
1687 #undef BITNO_8
1688 #undef BITNO_4
1689 #undef BITNO_2
1690 #undef BIT
1691 }
1692
1693 static u_int
1694 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1695 {
1696 u_int32_t caphdr_len;
1697
1698 if (caplen < 8) {
1699 printf("[|802.11]");
1700 return caplen;
1701 }
1702
1703 caphdr_len = EXTRACT_32BITS(p + 4);
1704 if (caphdr_len < 8) {
1705 /*
1706 * Yow! The capture header length is claimed not
1707 * to be large enough to include even the version
1708 * cookie or capture header length!
1709 */
1710 printf("[|802.11]");
1711 return caplen;
1712 }
1713
1714 if (caplen < caphdr_len) {
1715 printf("[|802.11]");
1716 return caplen;
1717 }
1718
1719 return caphdr_len + ieee802_11_print(p + caphdr_len,
1720 length - caphdr_len, caplen - caphdr_len, 0, 0);
1721 }
1722
1723 #define PRISM_HDR_LEN 144
1724
1725 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1726 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1727 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
1728
1729 /*
1730 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1731 * containing information such as radio information, which we
1732 * currently ignore.
1733 *
1734 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1735 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1736 * (currently, on Linux, there's no ARPHRD_ type for
1737 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1738 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1739 * the AVS header, and the first 4 bytes of the header are used to
1740 * indicate whether it's a Prism header or an AVS header).
1741 */
1742 u_int
1743 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1744 {
1745 u_int caplen = h->caplen;
1746 u_int length = h->len;
1747 u_int32_t msgcode;
1748
1749 if (caplen < 4) {
1750 printf("[|802.11]");
1751 return caplen;
1752 }
1753
1754 msgcode = EXTRACT_32BITS(p);
1755 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
1756 msgcode == WLANCAP_MAGIC_COOKIE_V2)
1757 return ieee802_11_avs_radio_print(p, length, caplen);
1758
1759 if (caplen < PRISM_HDR_LEN) {
1760 printf("[|802.11]");
1761 return caplen;
1762 }
1763
1764 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1765 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
1766 }
1767
1768 /*
1769 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1770 * header, containing information such as radio information.
1771 */
1772 u_int
1773 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1774 {
1775 return ieee802_11_radio_print(p, h->len, h->caplen);
1776 }
1777
1778 /*
1779 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1780 * extra header, containing information such as radio information,
1781 * which we currently ignore.
1782 */
1783 u_int
1784 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
1785 {
1786 return ieee802_11_avs_radio_print(p, h->len, h->caplen);
1787 }