GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-802_11.c Lines: 0 785 0.0 %
Date: 2017-11-07 Branches: 0 738 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-802_11.c,v 1.40 2017/09/01 14:04:49 stsp Exp $	*/
2
3
/*
4
 * Copyright (c) 2005 Reyk Floeter <reyk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/time.h>
20
#include <sys/socket.h>
21
#include <sys/file.h>
22
#include <sys/ioctl.h>
23
24
#include <net/if.h>
25
26
#include <netinet/in.h>
27
#include <netinet/if_ether.h>
28
29
#include <net80211/ieee80211.h>
30
#include <net80211/ieee80211_radiotap.h>
31
32
#include <ctype.h>
33
#include <pcap.h>
34
#include <stdio.h>
35
#include <string.h>
36
37
#include "addrtoname.h"
38
#include "interface.h"
39
40
const char *ieee80211_ctl_subtype_name[] = {
41
	"reserved#0",
42
	"reserved#1",
43
	"reserved#2",
44
	"reserved#3",
45
	"reserved#4",
46
	"reserved#5",
47
	"reserved#6",
48
	"wrapper",
49
	"block ack request",
50
	"block ack",
51
	"ps poll",
52
	"rts",
53
	"cts",
54
	"ack",
55
	"cf-end",
56
	"cf-end-ack",
57
};
58
59
const char *ieee80211_mgt_subtype_name[] = {
60
	"association request",
61
	"association response",
62
	"reassociation request",
63
	"reassociation response",
64
	"probe request",
65
	"probe response",
66
	"reserved#6",
67
	"reserved#7",
68
	"beacon",
69
	"atim",
70
	"disassociation",
71
	"authentication",
72
	"deauthentication",
73
	"action",
74
	"action noack",
75
	"reserved#15"
76
};
77
78
const char *ieee80211_data_subtype_name[] = {
79
	"data",
80
	"data cf ack",
81
	"data cf poll",
82
	"data cf poll ack",
83
	"no-data",
84
	"no-data cf poll",
85
	"no-data cf ack",
86
	"no-data cf poll ack",
87
	"QoS data",
88
	"QoS data cf ack",
89
	"QoS data cf poll",
90
	"QoS data cf poll ack",
91
	"QoS no-data",
92
	"QoS no-data cf poll",
93
	"QoS no-data cf ack",
94
	"QoS no-data cf poll ack"
95
};
96
97
int	 ieee80211_hdr(struct ieee80211_frame *);
98
int	 ieee80211_data(struct ieee80211_frame *, u_int);
99
void	 ieee80211_print_element(u_int8_t *, u_int);
100
void	 ieee80211_print_essid(u_int8_t *, u_int);
101
void	 ieee80211_print_country(u_int8_t *, u_int);
102
void	 ieee80211_print_htcaps(u_int8_t *, u_int);
103
void	 ieee80211_print_htop(u_int8_t *, u_int);
104
void	 ieee80211_print_rsncipher(u_int8_t []);
105
void	 ieee80211_print_akm(u_int8_t []);
106
void	 ieee80211_print_rsn(u_int8_t *, u_int);
107
int	 ieee80211_print_beacon(struct ieee80211_frame *, u_int);
108
int	 ieee80211_print_assocreq(struct ieee80211_frame *, u_int);
109
int	 ieee80211_print_elements(uint8_t *);
110
int	 ieee80211_frame(struct ieee80211_frame *, u_int);
111
int	 ieee80211_print(struct ieee80211_frame *, u_int);
112
u_int	 ieee80211_any2ieee(u_int, u_int);
113
void	 ieee80211_reason(u_int16_t);
114
115
#define TCARR(a)	TCHECK2(*a, sizeof(a))
116
117
int ieee80211_encap = 0;
118
119
int
120
ieee80211_hdr(struct ieee80211_frame *wh)
121
{
122
	struct ieee80211_frame_addr4 *w4;
123
124
	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
125
	case IEEE80211_FC1_DIR_NODS:
126
		TCARR(wh->i_addr2);
127
		printf("%s", etheraddr_string(wh->i_addr2));
128
		TCARR(wh->i_addr1);
129
		printf(" > %s", etheraddr_string(wh->i_addr1));
130
		TCARR(wh->i_addr3);
131
		printf(", bssid %s", etheraddr_string(wh->i_addr3));
132
		break;
133
	case IEEE80211_FC1_DIR_TODS:
134
		TCARR(wh->i_addr2);
135
		printf("%s", etheraddr_string(wh->i_addr2));
136
		TCARR(wh->i_addr3);
137
		printf(" > %s", etheraddr_string(wh->i_addr3));
138
		TCARR(wh->i_addr1);
139
		printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
140
		break;
141
	case IEEE80211_FC1_DIR_FROMDS:
142
		TCARR(wh->i_addr3);
143
		printf("%s", etheraddr_string(wh->i_addr3));
144
		TCARR(wh->i_addr1);
145
		printf(" > %s", etheraddr_string(wh->i_addr1));
146
		TCARR(wh->i_addr2);
147
		printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
148
		break;
149
	case IEEE80211_FC1_DIR_DSTODS:
150
		w4 = (struct ieee80211_frame_addr4 *) wh;
151
		TCARR(w4->i_addr4);
152
		printf("%s", etheraddr_string(w4->i_addr4));
153
		TCARR(w4->i_addr3);
154
		printf(" > %s", etheraddr_string(w4->i_addr3));
155
		TCARR(w4->i_addr2);
156
		printf(", bssid %s", etheraddr_string(w4->i_addr2));
157
		TCARR(w4->i_addr1);
158
		printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1));
159
		break;
160
	}
161
	if (vflag) {
162
		u_int16_t seq;
163
		TCARR(wh->i_seq);
164
		bcopy(wh->i_seq, &seq, sizeof(u_int16_t));
165
		printf(" (seq %u): ", letoh16(seq));
166
	} else
167
		printf(": ");
168
169
	return (0);
170
171
 trunc:
172
	/* Truncated elements in frame */
173
	return (1);
