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