]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
updated print-ipnet.c to use netdissect options structure
[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 (FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
1325 meshdrlen = extract_mesh_header_length(p+hdrlen);
1326 hdrlen += meshdrlen;
1327 } else
1328 meshdrlen = 0;
1329
1330
1331 if (caplen < hdrlen) {
1332 printf("[|802.11]");
1333 return hdrlen;
1334 }
1335
1336 ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
1337
1338 /*
1339 * Go past the 802.11 header.
1340 */
1341 length -= hdrlen;
1342 caplen -= hdrlen;
1343 p += hdrlen;
1344
1345 switch (FC_TYPE(fc)) {
1346 case T_MGMT:
1347 if (!mgmt_body_print(fc,
1348 (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
1349 printf("[|802.11]");
1350 return hdrlen;
1351 }
1352 break;
1353 case T_CTRL:
1354 if (!ctrl_body_print(fc, p - hdrlen)) {
1355 printf("[|802.11]");
1356 return hdrlen;
1357 }
1358 break;
1359 case T_DATA:
1360 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
1361 return hdrlen; /* no-data frame */
1362 /* There may be a problem w/ AP not having this bit set */
1363 if (FC_WEP(fc)) {
1364 if (!wep_print(p)) {
1365 printf("[|802.11]");
1366 return hdrlen;
1367 }
1368 } else if (llc_print(p, length, caplen, dst, src,
1369 &extracted_ethertype) == 0) {
1370 /*
1371 * Some kinds of LLC packet we cannot
1372 * handle intelligently
1373 */
1374 if (!eflag)
1375 ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
1376 meshdrlen, NULL, NULL);
1377 if (extracted_ethertype)
1378 printf("(LLC %s) ",
1379 etherproto_string(
1380 htons(extracted_ethertype)));
1381 if (!suppress_default_print)
1382 default_print(p, caplen);
1383 }
1384 break;
1385 default:
1386 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
1387 break;
1388 }
1389
1390 return hdrlen;
1391 }
1392
1393 /*
1394 * This is the top level routine of the printer. 'p' points
1395 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
1396 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1397 * is the number of bytes actually captured.
1398 */
1399 u_int
1400 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
1401 {
1402 return ieee802_11_print(p, h->len, h->caplen, 0, 0);
1403 }
1404
1405 #define IEEE80211_CHAN_FHSS \
1406 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
1407 #define IEEE80211_CHAN_A \
1408 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
1409 #define IEEE80211_CHAN_B \
1410 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
1411 #define IEEE80211_CHAN_PUREG \
1412 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
1413 #define IEEE80211_CHAN_G \
1414 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
1415
1416 #define IS_CHAN_FHSS(flags) \
1417 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
1418 #define IS_CHAN_A(flags) \
1419 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
1420 #define IS_CHAN_B(flags) \
1421 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
1422 #define IS_CHAN_PUREG(flags) \
1423 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
1424 #define IS_CHAN_G(flags) \
1425 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
1426 #define IS_CHAN_ANYG(flags) \
1427 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
1428
1429 static void
1430 print_chaninfo(int freq, int flags)
1431 {
1432 printf("%u MHz", freq);
1433 if (IS_CHAN_FHSS(flags))
1434 printf(" FHSS");
1435 if (IS_CHAN_A(flags)) {
1436 if (flags & IEEE80211_CHAN_HALF)
1437 printf(" 11a/10Mhz");
1438 else if (flags & IEEE80211_CHAN_QUARTER)
1439 printf(" 11a/5Mhz");
1440 else
1441 printf(" 11a");
1442 }
1443 if (IS_CHAN_ANYG(flags)) {
1444 if (flags & IEEE80211_CHAN_HALF)
1445 printf(" 11g/10Mhz");
1446 else if (flags & IEEE80211_CHAN_QUARTER)
1447 printf(" 11g/5Mhz");
1448 else
1449 printf(" 11g");
1450 } else if (IS_CHAN_B(flags))
1451 printf(" 11b");
1452 if (flags & IEEE80211_CHAN_TURBO)
1453 printf(" Turbo");
1454 if (flags & IEEE80211_CHAN_HT20)
1455 printf(" ht/20");
1456 else if (flags & IEEE80211_CHAN_HT40D)
1457 printf(" ht/40-");
1458 else if (flags & IEEE80211_CHAN_HT40U)
1459 printf(" ht/40+");
1460 printf(" ");
1461 }
1462
1463 static int
1464 print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags)
1465 {
1466 union {
1467 int8_t i8;
1468 u_int8_t u8;
1469 int16_t i16;
1470 u_int16_t u16;
1471 u_int32_t u32;
1472 u_int64_t u64;
1473 } u, u2, u3, u4;
1474 int rc;
1475
1476 switch (bit) {
1477 case IEEE80211_RADIOTAP_FLAGS:
1478 rc = cpack_uint8(s, &u.u8);
1479 *flags = u.u8;
1480 break;
1481 case IEEE80211_RADIOTAP_RATE:
1482 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1483 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1484 case IEEE80211_RADIOTAP_ANTENNA:
1485 rc = cpack_uint8(s, &u.u8);
1486 break;
1487 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1488 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1489 rc = cpack_int8(s, &u.i8);
1490 break;
1491 case IEEE80211_RADIOTAP_CHANNEL:
1492 rc = cpack_uint16(s, &u.u16);
1493 if (rc != 0)
1494 break;
1495 rc = cpack_uint16(s, &u2.u16);
1496 break;
1497 case IEEE80211_RADIOTAP_FHSS:
1498 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1499 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1500 rc = cpack_uint16(s, &u.u16);
1501 break;
1502 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1503 rc = cpack_uint8(s, &u.u8);
1504 break;
1505 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1506 rc = cpack_int8(s, &u.i8);
1507 break;
1508 case IEEE80211_RADIOTAP_TSFT:
1509 rc = cpack_uint64(s, &u.u64);
1510 break;
1511 case IEEE80211_RADIOTAP_XCHANNEL:
1512 rc = cpack_uint32(s, &u.u32);
1513 if (rc != 0)
1514 break;
1515 rc = cpack_uint16(s, &u2.u16);
1516 if (rc != 0)
1517 break;
1518 rc = cpack_uint8(s, &u3.u8);
1519 if (rc != 0)
1520 break;
1521 rc = cpack_uint8(s, &u4.u8);
1522 break;
1523 default:
1524 /* this bit indicates a field whose
1525 * size we do not know, so we cannot
1526 * proceed.
1527 */
1528 printf("[0x%08x] ", bit);
1529 return -1;
1530 }
1531
1532 if (rc != 0) {
1533 printf("[|802.11]");
1534 return rc;
1535 }
1536
1537 switch (bit) {
1538 case IEEE80211_RADIOTAP_CHANNEL:
1539 print_chaninfo(u.u16, u2.u16);
1540 break;
1541 case IEEE80211_RADIOTAP_FHSS:
1542 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1543 break;
1544 case IEEE80211_RADIOTAP_RATE:
1545 if (u.u8 & 0x80)
1546 PRINT_HT_RATE("", u.u8, " Mb/s ");
1547 else
1548 PRINT_RATE("", u.u8, " Mb/s ");
1549 break;
1550 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1551 printf("%ddB signal ", u.i8);
1552 break;
1553 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1554 printf("%ddB noise ", u.i8);
1555 break;
1556 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1557 printf("%ddB signal ", u.u8);
1558 break;
1559 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1560 printf("%ddB noise ", u.u8);
1561 break;
1562 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1563 printf("%u sq ", u.u16);
1564 break;
1565 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1566 printf("%d tx power ", -(int)u.u16);
1567 break;
1568 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1569 printf("%ddB tx power ", -(int)u.u8);
1570 break;
1571 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1572 printf("%ddBm tx power ", u.i8);
1573 break;
1574 case IEEE80211_RADIOTAP_FLAGS:
1575 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1576 printf("cfp ");
1577 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1578 printf("short preamble ");
1579 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1580 printf("wep ");
1581 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1582 printf("fragmented ");
1583 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1584 printf("bad-fcs ");
1585 break;
1586 case IEEE80211_RADIOTAP_ANTENNA:
1587 printf("antenna %d ", u.u8);
1588 break;
1589 case IEEE80211_RADIOTAP_TSFT:
1590 printf("%" PRIu64 "us tsft ", u.u64);
1591 break;
1592 case IEEE80211_RADIOTAP_XCHANNEL:
1593 print_chaninfo(u2.u16, u.u32);
1594 break;
1595 }
1596 return 0;
1597 }
1598
1599 static u_int
1600 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1601 {
1602 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1603 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1604 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1605 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1606 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1607 #define BIT(n) (1U << n)
1608 #define IS_EXTENDED(__p) \
1609 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1610
1611 struct cpack_state cpacker;
1612 struct ieee80211_radiotap_header *hdr;
1613 u_int32_t present, next_present;
1614 u_int32_t *presentp, *last_presentp;
1615 enum ieee80211_radiotap_type bit;
1616 int bit0;
1617 const u_char *iter;
1618 u_int len;
1619 u_int8_t flags;
1620 int pad;
1621 u_int fcslen;
1622
1623 if (caplen < sizeof(*hdr)) {
1624 printf("[|802.11]");
1625 return caplen;
1626 }
1627
1628 hdr = (struct ieee80211_radiotap_header *)p;
1629
1630 len = EXTRACT_LE_16BITS(&hdr->it_len);
1631
1632 if (caplen < len) {
1633 printf("[|802.11]");
1634 return caplen;
1635 }
1636 for (last_presentp = &hdr->it_present;
1637 IS_EXTENDED(last_presentp) &&
1638 (u_char*)(last_presentp + 1) <= p + len;
1639 last_presentp++);
1640
1641 /* are there more bitmap extensions than bytes in header? */
1642 if (IS_EXTENDED(last_presentp)) {
1643 printf("[|802.11]");
1644 return caplen;
1645 }
1646
1647 iter = (u_char*)(last_presentp + 1);
1648
1649 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1650 /* XXX */
1651 printf("[|802.11]");
1652 return caplen;
1653 }
1654
1655 /* Assume no flags */
1656 flags = 0;
1657 /* Assume no Atheros padding between 802.11 header and body */
1658 pad = 0;
1659 /* Assume no FCS at end of frame */
1660 fcslen = 0;
1661 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1662 presentp++, bit0 += 32) {
1663 for (present = EXTRACT_LE_32BITS(presentp); present;
1664 present = next_present) {
1665 /* clear the least significant bit that is set */
1666 next_present = present & (present - 1);
1667
1668 /* extract the least significant bit that is set */
1669 bit = (enum ieee80211_radiotap_type)
1670 (bit0 + BITNO_32(present ^ next_present));
1671
1672 if (print_radiotap_field(&cpacker, bit, &flags) != 0)
1673 goto out;
1674 }
1675 }
1676
1677 if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
1678 pad = 1; /* Atheros padding */
1679 if (flags & IEEE80211_RADIOTAP_F_FCS)
1680 fcslen = 4; /* FCS at end of packet */
1681 out:
1682 return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
1683 fcslen);
1684 #undef BITNO_32
1685 #undef BITNO_16
1686 #undef BITNO_8
1687 #undef BITNO_4
1688 #undef BITNO_2
1689 #undef BIT
1690 }
1691
1692 static u_int
1693 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1694 {
1695 u_int32_t caphdr_len;
1696
1697 if (caplen < 8) {
1698 printf("[|802.11]");
1699 return caplen;
1700 }
1701
1702 caphdr_len = EXTRACT_32BITS(p + 4);
1703 if (caphdr_len < 8) {
1704 /*
1705 * Yow! The capture header length is claimed not
1706 * to be large enough to include even the version
1707 * cookie or capture header length!
1708 */
1709 printf("[|802.11]");
1710 return caplen;
1711 }
1712
1713 if (caplen < caphdr_len) {
1714 printf("[|802.11]");
1715 return caplen;
1716 }
1717
1718 return caphdr_len + ieee802_11_print(p + caphdr_len,
1719 length - caphdr_len, caplen - caphdr_len, 0, 0);
1720 }
1721
1722 #define PRISM_HDR_LEN 144
1723
1724 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
1725 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1726 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002
1727
1728 /*
1729 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1730 * containing information such as radio information, which we
1731 * currently ignore.
1732 *
1733 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
1734 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
1735 * (currently, on Linux, there's no ARPHRD_ type for
1736 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
1737 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
1738 * the AVS header, and the first 4 bytes of the header are used to
1739 * indicate whether it's a Prism header or an AVS header).
1740 */
1741 u_int
1742 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1743 {
1744 u_int caplen = h->caplen;
1745 u_int length = h->len;
1746 u_int32_t msgcode;
1747
1748 if (caplen < 4) {
1749 printf("[|802.11]");
1750 return caplen;
1751 }
1752
1753 msgcode = EXTRACT_32BITS(p);
1754 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
1755 msgcode == WLANCAP_MAGIC_COOKIE_V2)
1756 return ieee802_11_avs_radio_print(p, length, caplen);
1757
1758 if (caplen < PRISM_HDR_LEN) {
1759 printf("[|802.11]");
1760 return caplen;
1761 }
1762
1763 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1764 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
1765 }
1766
1767 /*
1768 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1769 * header, containing information such as radio information.
1770 */
1771 u_int
1772 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1773 {
1774 return ieee802_11_radio_print(p, h->len, h->caplen);
1775 }
1776
1777 /*
1778 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
1779 * extra header, containing information such as radio information,
1780 * which we currently ignore.
1781 */
1782 u_int
1783 ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
1784 {
1785 return ieee802_11_avs_radio_print(p, h->len, h->caplen);
1786 }