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