174
}
175
176
int
177
ieee80211_data(struct ieee80211_frame *wh, u_int len)
178
{
179
	u_int8_t *t = (u_int8_t *)wh;
180
	u_int datalen;
181
	int data = !(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_NODATA);
182
	int hasqos = ((wh->i_fc[0] &
183
	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
184
	    (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS));
185
	u_char *esrc = NULL, *edst = NULL;
186
187
	if (hasqos) {
188
		struct ieee80211_qosframe *wq;
189
190
		wq = (struct ieee80211_qosframe *) wh;
191
		TCHECK(*wq);
192
		t += sizeof(*wq);
193
		datalen = len - sizeof(*wq);
194
	} else {
195
		TCHECK(*wh);
196
		t += sizeof(*wh);
197
		datalen = len - sizeof(*wh);
198
	}
199
200
	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
201
	case IEEE80211_FC1_DIR_TODS:
202
		esrc = wh->i_addr2;
203
		edst = wh->i_addr3;
204
		break;
205
	case IEEE80211_FC1_DIR_FROMDS:
206
		esrc = wh->i_addr3;
207
		edst = wh->i_addr1;
208
		break;
209
	case IEEE80211_FC1_DIR_NODS:
210
		esrc = wh->i_addr2;
211
		edst = wh->i_addr1;
212
		break;
213
	case IEEE80211_FC1_DIR_DSTODS:
214
		if (hasqos) {
215
			struct ieee80211_qosframe_addr4 *w4;
216
217
			w4 = (struct ieee80211_qosframe_addr4 *) wh;
218
			TCHECK(*w4);
219
			t = (u_int8_t *) (w4 + 1);
220
			datalen = len - sizeof(*w4);
221
			esrc = w4->i_addr4;
222
			edst = w4->i_addr3;
223
		} else {
224
			struct ieee80211_frame_addr4 *w4;
225
226
			w4 = (struct ieee80211_frame_addr4 *) wh;
227
			TCHECK(*w4);
228
			t = (u_int8_t *) (w4 + 1);
229
			datalen = len - sizeof(*w4);
230
			esrc = w4->i_addr4;
231
			edst = w4->i_addr3;
232
		}
233
		break;
234
	}
235
236
	if (data && esrc)
237
		llc_print(t, datalen, datalen, esrc, edst);
238
	else if (eflag && esrc)
239
		printf("%s > %s",
240
		    etheraddr_string(esrc), etheraddr_string(edst));
241
242
	return (0);
243
244
 trunc:
245
	/* Truncated elements in frame */
246
	return (1);
247
}
248
249
/* Caller checks len */
250
void
251
ieee80211_print_element(u_int8_t *data, u_int len)
252
{
253
	u_int8_t *p;
254
	int i;
255
256
	printf(" 0x");
257
	for (i = 0, p = data; i < len; i++, p++)
258
		printf("%02x", *p);
259
}
260
261
/* Caller checks len */
262
void
263
ieee80211_print_essid(u_int8_t *essid, u_int len)
264
{
265
	u_int8_t *p;
266
	int i;
267
268
	if (len > IEEE80211_NWID_LEN)
269
		len = IEEE80211_NWID_LEN;
270
271
	/* determine printable or not */
272
	for (i = 0, p = essid; i < len; i++, p++) {
273
		if (*p < ' ' || *p > 0x7e)
274
			break;
275
	}
276
	if (i == len) {
277
		printf(" (");
278
		for (i = 0, p = essid; i < len; i++, p++)
279
			putchar(*p);
280
		putchar(')');
281
	} else
282
		ieee80211_print_element(essid, len);
283
}
284
285
/* Caller checks len */
286
void
287
ieee80211_print_country(u_int8_t *data, u_int len)
288
{
289
	u_int8_t first_chan, nchan, maxpower;
290
291
	if (len < 6)
292
		return;
293
294
	/* country string */
295
	printf((isprint(data[0]) ? " '%c" : " '\\%03o"), data[0]);
296
	printf((isprint(data[1]) ? "%c" : "\\%03o"), data[1]);
297
	printf((isprint(data[2]) ? "%c'" : "\\%03o'"), data[2]);
298
299
	len -= 3;
300
	data += 3;
301
302
	/* channels and corresponding TX power limits */
303
	while (len >= 3) {
304
		/* no pretty-printing for nonsensical zero values,
305
		 * nor for operating extension IDs (values >= 201) */
306
		if (data[0] == 0 || data[1] == 0 ||
307
		    data[0] >= 201 || data[1] >= 201) {
308
			printf(", %d %d %d", data[0], data[1], data[2]);
309
			len -= 3;
310
			data += 3;
311
			continue;
312
		}
313
314
		first_chan = data[0];
315
		nchan = data[1];
316
		maxpower = data[2];
317
318
		printf(", channel%s %d", nchan == 1 ? "" : "s", first_chan);
319
		if (nchan > 1)
320
			printf("-%d", first_chan + nchan - 1);
321
		printf(" limit %ddB", maxpower);
322
323
		len -= 3;
324
		data += 3;
325
	}
326
}
327
328
/* Caller checks len */
329
void
330
ieee80211_print_htcaps(u_int8_t *data, u_int len)
331
{
332
	uint16_t htcaps, rxrate;
333
	int smps, rxstbc;
334
	uint8_t ampdu, txmcs;
335
	int i;
336
	uint8_t *rxmcs;
337
338
	if (len < 2) {
339
		ieee80211_print_element(data, len);
340
		return;
341
	}
342
343
	htcaps = (data[0]) | (data[1] << 8);
344
	printf("=<");
345
346
	/* channel width */
347
	if (htcaps & IEEE80211_HTCAP_CBW20_40)
348
		printf("20/40MHz");
349
	else
350
		printf("20MHz");
351
352
	/* LDPC coding */
353
	if (htcaps & IEEE80211_HTCAP_LDPC)
354
		printf(",LDPC");
355
356
	/* spatial multiplexing power save mode */
357
	smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK)
358
	    >> IEEE80211_HTCAP_SMPS_SHIFT;
359
	if (smps == 0)
360
		printf(",SMPS static");
361
	else if (smps == 1)
362
		printf(",SMPS dynamic");
363
364
	/* 11n greenfield mode */
365
	if (htcaps & IEEE80211_HTCAP_GF)
366
		printf(",greenfield");
367
368
	/* short guard interval */
369
	if (htcaps & IEEE80211_HTCAP_SGI20)
370
		printf(",SGI@20MHz");
371
	if (htcaps & IEEE80211_HTCAP_SGI40)
372
		printf(",SGI@40MHz");
373
374
	/* space-time block coding */
375
	if (htcaps & IEEE80211_HTCAP_TXSTBC)
