OSDN Git Service

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