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