376
		printf(",TXSTBC");
377
	rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK)
378
	    >> IEEE80211_HTCAP_RXSTBC_SHIFT;
379
	if (rxstbc > 0 && rxstbc < 4)
380
		printf(",RXSTBC %d stream", rxstbc);
381
382
	/* delayed block-ack */
383
	if (htcaps & IEEE80211_HTCAP_DELAYEDBA)
384
		printf(",delayed BA");
385
386
	/* max A-MSDU length */
387
	if (htcaps & IEEE80211_HTCAP_AMSDU7935)
388
		printf(",A-MSDU 7935");
389
	else
390
		printf(",A-MSDU 3839");
391
392
	/* DSSS/CCK in 40MHz mode */
393
	if (htcaps & IEEE80211_HTCAP_DSSSCCK40)
394
		printf(",DSSS/CCK@40MHz");
395
396
	/* 40MHz intolerant */
397
	if (htcaps & IEEE80211_HTCAP_40INTOLERANT)
398
		printf(",40MHz intolerant");
399
400
	/* L-SIG TXOP protection */
401
	if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT)
402
		printf(",L-SIG TXOP prot");
403
404
	if (len < 3) {
405
		printf(">");
406
		return;
407
	}
408
409
	/* A-MPDU parameters. */
410
	ampdu = data[2];
411
412
	/* A-MPDU length exponent */
413
	if ((ampdu & IEEE80211_AMPDU_PARAM_LE) >= 0 &&
414
	    (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3)
415
		printf(",A-MPDU max %d",
416
		    (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE))) - 1);
417
418
	/* A-MPDU start spacing */
419
	if (ampdu & IEEE80211_AMPDU_PARAM_SS) {
420
		float ss;
421
422
		switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 2) {
423
		case 1:
424
			ss = 0.25;
425
			break;
426
		case 2:
427
			ss = 0.5;
428
			break;
429
		case 3:
430
			ss = 1;
431
			break;
432
		case 4:
433
			ss = 2;
434
			break;
435
		case 5:
436
			ss = 4;
437
			break;
438
		case 6:
439
			ss = 8;
440
			break;
441
		case 7:
442
			ss = 16;
443
			break;
444
		default:
445
			ss = 0;
446
			break;
447
		}
448
		if (ss != 0)
449
			printf(",A-MPDU spacing %.2fus", ss);
450
	}
451
452
	if (len < 21) {
453
		printf(">");
454
		return;
455
	}
456
457
	/* Supported MCS set. */
458
	printf(",RxMCS 0x");
459
	rxmcs = &data[3];
460
	for (i = 0; i < 10; i++)
461
		printf("%02x", rxmcs[i]);
462
463
	/* Max MCS Rx rate (a value of 0 means "not specified"). */
464
	rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH);
465
	if (rxrate)
466
		printf(",RxMaxrate %huMb/s", rxrate);
467
468
	/* Tx MCS Set */
469
	txmcs = data[15];
470
	if (txmcs & IEEE80211_TX_MCS_SET_DEFINED) {
471
		if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) {
472
			/* Number of spatial Tx streams. */
473
			printf(",%d Tx streams",
474
			     1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2));
475
			/* Transmit unequal modulation supported. */
476
			if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION)
477
				printf(",UEQM");
478
		}
479
	}
480
481
	printf(">");
482
}
483
484
/* Caller checks len */
485
void
486
ieee80211_print_htop(u_int8_t *data, u_int len)
487
{
488
	u_int8_t primary_chan;
489
	u_int8_t htopinfo[5];
490
	u_int8_t basic_mcs[16];
491
	int sco, htprot, i;
492
493
	if (len < sizeof(primary_chan) + sizeof(htopinfo) + sizeof(basic_mcs)) {
494
		ieee80211_print_element(data, len);
495
		return;
496
	}
497
498
	htopinfo[0] = data[1];
499
500
	printf("=<");
501
502
	/* primary channel and secondary channel offset */
503
	primary_chan = data[0];
504
	sco = ((htopinfo[0] & IEEE80211_HTOP0_SCO_MASK)
505
	    >> IEEE80211_HTOP0_SCO_SHIFT);
506
	if (sco == 0) /* no secondary channel */
507
		printf("20MHz chan %d", primary_chan);
508
	else if (sco == 1) { /* secondary channel above */
509
		if (primary_chan >= 1 && primary_chan <= 13) /* 2GHz */
510
			printf("40MHz chan %d:%d", primary_chan,
511
			    primary_chan + 1);
512
		else if (primary_chan >= 34) /* 5GHz */
513
			printf("40MHz chan %d:%d", primary_chan,
514
			    primary_chan + 4);
515
		else
516
			printf("[invalid 40MHz chan %d+]", primary_chan);
517
	} else if (sco == 3) { /* secondary channel below */
518
		if (primary_chan >= 2 && primary_chan <= 14) /* 2GHz */
519
			printf("40MHz chan %d:%d", primary_chan,
520
			    primary_chan - 1);
521
		else if (primary_chan >= 40) /* 5GHz */
522
			printf("40MHz chan %d:%d", primary_chan,
523
			    primary_chan - 4);
524
		else
525
			printf("[invalid 40MHz chan %d-]", primary_chan);
526
	} else
527
		printf("chan %d [invalid secondary channel offset %d]",
528
		    primary_chan, sco);
529
530
	/* STA channel width */
531
	if ((htopinfo[0] & IEEE80211_HTOP0_CHW) == 0)
532
		printf(",STA chanw 20MHz");
533
534
	/* reduced interframe space (RIFS) permitted */
535
	if (htopinfo[0] & IEEE80211_HTOP0_RIFS)
536
		printf(",RIFS");
537
538
	htopinfo[1] = data[2];
539
540
	/* protection requirements for HT transmissions */
541
	htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK)
542
	    >> IEEE80211_HTOP1_PROT_SHIFT);
543
	switch (htprot) {
544
	case IEEE80211_HTPROT_NONE:
545
		printf(",htprot none");
546
		break;
547
	case IEEE80211_HTPROT_NONMEMBER:
548
		printf(",htprot non-member");
549
		break;
550
	case IEEE80211_HTPROT_20MHZ:
551
		printf(",htprot 20MHz");
552
		break;
553
	case IEEE80211_HTPROT_NONHT_MIXED:
554
		printf(",htprot non-HT-mixed");
555
		break;
556
	default:
557
		printf(",htprot %d", htprot);
558
		break;
559
	}
