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