Import of TCPDUMP 3.9.5
[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.11 2006/06/13 22:25:43 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->rates.length > 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         switch (FC_SUBTYPE(fc)) {
691         case DATA_DATA:
692         case DATA_NODATA:
693                 break;
694         case DATA_DATA_CF_ACK:
695         case DATA_NODATA_CF_ACK:
696                 printf("CF Ack ");
697                 break;
698         case DATA_DATA_CF_POLL:
699         case DATA_NODATA_CF_POLL:
700                 printf("CF Poll ");
701                 break;
702         case DATA_DATA_CF_ACK_POLL:
703         case DATA_NODATA_CF_ACK_POLL:
704                 printf("CF Ack/Poll ");
705                 break;
706         }
707
708 #define ADDR1  (p + 4)
709 #define ADDR2  (p + 10)
710 #define ADDR3  (p + 16)
711 #define ADDR4  (p + 24)
712
713         if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
714                 if (srcp != NULL)
715                         *srcp = ADDR2;
716                 if (dstp != NULL)
717                         *dstp = ADDR1;
718                 if (!eflag)
719                         return;
720                 printf("DA:%s SA:%s BSSID:%s ",
721                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
722                     etheraddr_string(ADDR3));
723         } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
724                 if (srcp != NULL)
725                         *srcp = ADDR3;
726                 if (dstp != NULL)
727                         *dstp = ADDR1;
728                 if (!eflag)
729                         return;
730                 printf("DA:%s BSSID:%s SA:%s ",
731                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
732                     etheraddr_string(ADDR3));
733         } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
734                 if (srcp != NULL)
735                         *srcp = ADDR2;
736                 if (dstp != NULL)
737                         *dstp = ADDR3;
738                 if (!eflag)
739                         return;
740                 printf("BSSID:%s SA:%s DA:%s ",
741                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
742                     etheraddr_string(ADDR3));
743         } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
744                 if (srcp != NULL)
745                         *srcp = ADDR4;
746                 if (dstp != NULL)
747                         *dstp = ADDR3;
748                 if (!eflag)
749                         return;
750                 printf("RA:%s TA:%s DA:%s SA:%s ",
751                     etheraddr_string(ADDR1), etheraddr_string(ADDR2),
752                     etheraddr_string(ADDR3), etheraddr_string(ADDR4));
753         }
754
755 #undef ADDR1
756 #undef ADDR2
757 #undef ADDR3
758 #undef ADDR4
759 }
760
761 static void
762 mgmt_header_print(const u_char *p, const u_int8_t **srcp,
763     const u_int8_t **dstp)
764 {
765         const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
766
767         if (srcp != NULL)
768                 *srcp = hp->sa;
769         if (dstp != NULL)
770                 *dstp = hp->da;
771         if (!eflag)
772                 return;
773
774         printf("BSSID:%s DA:%s SA:%s ",
775             etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
776             etheraddr_string((hp)->sa));
777 }
778
779 static void
780 ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
781     const u_int8_t **dstp)
782 {
783         if (srcp != NULL)
784                 *srcp = NULL;
785         if (dstp != NULL)
786                 *dstp = NULL;
787         if (!eflag)
788                 return;
789
790         switch (FC_SUBTYPE(fc)) {
791         case CTRL_PS_POLL:
792                 printf("BSSID:%s TA:%s ",
793                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
794                     etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
795                 break;
796         case CTRL_RTS:
797                 printf("RA:%s TA:%s ",
798                     etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
799                     etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
800                 break;
801         case CTRL_CTS:
802                 printf("RA:%s ",
803                     etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
804                 break;
805         case CTRL_ACK:
806                 printf("RA:%s ",
807                     etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
808                 break;
809         case CTRL_CF_END:
810                 printf("RA:%s BSSID:%s ",
811                     etheraddr_string(((const struct ctrl_end_t *)p)->ra),
812                     etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
813                 break;
814         case CTRL_END_ACK:
815                 printf("RA:%s BSSID:%s ",
816                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
817                     etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
818                 break;
819         default:
820                 printf("(H) Unknown Ctrl Subtype");
821                 break;
822         }
823 }
824
825 static int
826 extract_header_length(u_int16_t fc)
827 {
828         switch (FC_TYPE(fc)) {
829         case T_MGMT:
830                 return MGMT_HDRLEN;
831         case T_CTRL:
832                 switch (FC_SUBTYPE(fc)) {
833                 case CTRL_PS_POLL:
834                         return CTRL_PS_POLL_HDRLEN;
835                 case CTRL_RTS:
836                         return CTRL_RTS_HDRLEN;
837                 case CTRL_CTS:
838                         return CTRL_CTS_HDRLEN;
839                 case CTRL_ACK:
840                         return CTRL_ACK_HDRLEN;
841                 case CTRL_CF_END:
842                         return CTRL_END_HDRLEN;
843                 case CTRL_END_ACK:
844                         return CTRL_END_ACK_HDRLEN;
845                 default:
846                         return 0;
847                 }
848         case T_DATA:
849                 return (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
850         default:
851                 printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
852                 return 0;
853         }
854 }
855
856 /*
857  * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
858  * to point to the source and destination MAC addresses in any case if
859  * "srcp" and "dstp" aren't null.
860  */
861 static inline void
862 ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
863     const u_int8_t **dstp)
864 {
865         if (vflag) {
866                 if (FC_MORE_DATA(fc))
867                         printf("More Data ");
868                 if (FC_MORE_FLAG(fc))
869                         printf("More Fragments ");
870                 if (FC_POWER_MGMT(fc))
871                         printf("Pwr Mgmt ");
872                 if (FC_RETRY(fc))
873                         printf("Retry ");
874                 if (FC_ORDER(fc))
875                         printf("Strictly Ordered ");
876                 if (FC_WEP(fc))
877                         printf("WEP Encrypted ");
878                 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
879                         printf("%dus ",
880                             EXTRACT_LE_16BITS(
881                                 &((const struct mgmt_header_t *)p)->duration));
882         }
883
884         switch (FC_TYPE(fc)) {
885         case T_MGMT:
886                 mgmt_header_print(p, srcp, dstp);
887                 break;
888         case T_CTRL:
889                 ctrl_header_print(fc, p, srcp, dstp);
890                 break;
891         case T_DATA:
892                 data_header_print(fc, p, srcp, dstp);
893                 break;
894         default:
895                 printf("(header) unknown IEEE802.11 frame type (%d)",
896                     FC_TYPE(fc));
897                 *srcp = NULL;
898                 *dstp = NULL;
899                 break;
900         }
901 }
902
903 static u_int
904 ieee802_11_print(const u_char *p, u_int length, u_int caplen)
905 {
906         u_int16_t fc;
907         u_int hdrlen;
908         const u_int8_t *src, *dst;
909         u_short extracted_ethertype;
910
911         if (caplen < IEEE802_11_FC_LEN) {
912                 printf("[|802.11]");
913                 return caplen;
914         }
915
916         fc = EXTRACT_LE_16BITS(p);
917         hdrlen = extract_header_length(fc);
918
919         if (caplen < hdrlen) {
920                 printf("[|802.11]");
921                 return hdrlen;
922         }
923
924         ieee_802_11_hdr_print(fc, p, &src, &dst);
925
926         /*
927          * Go past the 802.11 header.
928          */
929         length -= hdrlen;
930         caplen -= hdrlen;
931         p += hdrlen;
932
933         switch (FC_TYPE(fc)) {
934         case T_MGMT:
935                 if (!mgmt_body_print(fc,
936                     (const struct mgmt_header_t *)(p - hdrlen), p)) {
937                         printf("[|802.11]");
938                         return hdrlen;
939                 }
940                 break;
941         case T_CTRL:
942                 if (!ctrl_body_print(fc, p - hdrlen)) {
943                         printf("[|802.11]");
944                         return hdrlen;
945                 }
946                 break;
947         case T_DATA:
948                 /* There may be a problem w/ AP not having this bit set */
949                 if (FC_WEP(fc)) {
950                         if (!wep_print(p)) {
951                                 printf("[|802.11]");
952                                 return hdrlen;
953                         }
954                 } else if (llc_print(p, length, caplen, dst, src,
955                     &extracted_ethertype) == 0) {
956                         /*
957                          * Some kinds of LLC packet we cannot
958                          * handle intelligently
959                          */
960                         if (!eflag)
961                                 ieee_802_11_hdr_print(fc, p - hdrlen, NULL,
962                                     NULL);
963                         if (extracted_ethertype)
964                                 printf("(LLC %s) ",
965                                     etherproto_string(
966                                         htons(extracted_ethertype)));
967                         if (!suppress_default_print)
968                                 default_print(p, caplen);
969                 }
970                 break;
971         default:
972                 printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
973                 break;
974         }
975
976         return hdrlen;
977 }
978
979 /*
980  * This is the top level routine of the printer.  'p' points
981  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
982  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
983  * is the number of bytes actually captured.
984  */
985 u_int
986 ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
987 {
988         return ieee802_11_print(p, h->len, h->caplen);
989 }
990
991 static int
992 print_radiotap_field(struct cpack_state *s, u_int32_t bit)
993 {
994         union {
995                 int8_t          i8;
996                 u_int8_t        u8;
997                 int16_t         i16;
998                 u_int16_t       u16;
999                 u_int32_t       u32;
1000                 u_int64_t       u64;
1001         } u, u2;
1002         int rc;
1003
1004         switch (bit) {
1005         case IEEE80211_RADIOTAP_FLAGS:
1006         case IEEE80211_RADIOTAP_RATE:
1007         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1008         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1009         case IEEE80211_RADIOTAP_ANTENNA:
1010                 rc = cpack_uint8(s, &u.u8);
1011                 break;
1012         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1013         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1014                 rc = cpack_int8(s, &u.i8);
1015                 break;
1016         case IEEE80211_RADIOTAP_CHANNEL:
1017                 rc = cpack_uint16(s, &u.u16);
1018                 if (rc != 0)
1019                         break;
1020                 rc = cpack_uint16(s, &u2.u16);
1021                 break;
1022         case IEEE80211_RADIOTAP_FHSS:
1023         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1024         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1025                 rc = cpack_uint16(s, &u.u16);
1026                 break;
1027         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1028                 rc = cpack_uint8(s, &u.u8);
1029                 break;
1030         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1031                 rc = cpack_int8(s, &u.i8);
1032                 break;
1033         case IEEE80211_RADIOTAP_TSFT:
1034                 rc = cpack_uint64(s, &u.u64);
1035                 break;
1036         default:
1037                 /* this bit indicates a field whose
1038                  * size we do not know, so we cannot
1039                  * proceed.
1040                  */
1041                 printf("[0x%08x] ", bit);
1042                 return -1;
1043         }
1044
1045         if (rc != 0) {
1046                 printf("[|802.11]");
1047                 return rc;
1048         }
1049
1050         switch (bit) {
1051         case IEEE80211_RADIOTAP_CHANNEL:
1052                 printf("%u MHz ", u.u16);
1053                 if (u2.u16 != 0)
1054                         printf("(0x%04x) ", u2.u16);
1055                 break;
1056         case IEEE80211_RADIOTAP_FHSS:
1057                 printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1058                 break;
1059         case IEEE80211_RADIOTAP_RATE:
1060                 PRINT_RATE("", u.u8, " Mb/s ");
1061                 break;
1062         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1063                 printf("%ddB signal ", u.i8);
1064                 break;
1065         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1066                 printf("%ddB noise ", u.i8);
1067                 break;
1068         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1069                 printf("%ddB signal ", u.u8);
1070                 break;
1071         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1072                 printf("%ddB noise ", u.u8);
1073                 break;
1074         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1075                 printf("%u sq ", u.u16);
1076                 break;
1077         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1078                 printf("%d tx power ", -(int)u.u16);
1079                 break;
1080         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1081                 printf("%ddB tx power ", -(int)u.u8);
1082                 break;
1083         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1084                 printf("%ddBm tx power ", u.i8);
1085                 break;
1086         case IEEE80211_RADIOTAP_FLAGS:
1087                 if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1088                         printf("cfp ");
1089                 if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1090                         printf("short preamble ");
1091                 if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1092                         printf("wep ");
1093                 if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1094                         printf("fragmented ");
1095                 if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1096                         printf("bad-fcs ");
1097                 break;
1098         case IEEE80211_RADIOTAP_ANTENNA:
1099                 printf("antenna %d ", u.u8);
1100                 break;
1101         case IEEE80211_RADIOTAP_TSFT:
1102                 printf("%" PRIu64 "us tsft ", u.u64);
1103                 break;
1104         }
1105         return 0;
1106 }
1107
1108 static u_int
1109 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
1110 {
1111 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1112 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1113 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1114 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1115 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1116 #define BIT(n)  (1 << n)
1117 #define IS_EXTENDED(__p)        \
1118             (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1119
1120         struct cpack_state cpacker;
1121         struct ieee80211_radiotap_header *hdr;
1122         u_int32_t present, next_present;
1123         u_int32_t *presentp, *last_presentp;
1124         enum ieee80211_radiotap_type bit;
1125         int bit0;
1126         const u_char *iter;
1127         u_int len;
1128
1129         if (caplen < sizeof(*hdr)) {
1130                 printf("[|802.11]");
1131                 return caplen;
1132         }
1133
1134         hdr = (struct ieee80211_radiotap_header *)p;
1135
1136         len = EXTRACT_LE_16BITS(&hdr->it_len);
1137
1138         if (caplen < len) {
1139                 printf("[|802.11]");
1140                 return caplen;
1141         }
1142         for (last_presentp = &hdr->it_present;
1143              IS_EXTENDED(last_presentp) &&
1144              (u_char*)(last_presentp + 1) <= p + len;
1145              last_presentp++);
1146
1147         /* are there more bitmap extensions than bytes in header? */
1148         if (IS_EXTENDED(last_presentp)) {
1149                 printf("[|802.11]");
1150                 return caplen;
1151         }
1152
1153         iter = (u_char*)(last_presentp + 1);
1154
1155         if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1156                 /* XXX */
1157                 printf("[|802.11]");
1158                 return caplen;
1159         }
1160
1161         for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1162              presentp++, bit0 += 32) {
1163                 for (present = EXTRACT_LE_32BITS(presentp); present;
1164                      present = next_present) {
1165                         /* clear the least significant bit that is set */
1166                         next_present = present & (present - 1);
1167
1168                         /* extract the least significant bit that is set */
1169                         bit = (enum ieee80211_radiotap_type)
1170                             (bit0 + BITNO_32(present ^ next_present));
1171
1172                         if (print_radiotap_field(&cpacker, bit) != 0)
1173                                 goto out;
1174                 }
1175         }
1176 out:
1177         return len + ieee802_11_print(p + len, length - len, caplen - len);
1178 #undef BITNO_32
1179 #undef BITNO_16
1180 #undef BITNO_8
1181 #undef BITNO_4
1182 #undef BITNO_2
1183 #undef BIT
1184 }
1185
1186 static u_int
1187 ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
1188 {
1189         u_int32_t caphdr_len;
1190
1191         caphdr_len = EXTRACT_32BITS(p + 4);
1192         if (caphdr_len < 8) {
1193                 /*
1194                  * Yow!  The capture header length is claimed not
1195                  * to be large enough to include even the version
1196                  * cookie or capture header length!
1197                  */
1198                 printf("[|802.11]");
1199                 return caplen;
1200         }
1201
1202         if (caplen < caphdr_len) {
1203                 printf("[|802.11]");
1204                 return caplen;
1205         }
1206
1207         return caphdr_len + ieee802_11_print(p + caphdr_len,
1208             length - caphdr_len, caplen - caphdr_len);
1209 }
1210
1211 #define PRISM_HDR_LEN           144
1212
1213 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001
1214
1215 /*
1216  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
1217  * containing information such as radio information, which we
1218  * currently ignore.
1219  *
1220  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1, it's
1221  * really DLT_IEEE802_11_RADIO (currently, on Linux, there's no
1222  * ARPHRD_ type for DLT_IEEE802_11_RADIO, as there is a
1223  * ARPHRD_IEEE80211_PRISM for DLT_PRISM_HEADER, so
1224  * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and
1225  * the first 4 bytes of the header are used to indicate which it is).
1226  */
1227 u_int
1228 prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
1229 {
1230         u_int caplen = h->caplen;
1231         u_int length = h->len;
1232
1233         if (caplen < 4) {
1234                 printf("[|802.11]");
1235                 return caplen;
1236         }
1237
1238         if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
1239                 return ieee802_11_avs_radio_print(p, length, caplen);
1240
1241         if (caplen < PRISM_HDR_LEN) {
1242                 printf("[|802.11]");
1243                 return caplen;
1244         }
1245
1246         return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
1247             length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN);
1248 }
1249
1250 /*
1251  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
1252  * header, containing information such as radio information, which we
1253  * currently ignore.
1254  */
1255 u_int
1256 ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
1257 {
1258         u_int caplen = h->caplen;
1259         u_int length = h->len;
1260
1261         if (caplen < 8) {
1262                 printf("[|802.11]");
1263                 return caplen;
1264         }
1265
1266         return ieee802_11_radio_print(p, length, caplen);
1267 }