560
561
	/* non-greenfield STA present */
562
	if (htopinfo[1] & IEEE80211_HTOP1_NONGF_STA)
563
		printf(",non-greenfield STA");
564
565
	/* non-HT STA present */
566
	if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA)
567
		printf(",non-HT STA");
568
569
	htopinfo[3] = data[4];
570
571
	/* dual-beacon */
572
	if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON)
573
		printf(",dualbeacon");
574
575
	/* dual CTS protection */
576
	if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT)
577
		printf(",dualctsprot");
578
579
	htopinfo[4] = data[5];
580
581
	/* space-time block coding (STBC) beacon */
582
	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON)
583
		printf(",STBC beacon");
584
585
	/* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */
586
	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP)
587
		printf(",lsigtxprot");
588
589
	/* phased-coexistence operation (PCO) active */
590
	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE) {
591
		/* PCO phase */
592
		if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE40)
593
			printf(",pco40MHz");
594
		else
595
			printf(",pco20MHz");
596
	}
597
598
	/* basic MCS set */
599
	memcpy(basic_mcs, &data[6], sizeof(basic_mcs));
600
	printf(",basic MCS set 0x");
601
	for (i = 0; i < sizeof(basic_mcs) / sizeof(basic_mcs[0]); i++)
602
			printf("%x", basic_mcs[i]);
603
604
	printf(">");
605
}
606
607
void
608
ieee80211_print_rsncipher(uint8_t selector[4])
609
{
610
	if (memcmp(selector, MICROSOFT_OUI, 3) != 0 &&
611
	    memcmp(selector, IEEE80211_OUI, 3) != 0) {
612
		printf("0x%x%x%x%x", selector[0], selector[1], selector[2],
613
		     selector[3]);
614
	    	return;
615
	}
616
617
	/* See 802.11-2012 Table 8-99 */
618
	switch (selector[3]) {
619
	case 0:	/* use group data cipher suite */
620
		printf("usegroup");
621
		break;
622
	case 1:	/* WEP-40 */
623
		printf("wep40");
624
		break;
625
	case 2:	/* TKIP */
626
		printf("tkip");
627
		break;
628
	case 4:	/* CCMP (RSNA default) */
629
		printf("ccmp");
630
		break;
631
	case 5:	/* WEP-104 */
632
		printf("wep104");
633
		break;
634
	case 6:	/* BIP */
635
		printf("bip");
636
		break;
637
	default:
638
		printf("%d", selector[3]);
639
		break;
640
	}
641
}
642
643
void
644
ieee80211_print_akm(uint8_t selector[4])
645
{
646
	if (memcmp(selector, MICROSOFT_OUI, 3) != 0 &&
647
	    memcmp(selector, IEEE80211_OUI, 3) != 0) {
648
		printf("0x%x%x%x%x", selector[0], selector[1], selector[2],
649
		     selector[3]);
650
	    	return;
651
	}
652
653
	switch (selector[3]) {
654
	case 1:
655
		printf("802.1x");
656
		break;
657
	case 2:
658
		printf("PSK");
659
		break;
660
	case 5:
661
		printf("SHA256-802.1x");
662
		break;
663
	case 6:
664
		printf("SHA256-PSK");
665
		break;
666
	default:
667
		printf("%d", selector[3]);
668
		break;
669
	}
670
}
671
672
/* Caller checks len */
673
void
674
ieee80211_print_rsn(u_int8_t *data, u_int len)
675
{
676
	uint16_t version, nciphers, nakms, rsncap, npmk;
677
	int i, j;
678
	uint8_t selector[4];
679
680
	if (len < 2) {
681
		ieee80211_print_element(data, len);
682
		return;
683
	}
684
685
	version = (data[0]) | (data[1] << 8);
686
	printf("=<version %d", version);
687
688
	if (len < 6) {
689
		printf(">");
690
		return;
691
	}
692
693
	data += 2;
694
	printf(",groupcipher ");
695
	for (i = 0; i < 4; i++)
696
		selector[i] = data[i];
697
	ieee80211_print_rsncipher(selector);
698
699
	if (len < 8) {
700
		printf(">");
701
		return;
702
	}
703
704
	data += 4;
705
	nciphers = (data[0]) | ((data[1]) << 8);
706
	data += 2;
707
708
	if (len < 8 + (nciphers * 4)) {
709
		printf(">");
710
		return;
711
	}
712
713
	printf(",cipher%s ", nciphers > 1 ? "s" : "");
714
	for (i = 0; i < nciphers; i++) {
715
		for (j = 0; j < 4; j++)
716
			selector[j] = data[i + j];
717
		ieee80211_print_rsncipher(selector);
718
		if (i < nciphers - 1)
719
			printf(" ");
720
		data += 4;
721
	}
722
723
	if (len < 8 + (nciphers * 4) + 2) {
724
		printf(">");
725
		return;
726
	}
727
728
	nakms = (data[0]) | ((data[1]) << 8);
729
	data += 2;
730
731
	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) {
732
		printf(">");
733
		return;
734
	}
735
736
	printf(",akm%s ", nakms > 1 ? "s" : "");
737
	for (i = 0; i < nciphers; i++) {
738
		for (j = 0; j < 4; j++)
739
			selector[j] = data[i + j];
740
		ieee80211_print_akm(selector);
741
		if (i < nciphers - 1)
742
			printf(" ");
743
		data += 4;
744
	}
745
746
	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) {
747
		printf(">");
748
		return;
749
	}
750
751
	rsncap = (data[0]) | ((data[1]) << 8);
752
	printf(",rsncap 0x%x", rsncap);
753
	data += 2;
754
755
	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) {
756
		printf(">");
757
		return;
758
	}
759
760
	npmk = (data[0]) | ((data[1]) << 8);
761
	data += 2;
762
763
	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
764
	    (npmk * IEEE80211_PMKID_LEN)) {
765
		printf(">");
766
		return;
767
	}
768
769
	if (npmk >= 1)
770
		printf(",pmkid%s ", npmk > 1 ? "s" : "");
771
	for (i = 0; i < npmk; i++) {
772
		printf("0x");
773
		for (j = 0; j < IEEE80211_PMKID_LEN; j++)
774
			printf("%x", data[i + j]);
775
		if (i < npmk - 1)
776
			printf(" ");
777
		data += IEEE80211_PMKID_LEN;
778
	}
