]> The Tcpdump Group git mirrors - tcpdump/blob - print-802_11.c
We already print "Unhandled Management subtype(N)" for management frames
[tcpdump] / print-802_11.c
1 /*
2 * Copyright (c) 2001
3 * Fortress Technologies, Inc. All rights reserved.
4 * Charlie Lenahan (clenahan@fortresstech.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23 #ifndef lint
24 static const char rcsid[] _U_ =
25 "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.31.2.4 2005-07-30 18:49:29 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_RATE(_sep, _r, _suf) \
50 printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
51 #define PRINT_RATES(p) \
52 do { \
53 int z; \
54 const char *sep = " ["; \
55 for (z = 0; z < p.rates.length ; z++) { \
56 PRINT_RATE(sep, p.rates.rate[z], \
57 (p.rates.rate[z] & 0x80 ? "*" : "")); \
58 sep = " "; \
59 } \
60 if (p.rates.length != 0) \
61 printf(" Mbit]"); \
62 } while (0)
63
64 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
65 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
66
67 static const char *subtype_text[16]={
68 "Assoc Request",
69 "Assoc Response",
70 "ReAssoc Request",
71 "ReAssoc Response",
72 "Probe Request",
73 "Probe Response",
74 "",
75 "",
76 "Beacon",
77 "ATIM",
78 "Disassociation",
79 "Authentication",
80 "DeAuthentication",
81 "",
82 "",
83 ""
84 };
85
86 static const char *status_text[] = {
87 "Succesful", /* 0 */
88 "Unspecified failure", /* 1 */
89 "Reserved", /* 2 */
90 "Reserved", /* 3 */
91 "Reserved", /* 4 */
92 "Reserved", /* 5 */
93 "Reserved", /* 6 */
94 "Reserved", /* 7 */
95 "Reserved", /* 8 */
96 "Reserved", /* 9 */
97 "Cannot Support all requested capabilities in the Capability Information field", /* 10 */
98 "Reassociation denied due to inability to confirm that association exists", /* 11 */
99 "Association denied due to reason outside the scope of the standard", /* 12 */
100 "Responding station does not support the specified authentication algorithm ", /* 13 */
101 "Received an Authentication frame with authentication transaction " \
102 "sequence number out of expected sequence", /* 14 */
103 "Authentication rejected because of challenge failure", /* 15 */
104 "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */
105 "Association denied because AP is unable to handle additional associated stations", /* 17 */
106 "Association denied due to requesting station not supporting all of the " \
107 "data rates in BSSBasicRateSet parameter", /* 18 */
108 };
109 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
110
111 static const char *reason_text[] = {
112 "Reserved", /* 0 */
113 "Unspecified reason", /* 1 */
114 "Previous authentication no longer valid", /* 2 */
115 "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
116 "Disassociated due to inactivity", /* 4 */
117 "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
118 "Class 2 frame received from nonauthenticated station", /* 6 */
119 "Class 3 frame received from nonassociated station", /* 7 */
120 "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
121 "Station requesting (re)association is not authenticated with responding station", /* 9 */
122 };
123 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
124
125 static int
126 wep_print(const u_char *p)
127 {
128 u_int32_t iv;
129
130 if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
131 return 0;
132 iv = EXTRACT_LE_32BITS(p);
133
134 printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
135 IV_KEYID(iv));
136
137 return 1;
138 }
139
140 static int
141 parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset)
142 {
143 for (;;) {
144 if (!TTEST2(*(p + offset), 1))
145 return 1;
146 switch (*(p + offset)) {
147 case E_SSID:
148 if (!TTEST2(*(p + offset), 2))
149 return 0;
150 memcpy(&pbody->ssid, p + offset, 2);
151 offset += 2;
152 if (pbody->ssid.length <= 0)
153 break;
154 if (!TTEST2(*(p + offset), pbody->ssid.length))
155 return 0;
156 memcpy(&pbody->ssid.ssid, p + offset,
157 pbody->ssid.length);
158 offset += pbody->ssid.length;
159 pbody->ssid.ssid[pbody->ssid.length] = '\0';
160 break;
161 case E_CHALLENGE:
162 if (!TTEST2(*(p + offset), 2))
163 return 0;
164 memcpy(&pbody->challenge, p + offset, 2);
165 offset += 2;
166 if (pbody->challenge.length <= 0)
167 break;
168 if (!TTEST2(*(p + offset), pbody->challenge.length))
169 return 0;
170 memcpy(&pbody->challenge.text, p + offset,
171 pbody->challenge.length);
172 offset += pbody->challenge.length;
173 pbody->challenge.text[pbody->challenge.length] = '\0';
174 break;
175 case E_RATES:
176 if (!TTEST2(*(p + offset), 2))
177 return 0;
178 memcpy(&(pbody->rates), p + offset, 2);
179 offset += 2;
180 if (pbody->rates.length <= 0)
181 break;
182 if (!TTEST2(*(p + offset), pbody->rates.length))
183 return 0;
184 memcpy(&pbody->rates.rate, p + offset,
185 pbody->rates.length);
186 offset += pbody->rates.length;
187 break;
188 case E_DS:
189 if (!TTEST2(*(p + offset), 3))
190 return 0;
191 memcpy(&pbody->ds, p + offset, 3);
192 offset += 3;
193 break;
194 case E_CF:
195 if (!TTEST2(*(p + offset), 8))
196 return 0;
197 memcpy(&pbody->cf, p + offset, 8);
198 offset += 8;
199 break;
200 case E_TIM:
201 if (!TTEST2(*(p + offset), 2))
202 return 0;
203 memcpy(&pbody->tim, p + offset, 2);
204 offset += 2;
205 if (!TTEST2(*(p + offset), 3))
206 return 0;
207 memcpy(&pbody->tim.count, p + offset, 3);
208 offset += 3;
209
210 if (pbody->tim.length <= 3)
211 break;
212 if (!TTEST2(*(p + offset), pbody->tim.length - 3))
213 return 0;
214 memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),
215 (pbody->tim.length - 3));
216 offset += pbody->tim.length - 3;
217 break;
218 default:
219 #if 0
220 printf("(1) unhandled element_id (%d) ",
221 *(p + offset) );
222 #endif
223 offset += *(p + offset + 1) + 2;
224 break;
225 }
226 }
227 return 1;
228 }
229
230 /*********************************************************************************
231 * Print Handle functions for the management frame types
232 *********************************************************************************/
233
234 static int
235 handle_beacon(const u_char *p)
236 {
237 struct mgmt_body_t pbody;
238 int offset = 0;
239
240 memset(&pbody, 0, sizeof(pbody));
241
242 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
243 IEEE802_11_CAPINFO_LEN))
244 return 0;
245 memcpy(&pbody.timestamp, p, 8);
246 offset += IEEE802_11_TSTAMP_LEN;
247 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
248 offset += IEEE802_11_BCNINT_LEN;
249 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
250 offset += IEEE802_11_CAPINFO_LEN;
251
252 if (!parse_elements(&pbody, p, offset))
253 return 0;
254
255 printf(" (");
256 fn_print(pbody.ssid.ssid, NULL);
257 printf(")");
258 PRINT_RATES(pbody);
259 printf(" %s CH: %u%s",
260 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS",
261 pbody.ds.channel,
262 CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );
263
264 return 1;
265 }
266
267 static int
268 handle_assoc_request(const u_char *p)
269 {
270 struct mgmt_body_t pbody;
271 int offset = 0;
272
273 memset(&pbody, 0, sizeof(pbody));
274
275 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
276 return 0;
277 pbody.capability_info = EXTRACT_LE_16BITS(p);
278 offset += IEEE802_11_CAPINFO_LEN;
279 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
280 offset += IEEE802_11_LISTENINT_LEN;
281
282 if (!parse_elements(&pbody, p, offset))
283 return 0;
284
285 printf(" (");
286 fn_print(pbody.ssid.ssid, NULL);
287 printf(")");
288 PRINT_RATES(pbody);
289 return 1;
290 }
291
292 static int
293 handle_assoc_response(const u_char *p)
294 {
295 struct mgmt_body_t pbody;
296 int offset = 0;
297
298 memset(&pbody, 0, sizeof(pbody));
299
300 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
301 IEEE802_11_AID_LEN))
302 return 0;
303 pbody.capability_info = EXTRACT_LE_16BITS(p);
304 offset += IEEE802_11_CAPINFO_LEN;
305 pbody.status_code = EXTRACT_LE_16BITS(p+offset);
306 offset += IEEE802_11_STATUS_LEN;
307 pbody.aid = EXTRACT_LE_16BITS(p+offset);
308 offset += IEEE802_11_AID_LEN;
309
310 if (!parse_elements(&pbody, p, offset))
311 return 0;
312
313 printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
314 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
315 (pbody.status_code < NUM_STATUSES
316 ? status_text[pbody.status_code]
317 : "n/a"));
318
319 return 1;
320 }
321
322 static int
323 handle_reassoc_request(const u_char *p)
324 {
325 struct mgmt_body_t pbody;
326 int offset = 0;
327
328 memset(&pbody, 0, sizeof(pbody));
329
330 if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
331 IEEE802_11_AP_LEN))
332 return 0;
333 pbody.capability_info = EXTRACT_LE_16BITS(p);
334 offset += IEEE802_11_CAPINFO_LEN;
335 pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
336 offset += IEEE802_11_LISTENINT_LEN;
337 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
338 offset += IEEE802_11_AP_LEN;
339
340 if (!parse_elements(&pbody, p, offset))
341 return 0;
342
343 printf(" (");
344 fn_print(pbody.ssid.ssid, NULL);
345 printf(") AP : %s", etheraddr_string( pbody.ap ));
346
347 return 1;
348 }
349
350 static int
351 handle_reassoc_response(const u_char *p)
352 {
353 /* Same as a Association Reponse */
354 return handle_assoc_response(p);
355 }
356
357 static int
358 handle_probe_request(const u_char *p)
359 {
360 struct mgmt_body_t pbody;
361 int offset = 0;
362
363 memset(&pbody, 0, sizeof(pbody));
364
365 if (!parse_elements(&pbody, p, offset))
366 return 0;
367
368 printf(" (");
369 fn_print(pbody.ssid.ssid, NULL);
370 printf(")");
371 PRINT_RATES(pbody);
372
373 return 1;
374 }
375
376 static int
377 handle_probe_response(const u_char *p)
378 {
379 struct mgmt_body_t pbody;
380 int offset = 0;
381
382 memset(&pbody, 0, sizeof(pbody));
383
384 if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
385 IEEE802_11_CAPINFO_LEN))
386 return 0;
387
388 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
389 offset += IEEE802_11_TSTAMP_LEN;
390 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
391 offset += IEEE802_11_BCNINT_LEN;
392 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
393 offset += IEEE802_11_CAPINFO_LEN;
394
395 if (!parse_elements(&pbody, p, offset))
396 return 0;
397
398 printf(" (");
399 fn_print(pbody.ssid.ssid, NULL);
400 printf(") ");
401 PRINT_RATES(pbody);
402 printf(" CH: %u%s", pbody.ds.channel,
403 CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );
404
405 return 1;
406 }
407
408 static int
409 handle_atim(void)
410 {
411 /* the frame body for ATIM is null. */
412 return 1;
413 }
414
415 static int
416 handle_disassoc(const u_char *p)
417 {
418 struct mgmt_body_t pbody;
419
420 memset(&pbody, 0, sizeof(pbody));
421
422 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
423 return 0;
424 pbody.reason_code = EXTRACT_LE_16BITS(p);
425
426 printf(": %s",
427 (pbody.reason_code < NUM_REASONS)
428 ? reason_text[pbody.reason_code]
429 : "Reserved" );
430
431 return 1;
432 }
433
434 static int
435 handle_auth(const u_char *p)
436 {
437 struct mgmt_body_t pbody;
438 int offset = 0;
439
440 memset(&pbody, 0, sizeof(pbody));
441
442 if (!TTEST2(*p, 6))
443 return 0;
444 pbody.auth_alg = EXTRACT_LE_16BITS(p);
445 offset += 2;
446 pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
447 offset += 2;
448 pbody.status_code = EXTRACT_LE_16BITS(p + offset);
449 offset += 2;
450
451 if (!parse_elements(&pbody, p, offset))
452 return 0;
453
454 if ((pbody.auth_alg == 1) &&
455 ((pbody.auth_trans_seq_num == 2) ||
456 (pbody.auth_trans_seq_num == 3))) {
457 printf(" (%s)-%x [Challenge Text] %s",
458 (pbody.auth_alg < NUM_AUTH_ALGS)
459 ? auth_alg_text[pbody.auth_alg]
460 : "Reserved",
461 pbody.auth_trans_seq_num,
462 ((pbody.auth_trans_seq_num % 2)
463 ? ((pbody.status_code < NUM_STATUSES)
464 ? status_text[pbody.status_code]
465 : "n/a") : ""));
466 return 1;
467 }
468 printf(" (%s)-%x: %s",
469 (pbody.auth_alg < NUM_AUTH_ALGS)
470 ? auth_alg_text[pbody.auth_alg]
471 : "Reserved",
472 pbody.auth_trans_seq_num,
473 (pbody.auth_trans_seq_num % 2)
474 ? ((pbody.status_code < NUM_STATUSES)
475 ? status_text[pbody.status_code]
476 : "n/a")
477 : "");
478
479 return 1;
480 }
481
482 static int
483 handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
484 {
485 struct mgmt_body_t pbody;
486 int offset = 0;
487 const char *reason = NULL;
488
489 memset(&pbody, 0, sizeof(pbody));
490
491 if (!TTEST2(*p, IEEE802_11_REASON_LEN))
492 return 0;
493 pbody.reason_code = EXTRACT_LE_16BITS(p);
494 offset += IEEE802_11_REASON_LEN;
495
496 reason = (pbody.reason_code < NUM_REASONS)
497 ? reason_text[pbody.reason_code]
498 : "Reserved";
499
500 if (eflag) {
501 printf(": %s", reason);
502 } else {
503 printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
504 }
505 return 1;
506 }
507
508
509 /*********************************************************************************
510 * Print Body funcs
511 *********************************************************************************/
512
513
514 static int
515 mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
516 const u_char *p)
517 {
518 printf("%s", subtype_text[FC_SUBTYPE(fc)]);
519
520 switch (FC_SUBTYPE(fc)) {
521 case ST_ASSOC_REQUEST:
522 return handle_assoc_request(p);
523 case ST_ASSOC_RESPONSE:
524 return handle_assoc_response(p);
525 case ST_REASSOC_REQUEST:
526 return handle_reassoc_request(p);
527 case ST_REASSOC_RESPONSE:
528 return handle_reassoc_response(p);
529 case ST_PROBE_REQUEST:
530 return handle_probe_request(p);
531 case ST_PROBE_RESPONSE:
532 return handle_probe_response(p);
533 case ST_BEACON:
534 return handle_beacon(p);
535 case ST_ATIM:
536 return handle_atim();
537 case ST_DISASSOC:
538 return handle_disassoc(p);
539 case ST_AUTH:
540 if (!TTEST2(*p, 3))
541 return 0;
542 if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
543 printf("Authentication (Shared-Key)-3 ");
544 return wep_print(p);
545 }
546 return handle_auth(p);
547 case ST_DEAUTH:
548 return handle_deauth(pmh, p);
549 break;
550 default:
551 printf("Unhandled Management subtype(%x)",
552 FC_SUBTYPE(fc));
553 return 1;
554 }
555 }
556
557
558 /*********************************************************************************
559 * Handles printing all the control frame types
560 *********************************************************************************/
561
562 static int
563 ctrl_body_print(u_int16_t fc, const u_char *p)
564 {
565 switch (FC_SUBTYPE(fc)) {
566 case CTRL_PS_POLL:
567 printf("Power Save-Poll");
568 if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
569 return 0;
570 printf(" AID(%x)",
571 EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
572 break;
573 case CTRL_RTS:
574 printf("Request-To-Send");
575 if (!TTEST2(*p, CTRL_RTS_HDRLEN))
576 return 0;
577 if (!eflag)
578 printf(" TA:%s ",
579 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
580 break;
581 case CTRL_CTS:
582 printf("Clear-To-Send");
583 if (!TTEST2(*p, CTRL_CTS_HDRLEN))
584 return 0;
585 if (!eflag)
586 printf(" RA:%s ",
587 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
588 break;
589 case CTRL_ACK:
590 printf("Acknowledgment");
591 if (!TTEST2(*p, CTRL_ACK_HDRLEN))
592 return 0;
593 if (!eflag)
594 printf(" RA:%s ",
595 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
596 break;
597 case CTRL_CF_END:
598 printf("CF-End");
599 if (!TTEST2(*p, CTRL_END_HDRLEN))
600 return 0;
601 if (!eflag)
602 printf(" RA:%s ",
603 etheraddr_string(((const struct ctrl_end_t *)p)->ra));
604 break;
605 case CTRL_END_ACK:
606 printf("CF-End+CF-Ack");
607 if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
608 return 0;
609 if (!eflag)
610 printf(" RA:%s ",
611 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
612 break;
613 default:
614 printf("Unknown Ctrl Subtype");
615 }
616 return 1;
617 }
618
619 /*
620 * Print Header funcs
621 */
622
623 /*
624 * Data Frame - Address field contents
625 *
626 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
627 * 0 | 0 | DA | SA | BSSID | n/a
628 * 0 | 1 | DA | BSSID | SA | n/a
629 * 1 | 0 | BSSID | SA | DA | n/a
630 * 1 | 1 | RA | TA | DA | SA
631 */
632
633 static void
634 data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
635 const u_int8_t **dstp)
636 {
637 switch (FC_SUBTYPE(fc)) {
638 case DATA_DATA:
639 case DATA_NODATA:
640 break;
641 case DATA_DATA_CF_ACK:
642 case DATA_NODATA_CF_ACK:
643 printf("CF Ack ");
644 break;
645 case DATA_DATA_CF_POLL:
646 case DATA_NODATA_CF_POLL:
647 printf("CF Poll ");
648 break;
649 case DATA_DATA_CF_ACK_POLL:
650 case DATA_NODATA_CF_ACK_POLL:
651 printf("CF Ack/Poll ");
652 break;
653 }
654
655 #define ADDR1 (p + 4)
656 #define ADDR2 (p + 10)
657 #define ADDR3 (p + 16)
658 #define ADDR4 (p + 24)
659
660 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
661 if (srcp != NULL)
662 *srcp = ADDR2;
663 if (dstp != NULL)
664 *dstp = ADDR1;
665 if (!eflag)
666 return;
667 printf("DA:%s SA:%s BSSID:%s ",
668 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
669 etheraddr_string(ADDR3));
670 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
671 if (srcp != NULL)
672 *srcp = ADDR3;
673 if (dstp != NULL)
674 *dstp = ADDR1;
675 if (!eflag)
676 return;
677 printf("DA:%s BSSID:%s SA:%s ",
678 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
679 etheraddr_string(ADDR3));
680 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
681 if (srcp != NULL)
682 *srcp = ADDR2;
683 if (dstp != NULL)
684 *dstp = ADDR3;
685 if (!eflag)
686 return;
687 printf("BSSID:%s SA:%s DA:%s ",
688 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
689 etheraddr_string(ADDR3));
690 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
691 if (srcp != NULL)
692 *srcp = ADDR4;
693 if (dstp != NULL)
694 *dstp = ADDR3;
695 if (!eflag)
696 return;
697 printf("RA:%s TA:%s DA:%s SA:%s ",
698 etheraddr_string(ADDR1), etheraddr_string(ADDR2),
699 etheraddr_string(ADDR3), etheraddr_string(ADDR4));
700 }
701
702 #undef ADDR1
703 #undef ADDR2
704 #undef ADDR3
705 #undef ADDR4
706 }
707
708 static void
709 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
710 const u_int8_t **dstp)
711 {
712 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
713
714 if (srcp != NULL)
715 *srcp = hp->sa;
716 if (dstp != NULL)
717 *dstp = hp->da;
718 if (!eflag)
719 return;
720
721 printf("BSSID:%s DA:%s SA:%s ",
722 etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
723 etheraddr_string((hp)->sa));
724 }
725
726 static void
727 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
728 const u_int8_t **dstp)
729 {
730 if (srcp != NULL)
731 *srcp = NULL;
732 if (dstp != NULL)
733 *dstp = NULL;
734 if (!eflag)
735 return;
736
737 switch (FC_SUBTYPE(fc)) {
738 case CTRL_PS_POLL:
739 printf("BSSID:%s TA:%s ",
740 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
741 etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
742 break;
743 case CTRL_RTS:
744 printf("RA:%s TA:%s ",
745 etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
746 etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
747 break;
748 case CTRL_CTS:
749 printf("RA:%s ",
750 etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
751 break;
752 case CTRL_ACK:
753 printf("RA:%s ",
754 etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
755 break;
756 case CTRL_CF_END:
757 printf("RA:%s BSSID:%s ",
758 etheraddr_string(((const struct ctrl_end_t *)p)->ra),
759 etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
760 break;
761 case CTRL_END_ACK:
762 printf("RA:%s BSSID:%s ",
763 etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
764 etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
765 break;
766 default:
767 printf("(H) Unknown Ctrl Subtype");
768 break;
769 }
770 }
771
772 static int
773 extract_header_length(u_int16_t fc)
774 {
775 switch (FC_TYPE(fc)) {
776 case T_MGMT:
777 return MGMT_HDRLEN;
778 case T_CTRL:
779 switch (FC_SUBTYPE(fc)) {
780 case CTRL_PS_POLL:
781 return CTRL_PS_POLL_HDRLEN;
782 case CTRL_RTS:
783 return CTRL_RTS_HDRLEN;
784 case CTRL_CTS:
785 return CTRL_CTS_HDRLEN;
786 case CTRL_ACK:
787 return CTRL_ACK_HDRLEN;
788 case CTRL_CF_END:
789 return CTRL_END_HDRLEN;
790 case CTRL_END_ACK:
791 return CTRL_END_ACK_HDRLEN;
792 default:
793 return 0;
794 }
795 case T_DATA:
796 return (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
797 default:
798 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
799 return 0;
800 }
801 }
802
803 /*
804 * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
805 * to point to the source and destination MAC addresses in any case if
806 * "srcp" and "dstp" aren't null.
807 */
808 static inline void
809 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
810 const u_int8_t **dstp)
811 {
812 if (vflag) {
813 if (FC_MORE_DATA(fc))
814 printf("More Data ");
815 if (FC_MORE_FLAG(fc))
816 printf("More Fragments ");
817 if (FC_POWER_MGMT(fc))
818 printf("Pwr Mgmt ");
819 if (FC_RETRY(fc))
820 printf("Retry ");
821 if (FC_ORDER(fc))
822 printf("Strictly Ordered ");
823 if (FC_WEP(fc))
824 printf("WEP Encrypted ");
825 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
826 printf("%dus ",
827 EXTRACT_LE_16BITS(
828 &((const struct mgmt_header_t *)p)->duration));
829 }
830
831 switch (FC_TYPE(fc)) {
832 case T_MGMT:
833 mgmt_header_print(p, srcp, dstp);
834 break;
835 case T_CTRL:
836 ctrl_header_print(fc, p, srcp, dstp);
837 break;
838 case T_DATA:
839 data_header_print(fc, p, srcp, dstp);
840 break;
841 default:
842 printf("(header) unknown IEEE802.11 frame type (%d)",
843 FC_TYPE(fc));
844 *srcp = NULL;
845 *dstp = NULL;
846 break;
847 }
848 }
849
850 static u_int
851 ieee802_11_print(const u_char *p, u_int length, u_int caplen)
852 {
853 u_int16_t fc;
854 u_int hdrlen;
855 const u_int8_t *src, *dst;
856 u_short extracted_ethertype;
857
858 if (caplen < IEEE802_11_FC_LEN) {
859 printf("[|802.11]");
860 return caplen;
861 }
862
863 fc = EXTRACT_LE_16BITS(p);
864 hdrlen = extract_header_length(fc);
865
866 if (caplen < hdrlen) {
867 printf("[|802.11]");
868 return hdrlen;
869 }
870
871 ieee_802_11_hdr_print(fc, p, &src, &dst);
872
873 /*
874 * Go past the 802.11 header.
875 */
876 length -= hdrlen;
877 caplen -= hdrlen;
878 p += hdrlen;
879
880 switch (FC_TYPE(fc)) {
881 case T_MGMT:
882 if (!mgmt_body_print(fc,
883 (const struct mgmt_header_t *)(p - hdrlen), p)) {
884 printf("[|802.11]");
885 return hdrlen;
886 }
887 break;
888 case T_CTRL:
889 if (!ctrl_body_print(fc, p - hdrlen)) {
890 printf("[|802.11]");
891 return hdrlen;
892 }
893 break;
894 case T_DATA:
895 /* There may be a problem w/ AP not having this bit set */
896 if (FC_WEP(fc)) {
897 if (!wep_print(p)) {
898 printf("[|802.11]");
899 return hdrlen;
900 }
901 } else if (llc_print(p, length, caplen, dst, src,
902 &extracted_ethertype) == 0) {
903 /*
904 * Some kinds of LLC packet we cannot
905 * handle intelligently
906 */
907 if (!eflag)
908 ieee_802_11_hdr_print(fc, p - hdrlen, NULL,
909 NULL);
910 if (extracted_ethertype)
911 printf("(LLC %s) ",
912 etherproto_string(
913 htons(extracted_ethertype)));
914 if (!suppress_default_print)
915 default_print(p, caplen);
916 }
917 break;
918 default:
919 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
920 break;
921 }
922
923 return hdrlen;
924 }
925
926 /*
927 * This is the top level routine of the printer. 'p' points
928 * to the 802.11 header of the packet, 'h->ts' is the timestamp,
929 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
930 * is the number of bytes actually captured.
931 */
932 u_int
933 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
934 {
935 return ieee802_11_print(p, h->len, h->caplen);
936 }
937
938 static int
939 print_radiotap_field(struct cpack_state *s, u_int32_t bit)
940 {
941 union {
942 int8_t i8;
943 u_int8_t u8;
944 int16_t i16;
945 u_int16_t u16;
946 u_int32_t u32;
947 u_int64_t u64;
948 } u, u2;
949 int rc;
950
951 switch (bit) {
952 case IEEE80211_RADIOTAP_FLAGS:
953 case IEEE80211_RADIOTAP_RATE:
954 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
955 case IEEE80211_RADIOTAP_DB_ANTNOISE:
956 case IEEE80211_RADIOTAP_ANTENNA:
957 rc = cpack_uint8(s, &u.u8);
958 break;
959 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
960 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
961 rc = cpack_int8(s, &u.i8);
962 break;
963 case IEEE80211_RADIOTAP_CHANNEL:
964 rc = cpack_uint16(s, &u.u16);
965 if (rc != 0)
966 break;
967 rc = cpack_uint16(s, &u2.u16);
968 break;
969 case IEEE80211_RADIOTAP_FHSS:
970 case IEEE80211_RADIOTAP_LOCK_QUALITY:
971 case IEEE80211_RADIOTAP_TX_ATTENUATION:
972 rc = cpack_uint16(s, &u.u16);
973 break;
974 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
975 rc = cpack_uint8(s, &u.u8);
976 break;
977 case IEEE80211_RADIOTAP_DBM_TX_POWER:
978 rc = cpack_int8(s, &u.i8);
979 break;
980 case IEEE80211_RADIOTAP_TSFT:
981 rc = cpack_uint64(s, &u.u64);
982 break;
983 default:
984 /* this bit indicates a field whose
985 * size we do not know, so we cannot
986 * proceed.
987 */
988 printf("[0x%08x] ", bit);
989 return -1;
990 }
991
992 if (rc != 0) {
993 printf("[|802.11]");
994 return rc;
995 }
996
997 switch (bit) {
998 case IEEE80211_RADIOTAP_CHANNEL:
999 printf("%u MHz ", u.u16);
1000 if (u2.u16 != 0)
1001 printf("(0x%04x) ", u2.u16);
1002 break;
1003 case IEEE80211_RADIOTAP_FHSS:
1004 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1005 break;
1006 case IEEE80211_RADIOTAP_RATE:
1007 PRINT_RATE("", u.u8, " Mb/s ");
1008 break;
1009 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1010 printf("%ddB signal ", u.i8);
1011 break;
1012 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1013 printf("%ddB noise ", u.i8);
1014 break;
1015 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1016 printf("%ddB signal ", u.u8);
1017 break;
1018 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1019 printf("%ddB noise ", u.u8);
1020 break;
1021 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1022 printf("%u sq ", u.u16);
1023 break;
1024 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1025 printf("%d tx power ", -(int)u.u16);
1026 break;
1027 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1028 printf("%ddB tx power ", -(int)u.u8);
1029 break;
1030 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1031 printf("%ddBm tx power ", u.i8);
1032 break;
1033 case IEEE80211_RADIOTAP_FLAGS:
1034 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1035 printf("cfp ");
1036 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1037 printf("short preamble ");
1038 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1039 printf("wep ");
1040 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1041 printf("fragmented ");
1042 break;
1043 case IEEE80211_RADIOTAP_ANTENNA:
1044 printf("antenna %d ", u.u8);
1045 break;
1046 case IEEE80211_RADIOTAP_TSFT:
1047 printf("%" PRIu64 "us tsft ", u.u64);
1048 break;
1049 }
1050 return 0;
1051 }
1052
1053 static u_int
1054 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1055 {
1056 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1057 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1058 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1059 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1060 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1061 #define BIT(n) (1 << n)
1062 #define IS_EXTENDED(__p) \
1063 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1064
1065 struct cpack_state cpacker;
1066 struct ieee80211_radiotap_header *hdr;
1067 u_int32_t present, next_present;
1068 u_int32_t *presentp, *last_presentp;
1069 enum ieee80211_radiotap_type bit;
1070 int bit0;
1071 const u_char *iter;
1072 u_int len;
1073
1074 if (caplen < sizeof(*hdr)) {
1075 printf("[|802.11]");
1076 return caplen;
1077 }
1078
1079 hdr = (struct ieee80211_radiotap_header *)p;
1080
1081 len = EXTRACT_LE_16BITS(&hdr->it_len);
1082
1083 if (caplen < len) {
1084 printf("[|802.11]");
1085 return caplen;
1086 }
1087 for (last_presentp = &hdr->it_present;
1088 IS_EXTENDED(last_presentp) &&
1089 (u_char*)(last_presentp + 1) <= p + len;
1090 last_presentp++);
1091
1092 /* are there more bitmap extensions than bytes in header? */
1093 if (IS_EXTENDED(last_presentp)) {
1094 printf("[|802.11]");
1095 return caplen;
1096 }
1097
1098 iter = (u_char*)(last_presentp + 1);
1099
1100 if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1101 /* XXX */
1102 printf("[|802.11]");
1103 return caplen;
1104 }
1105
1106 for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1107 presentp++, bit0 += 32) {
1108 for (present = EXTRACT_LE_32BITS(presentp); present;
1109 present = next_present) {
1110 /* clear the least significant bit that is set */
1111 next_present = present & (present - 1);
1112
1113 /* extract the least significant bit that is set */
1114 bit = (enum ieee80211_radiotap_type)
1115 (bit0 + BITNO_32(present ^ next_present));
1116
1117 if (print_radiotap_field(&cpacker, bit) != 0)
1118 goto out;
1119 }
1120 }
1121 out:
1122 return len + ieee802_11_print(p + len, length - len, caplen - len);
1123 #undef BITNO_32
1124 #undef BITNO_16
1125 #undef BITNO_8
1126 #undef BITNO_4
1127 #undef BITNO_2
1128 #undef BIT
1129 }
1130
1131 static u_int
1132 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1133 {
1134 u_int32_t caphdr_len;
1135
1136 caphdr_len = EXTRACT_32BITS(p + 4);
1137 if (caphdr_len < 8) {
1138 /*
1139 * Yow! The capture header length is claimed not
1140 * to be large enough to include even the version
1141 * cookie or capture header length!
1142 */
1143 printf("[|802.11]");
1144 return caplen;
1145 }
1146
1147 if (caplen < caphdr_len) {
1148 printf("[|802.11]");
1149 return caplen;
1150 }
1151
1152 return caphdr_len + ieee802_11_print(p + caphdr_len,
1153 length - caphdr_len, caplen - caphdr_len);
1154 }
1155
1156 #define PRISM_HDR_LEN 144
1157
1158 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1159
1160 /*
1161 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1162 * containing information such as radio information, which we
1163 * currently ignore.
1164 *
1165 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1, it's
1166 * really DLT_IEEE802_11_RADIO (currently, on Linux, there's no
1167 * ARPHRD_ type for DLT_IEEE802_11_RADIO, as there is a
1168 * ARPHRD_IEEE80211_PRISM for DLT_PRISM_HEADER, so
1169 * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and
1170 * the first 4 bytes of the header are used to indicate which it is).
1171 */
1172 u_int
1173 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1174 {
1175 u_int caplen = h->caplen;
1176 u_int length = h->len;
1177
1178 if (caplen < 4) {
1179 printf("[|802.11]");
1180 return caplen;
1181 }
1182
1183 if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
1184 return ieee802_11_avs_radio_print(p, length, caplen);
1185
1186 if (caplen < PRISM_HDR_LEN) {
1187 printf("[|802.11]");
1188 return caplen;
1189 }
1190
1191 return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1192 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN);
1193 }
1194
1195 /*
1196 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1197 * header, containing information such as radio information, which we
1198 * currently ignore.
1199 */
1200 u_int
1201 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1202 {
1203 u_int caplen = h->caplen;
1204 u_int length = h->len;
1205
1206 if (caplen < 8) {
1207 printf("[|802.11]");
1208 return caplen;
1209 }
1210
1211 return ieee802_11_radio_print(p, length, caplen);
1212 }