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