779
780
	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
781
	    (npmk * IEEE80211_PMKID_LEN) + 4) {
782
		printf(">");
783
		return;
784
	}
785
786
	printf(",integrity-groupcipher ");
787
	for (i = 0; i < 4; i++)
788
		selector[i] = data[i];
789
	ieee80211_print_rsncipher(selector);
790
791
	printf(">");
792
}
793
794
int
795
ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len)
796
{
797
	uint64_t tstamp;
798
	uint16_t bintval, capinfo;
799
	uint8_t *frm;
800
801
	if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo))
802
		return 1; /* truncated */
803
804
	frm = (u_int8_t *)&wh[1];
805
806
	bcopy(frm, &tstamp, sizeof(u_int64_t));
807
	frm += 8;
808
	if (vflag > 1)
809
		printf(", timestamp %llu", letoh64(tstamp));
810
811
	bcopy(frm, &bintval, sizeof(u_int16_t));
812
	frm += 2;
813
	if (vflag > 1)
814
		printf(", interval %u", letoh16(bintval));
815
816
	bcopy(frm, &capinfo, sizeof(u_int16_t));
817
	frm += 2;
818
	if (vflag)
819
		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
820
821
	return ieee80211_print_elements(frm);
822
}
823
824
int
825
ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len)
826
{
827
	uint8_t subtype;
828
	uint16_t capinfo, lintval;
829
	uint8_t *frm;
830
831
	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
832
833
	if (len < sizeof(capinfo) + sizeof(lintval) +
834
	    (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ?
835
	    IEEE80211_ADDR_LEN : 0))
836
		return 1; /* truncated */
837
838
	frm = (u_int8_t *)&wh[1];
839
840
	bcopy(frm, &capinfo, sizeof(u_int16_t));
841
	frm += 2;
842
	if (vflag)
843
		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
844
845
	bcopy(frm, &lintval, sizeof(u_int16_t));
846
	frm += 2;
847
	if (vflag > 1)
848
		printf(", listen interval %u", letoh16(lintval));
849
850
	if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
851
		if (vflag)
852
			printf(", AP %s", etheraddr_string(frm));
853
		frm += IEEE80211_ADDR_LEN;
854
	}
855
856
	return ieee80211_print_elements(frm);
857
}
858
859
int
860
ieee80211_print_elements(uint8_t *frm)
861
{
862
	int i;
863
864
	while (TTEST2(*frm, 2)) {
865
		u_int len = frm[1];
866
		u_int8_t *data = frm + 2;
867
868
		if (!TTEST2(*data, len))
869
			break;
870
871
#define ELEM_CHECK(l)	if (len != l) goto trunc
872
873
		switch (*frm) {
874
		case IEEE80211_ELEMID_SSID:
875
			printf(", ssid");
876
			ieee80211_print_essid(data, len);
877
			break;
878
		case IEEE80211_ELEMID_RATES:
879
			printf(", rates");
880
			if (!vflag)
881
				break;
882
			for (i = len; i > 0; i--, data++)
883
				printf(" %uM%s",
884
				    (data[0] & IEEE80211_RATE_VAL) / 2,
885
				    (data[0] & IEEE80211_RATE_BASIC
886
				    ? "*" : ""));
887
			break;
888
		case IEEE80211_ELEMID_FHPARMS:
889
			ELEM_CHECK(5);
890
			printf(", fh (dwell %u, chan %u, index %u)",
891
			    (data[1] << 8) | data[0],
892
			    (data[2] - 1) * 80 + data[3],	/* FH_CHAN */
893
			    data[4]);
894
			break;
895
		case IEEE80211_ELEMID_DSPARMS:
896
			ELEM_CHECK(1);
897
			printf(", ds");
898
			if (vflag)
899
				printf(" (chan %u)", data[0]);
900
			break;
901
		case IEEE80211_ELEMID_CFPARMS:
902
			printf(", cf");
903
			if (vflag)
904
				ieee80211_print_element(data, len);
905
			break;
906
		case IEEE80211_ELEMID_TIM:
907
			printf(", tim");
908
			if (vflag)
909
				ieee80211_print_element(data, len);
910
			break;
911
		case IEEE80211_ELEMID_IBSSPARMS:
912
			printf(", ibss");
913
			if (vflag)
914
				ieee80211_print_element(data, len);
915
			break;
916
		case IEEE80211_ELEMID_COUNTRY:
917
			printf(", country");
918
			if (vflag)
919
				ieee80211_print_country(data, len);
920
			break;
921
		case IEEE80211_ELEMID_CHALLENGE:
922
			printf(", challenge");
923
			if (vflag)
924
				ieee80211_print_element(data, len);
925
			break;
926
		case IEEE80211_ELEMID_CSA:
927
			ELEM_CHECK(3);
928
			printf(", csa (chan %u count %u%s)", data[1], data[2],
929
			    (data[0] == 1) ? " noTX" : "");
930
			break;
931
		case IEEE80211_ELEMID_ERP:
932
			printf(", erp");
933
			if (vflag)
934
				ieee80211_print_element(data, len);
935
			break;
936
		case IEEE80211_ELEMID_RSN:
937
			printf(", rsn");
938
			if (vflag)
939
				ieee80211_print_rsn(data, len);
940
			break;
941
		case IEEE80211_ELEMID_XRATES:
942
			printf(", xrates");
943
			if (!vflag)
944
				break;
945
			for (i = len; i > 0; i--, data++)
946
				printf(" %uM",
947
				    (data[0] & IEEE80211_RATE_VAL) / 2);
948
			break;
949
		case IEEE80211_ELEMID_TPC_REPORT:
950
			printf(", tpcreport");
951
			if (vflag)
952
				ieee80211_print_element(data, len);
953
			break;
954
		case IEEE80211_ELEMID_TPC_REQUEST:
955
			printf(", tpcrequest");
956
			if (vflag)
957
				ieee80211_print_element(data, len);
958
			break;
959
		case IEEE80211_ELEMID_HTCAPS:
960
			printf(", htcaps");
961
			if (vflag)
962
				ieee80211_print_htcaps(data, len);
963
			break;
964
		case IEEE80211_ELEMID_HTOP:
965
			printf(", htop");
966
			if (vflag)
967
				ieee80211_print_htop(data, len);
968
			break;
969
		case IEEE80211_ELEMID_POWER_CONSTRAINT:
970
			ELEM_CHECK(1);
971
			printf(", power constraint %udB", data[0]);
972
			break;
973
		case IEEE80211_ELEMID_QBSS_LOAD:
974
			ELEM_CHECK(5);
975
			printf(", %u stations, %d%% utilization, "
976
			    "admission capacity %uus/s",
977
			    (data[0] | data[1] << 8),
978
			    (data[2] * 100) / 255,
979
			    (data[3] | data[4] << 8) / 32);
980
			break;
981
		case IEEE80211_ELEMID_VENDOR:
982
			printf(", vendor");
983
			if (vflag)
984
				ieee80211_print_element(data, len);
985
			break;
986
		default:
987
			printf(", %u:%u", (u_int) *frm, len);
988
			if (vflag)
989
				ieee80211_print_element(data, len);
990
			break;
991
		}
992
		frm += len + 2;
993
994
		if (frm >= snapend)
995
			break;
996
	}
997
998
#undef ELEM_CHECK
999
1000
	return (0);
1001
1002
 trunc:
1003
	/* Truncated elements in frame */
1004
	return (1);
1005
}
1006
1007
int
1008
ieee80211_frame(struct ieee80211_frame *wh, u_int len)
1009
{
1010
	u_int8_t subtype, type, *frm;
1011
1012
	TCARR(wh->i_fc);
1013
1014
	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1015
	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1016
1017
	frm = (u_int8_t *)&wh[1];
1018
1019
	if (vflag)
1020
		printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS);
1021
1022
	switch (type) {
1023
	case IEEE80211_FC0_TYPE_DATA:
1024
		printf(": %s: ", ieee80211_data_subtype_name[
1025
		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1026
		ieee80211_data(wh, len);
1027
		break;
1028
	case IEEE80211_FC0_TYPE_MGT:
1029
		printf(": %s", ieee80211_mgt_subtype_name[
1030
		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1031
		switch (subtype) {
1032
		case IEEE80211_FC0_SUBTYPE_BEACON:
1033
		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1034
			if (ieee80211_print_beacon(wh, len) != 0)
1035
				goto trunc;
1036
			break;
1037
		case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1038
		case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1039
			if (ieee80211_print_assocreq(wh, len) != 0)
1040
				goto trunc;
1041
			break;
1042
		case IEEE80211_FC0_SUBTYPE_AUTH:
1043
			TCHECK2(*frm, 2);		/* Auth Algorithm */
1044
			switch (IEEE80211_AUTH_ALGORITHM(frm)) {
1045
			case IEEE80211_AUTH_ALG_OPEN:
1046
				TCHECK2(*frm, 4);	/* Auth Transaction */
1047
				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
1048
				case IEEE80211_AUTH_OPEN_REQUEST:
1049
					printf(" request");
1050
					break;
1051
				case IEEE80211_AUTH_OPEN_RESPONSE:
1052
					printf(" response");
1053
					break;
1054
				}
1055
				break;
1056
			case IEEE80211_AUTH_ALG_SHARED:
1057
				TCHECK2(*frm, 4);	/* Auth Transaction */
1058
				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
1059
				case IEEE80211_AUTH_SHARED_REQUEST:
1060
					printf(" request");
1061
					break;
1062
				case IEEE80211_AUTH_SHARED_CHALLENGE:
1063
					printf(" challenge");
1064
					break;
1065
				case IEEE80211_AUTH_SHARED_RESPONSE:
1066
					printf(" response");
1067
					break;
1068
				case IEEE80211_AUTH_SHARED_PASS:
1069
					printf(" pass");
1070
					break;
1071
				}
1072
				break;
1073
			case IEEE80211_AUTH_ALG_LEAP:
1074
				printf(" (leap)");
1075
				break;
1076
			}
1077
			break;
1078
		case IEEE80211_FC0_SUBTYPE_DEAUTH:
1079
		case IEEE80211_FC0_SUBTYPE_DISASSOC:
1080
			TCHECK2(*frm, 2);		/* Reason Code */
1081
			ieee80211_reason(frm[0] | (frm[1] << 8));
1082
			break;
1083
		}
1084
		break;
1085
	case IEEE80211_FC0_TYPE_CTL: {
1086
		u_int8_t *t = (u_int8_t *) wh;
1087
1088
		printf(": %s", ieee80211_ctl_subtype_name[
1089
		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1090
		if (!vflag)
1091
			break;
1092
1093
		/* See 802.11 2012 "8.3.1 Control frames". */
1094
		t += 2; /* skip Frame Control */
1095
		switch (subtype) {
1096
		case IEEE80211_FC0_SUBTYPE_RTS:
1097
		case IEEE80211_FC0_SUBTYPE_BAR:
1098
		case IEEE80211_FC0_SUBTYPE_BA:
1099
			TCHECK2(*t, 2); /* Duration */
1100
			printf(", duration %dus", (t[0] | t[1] << 8));
1101
			t += 2;
1102
			TCHECK2(*t, 6); /* RA */
1103
			printf(", ra %s", etheraddr_string(t));
1104
			t += 6;
1105
			TCHECK2(*t, 6); /* TA */
1106
			printf(", ta %s", etheraddr_string(t));
1107
			if (subtype == IEEE80211_FC0_SUBTYPE_BAR ||
1108
			    subtype == IEEE80211_FC0_SUBTYPE_BA) {
1109
				u_int16_t ctrl;
1110
1111
				t += 6;
1112
				TCHECK2(*t, 2); /* BAR/BA control */
1113
				ctrl = t[0] | (t[1] << 8);
1114
				if (ctrl & IEEE80211_BA_ACK_POLICY)
1115
					printf(", no ack");
1116
				else
1117
					printf(", normal ack");
1118
				if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 &&
1119
				    (ctrl & IEEE80211_BA_COMPRESSED) == 0)
1120
					printf(", basic variant");
1121
				else if ((ctrl & IEEE80211_BA_MULTI_TID) &&
1122
				    (ctrl & IEEE80211_BA_COMPRESSED))
1123
					printf(", multi-tid variant");
1124
				else if (ctrl & IEEE80211_BA_COMPRESSED)
1125
					printf(", compressed variant");
1126
			}
1127
			break;
1128
		case IEEE80211_FC0_SUBTYPE_CTS:
1129
		case IEEE80211_FC0_SUBTYPE_ACK:
1130
			TCHECK2(*t, 2); /* Duration */
1131
			printf(", duration %dus", (t[0] | t[1] << 8));
1132
			t += 2;
1133
			TCHECK2(*t, 6); /* RA */
1134
			printf(", ra %s", etheraddr_string(t));
1135
			break;
1136
		case IEEE80211_FC0_SUBTYPE_PS_POLL:
1137
			TCHECK2(*t, 2); /* AID */
1138
			printf(", aid 0x%x", (t[0] | t[1] << 8));
1139
			t += 2;
1140
			TCHECK2(*t, 6); /* BSSID(RA) */
1141
			printf(", ra %s", etheraddr_string(t));
1142
			t += 6;
1143
			TCHECK2(*t, 6); /* TA */
1144
			printf(", ta %s", etheraddr_string(t));
1145
			break;
1146
		}
1147
		break;
1148
	}
1149
	default:
1150
		printf(": type#%d", type);
1151
		break;
1152
	}
1153
1154
	return (0);
1155
1156
 trunc:
1157
	/* Truncated 802.11 frame */
1158
	return (1);
1159
}
1160
1161
u_int
1162
ieee80211_any2ieee(u_int freq, u_int flags)
1163
{
1164
	if (flags & IEEE80211_CHAN_2GHZ) {
1165
		if (freq == 2484)
1166
			return 14;
1167
		if (freq < 2484)
1168
			return (freq - 2407) / 5;
1169
		else
1170
			return 15 + ((freq - 2512) / 20);
1171
	} else if (flags & IEEE80211_CHAN_5GHZ) {
1172
		return (freq - 5000) / 5;
1173
	} else {
1174
		/* Assume channel is already an IEEE number */
1175
		return (freq);
1176
	}
1177
}
1178
1179
int
1180
ieee80211_print(struct ieee80211_frame *wh, u_int len)
1181
{
1182
	if (eflag)
1183
		if (ieee80211_hdr(wh))
1184
			return (1);
1185
1186
	printf("802.11");
1187
1188
	return (ieee80211_frame(wh, len));
1189
}
1190
1191
void
1192
ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h,
1193
    const u_char *p)
1194
{
1195
	struct ieee80211_frame *wh = (struct ieee80211_frame*)p;
1196
1197
	if (!ieee80211_encap)
1198
		ts_print(&h->ts);
1199
1200
	packetp = p;
1201
	snapend = p + h->caplen;
1202
1203
	if (ieee80211_print(wh, (u_int)h->len) != 0)
1204
		printf("[|802.11]");
1205
1206
	if (!ieee80211_encap) {
1207
		if (xflag)
1208
			default_print(p, (u_int)h->len);
1209
		putchar('\n');
1210
	}
1211
}
1212
1213
void
1214
ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h,
1215
    const u_char *p)
1216
{
1217
	struct ieee80211_radiotap_header *rh =
1218
	    (struct ieee80211_radiotap_header*)p;
1219
	struct ieee80211_frame *wh;
1220
	u_int8_t *t;
1221
	u_int32_t present;
1222
	u_int len, rh_len;
1223
	u_int16_t tmp;
1224
1225
	if (!ieee80211_encap)
1226
		ts_print(&h->ts);
1227
1228
	packetp = p;
1229
	snapend = p + h->caplen;
1230
1231
	TCHECK(*rh);
1232
1233
	len = h->len;
1234
	rh_len = letoh16(rh->it_len);
1235
	if (rh->it_version != 0) {
1236
		printf("[?radiotap + 802.11 v:%u]", rh->it_version);
1237
		goto out;
1238
	}
1239
1240
	wh = (struct ieee80211_frame *)(p + rh_len);
1241
	if (len <= rh_len || ieee80211_print(wh, len - rh_len))
1242
		printf("[|802.11]");
1243
1244
	t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header);
1245
1246
	if ((present = letoh32(rh->it_present)) == 0)
1247
		goto out;
1248
1249
	printf(", <radiotap v%u", rh->it_version);
1250
1251
#define RADIOTAP(_x)	\
1252
	(present & (1 << IEEE80211_RADIOTAP_##_x))
1253
1254
	if (RADIOTAP(TSFT)) {
1255
		u_int64_t tsf;
1256
1257
		TCHECK2(*t, 8);
1258
		bcopy(t, &tsf, sizeof(u_int64_t));
1259
		if (vflag > 1)
1260
			printf(", tsf %llu", letoh64(tsf));
1261
		t += 8;
1262
	}
1263
1264
	if (RADIOTAP(FLAGS)) {
1265
		u_int8_t flags = *(u_int8_t*)t;
1266
		TCHECK2(*t, 1);
1267
1268
		if (flags & IEEE80211_RADIOTAP_F_CFP)
1269
			printf(", CFP");
1270
		if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
1271
			printf(", SHORTPRE");
1272
		if (flags & IEEE80211_RADIOTAP_F_WEP)
1273
			printf(", WEP");
1274
		if (flags & IEEE80211_RADIOTAP_F_FRAG)
1275
			printf(", FRAG");
1276
		t += 1;
1277
	}
1278
1279
	if (RADIOTAP(RATE)) {
1280
		TCHECK2(*t, 1);
1281
		if (vflag) {
1282
			uint8_t rate = *(u_int8_t*)t;
1283
			if (rate & 0x80)
1284
				printf(", MCS %u", rate & 0x7f);
1285
			else
1286
				printf(", %uMbit/s", rate / 2);
1287
		}
1288
		t += 1;
1289
	}
1290
1291
	if (RADIOTAP(CHANNEL)) {
1292
		u_int16_t freq, flags;
1293
		TCHECK2(*t, 2);
1294
1295
		bcopy(t, &freq, sizeof(u_int16_t));
1296
		freq = letoh16(freq);
1297
		t += 2;
1298
		TCHECK2(*t, 2);
1299
		bcopy(t, &flags, sizeof(u_int16_t));
1300
		flags = letoh16(flags);
1301
		t += 2;
1302
1303
		printf(", chan %u", ieee80211_any2ieee(freq, flags));
1304
1305
		if (flags & IEEE80211_CHAN_HT)
1306
			printf(", 11n");
1307
		else if (flags & IEEE80211_CHAN_DYN &&
1308
		    flags & IEEE80211_CHAN_2GHZ)
1309
			printf(", 11g");
1310
		else if (flags & IEEE80211_CHAN_CCK &&
1311
		    flags & IEEE80211_CHAN_2GHZ)
1312
			printf(", 11b");
1313
		else if (flags & IEEE80211_CHAN_OFDM &&
1314
		    flags & IEEE80211_CHAN_2GHZ)
1315
			printf(", 11G");
1316
		else if (flags & IEEE80211_CHAN_OFDM &&
1317
		    flags & IEEE80211_CHAN_5GHZ)
1318
			printf(", 11a");
1319
1320
		if (flags & IEEE80211_CHAN_XR)
1321
			printf(", XR");
1322
	}
1323
1324
	if (RADIOTAP(FHSS)) {
1325
		TCHECK2(*t, 2);
1326
		printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
1327
		t += 2;
1328
	}
1329
1330
	if (RADIOTAP(DBM_ANTSIGNAL)) {
1331
		TCHECK(*t);
1332
		printf(", sig %ddBm", *(int8_t*)t);
1333
		t += 1;
1334
	}
1335
1336
	if (RADIOTAP(DBM_ANTNOISE)) {
1337
		TCHECK(*t);
1338
		printf(", noise %ddBm", *(int8_t*)t);
1339
		t += 1;
1340
	}
1341
1342
	if (RADIOTAP(LOCK_QUALITY)) {
1343
		TCHECK2(*t, 2);
1344
		if (vflag) {
1345
			bcopy(t, &tmp, sizeof(u_int16_t));
1346
			printf(", quality %u", letoh16(tmp));
1347
		}
1348
		t += 2;
1349
	}
1350
1351
	if (RADIOTAP(TX_ATTENUATION)) {
1352
		TCHECK2(*t, 2);
1353
		if (vflag) {
1354
			bcopy(t, &tmp, sizeof(u_int16_t));
1355
			printf(", txatt %u", letoh16(tmp));
1356
		}
1357
		t += 2;
1358
	}
1359
1360
	if (RADIOTAP(DB_TX_ATTENUATION)) {
1361
		TCHECK2(*t, 2);
1362
		if (vflag) {
1363
			bcopy(t, &tmp, sizeof(u_int16_t));
1364
			printf(", txatt %udB", letoh16(tmp));
1365
		}
1366
		t += 2;
1367
	}
1368
1369
	if (RADIOTAP(DBM_TX_POWER)) {
1370
		TCHECK(*t);
1371
		printf(", txpower %ddBm", *(int8_t*)t);
1372
		t += 1;
1373
	}
1374
1375
	if (RADIOTAP(ANTENNA)) {
1376
		TCHECK(*t);
1377
		if (vflag)
1378
			printf(", antenna %u", *(u_int8_t*)t);
1379
		t += 1;
1380
	}
1381
1382
	if (RADIOTAP(DB_ANTSIGNAL)) {
1383
		TCHECK(*t);
1384
		printf(", signal %udB", *(u_int8_t*)t);
1385
		t += 1;
1386
	}
1387
1388
	if (RADIOTAP(DB_ANTNOISE)) {
1389
		TCHECK(*t);
1390
		printf(", noise %udB", *(u_int8_t*)t);
1391
		t += 1;
1392
	}
1393
1394
	if (RADIOTAP(FCS)) {
1395
		TCHECK2(*t, 4);
1396
		if (vflag) {
1397
			u_int32_t fcs;
1398
			bcopy(t, &fcs, sizeof(u_int32_t));
1399
			printf(", fcs %08x", letoh32(fcs));
1400
		}
1401
		t += 4;
1402
	}
1403
1404
	if (RADIOTAP(RSSI)) {
1405
		u_int8_t rssi, max_rssi;
1406
		TCHECK(*t);
1407
		rssi = *(u_int8_t*)t;
1408
		t += 1;
1409
		TCHECK(*t);
1410
		max_rssi = *(u_int8_t*)t;
1411
		t += 1;
1412
1413
		printf(", rssi %u/%u", rssi, max_rssi);
1414
	}
1415
1416
#undef RADIOTAP
1417
1418
	putchar('>');
1419
	goto out;
1420
1421
 trunc:
1422
	/* Truncated frame */
1423
	printf("[|radiotap + 802.11]");
1424
1425
 out:
1426
	if (!ieee80211_encap) {
1427
		if (xflag)
1428
			default_print(p, h->len);
1429
		putchar('\n');
1430
	}
1431
}
1432
1433
void
1434
ieee80211_reason(u_int16_t reason)
1435
{
1436
	if (!vflag)
1437
		return;
1438
1439
	switch (reason) {
1440
	case IEEE80211_REASON_UNSPECIFIED:
1441
		printf(", unspecified failure");
1442
		break;
1443
	case IEEE80211_REASON_AUTH_EXPIRE:
1444
		printf(", authentication expired");
1445
		break;
1446
	case IEEE80211_REASON_AUTH_LEAVE:
1447
		printf(", deauth - station left");
1448
		break;
1449
	case IEEE80211_REASON_ASSOC_EXPIRE:
1450
		printf(", association expired");
1451
		break;
1452
	case IEEE80211_REASON_ASSOC_TOOMANY:
1453
		printf(", too many associated stations");
1454
		break;
1455
	case IEEE80211_REASON_NOT_AUTHED:
1456
		printf(", not authenticated");
1457
		break;
1458
	case IEEE80211_REASON_NOT_ASSOCED:
1459
		printf(", not associated");
1460
		break;
1461
	case IEEE80211_REASON_ASSOC_LEAVE:
1462
		printf(", disassociated - station left");
1463
		break;
1464
	case IEEE80211_REASON_ASSOC_NOT_AUTHED:
1465
		printf(", association but not authenticated");
1466
		break;
1467
	case IEEE80211_REASON_RSN_REQUIRED:
1468
		printf(", rsn required");
1469
		break;
1470
	case IEEE80211_REASON_RSN_INCONSISTENT:
1471
		printf(", rsn inconsistent");
1472
		break;
1473
	case IEEE80211_REASON_IE_INVALID:
1474
		printf(", ie invalid");
1475
		break;
1476
	case IEEE80211_REASON_MIC_FAILURE:
1477
		printf(", mic failure");
1478
		break;
1479
	default:
1480
		printf(", unknown reason %u", reason);
1481
	}
1482
}