o add minimal radiotap support for 11n
This commit is contained in:
parent
9fca1df981
commit
860e02a293
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* @(#) $Header: /tcpdump/master/tcpdump/ieee802_11.h,v 1.9 2003/07/22 17:36:57 guy Exp $ (LBL) */
|
||||
/*
|
||||
* Copyright (c) 2001
|
||||
@ -30,6 +31,7 @@
|
||||
#define IEEE802_11_RA_LEN 6
|
||||
#define IEEE802_11_TA_LEN 6
|
||||
#define IEEE802_11_SEQ_LEN 2
|
||||
#define IEEE802_11_CTL_LEN 2
|
||||
#define IEEE802_11_IV_LEN 3
|
||||
#define IEEE802_11_KID_LEN 1
|
||||
|
||||
@ -72,6 +74,7 @@
|
||||
/* RESERVED 0xF */
|
||||
|
||||
|
||||
#define CTRL_BAR 0x8
|
||||
#define CTRL_PS_POLL 0xA
|
||||
#define CTRL_RTS 0xB
|
||||
#define CTRL_CTS 0xC
|
||||
@ -280,6 +283,20 @@ struct ctrl_end_ack_t {
|
||||
#define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
|
||||
IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
|
||||
|
||||
struct ctrl_bar_t {
|
||||
u_int16_t fc;
|
||||
u_int16_t dur;
|
||||
u_int8_t ra[6];
|
||||
u_int8_t ta[6];
|
||||
u_int16_t ctl;
|
||||
u_int16_t seq;
|
||||
u_int8_t fcs[4];
|
||||
};
|
||||
|
||||
#define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
|
||||
IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\
|
||||
IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN)
|
||||
|
||||
#define IV_IV(iv) ((iv) & 0xFFFFFF)
|
||||
#define IV_PAD(iv) (((iv) >> 24) & 0x3F)
|
||||
#define IV_KEYID(iv) (((iv) >> 30) & 0x03)
|
||||
|
@ -53,7 +53,11 @@
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/* The radio capture header precedes the 802.11 header. */
|
||||
/*
|
||||
* The radio capture header precedes the 802.11 header.
|
||||
*
|
||||
* Note well: all radiotap fields are little-endian.
|
||||
*/
|
||||
struct ieee80211_radiotap_header {
|
||||
u_int8_t it_version; /* Version 0. Only increases
|
||||
* for drastic changes,
|
||||
@ -87,15 +91,19 @@ struct ieee80211_radiotap_header {
|
||||
* IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap
|
||||
*
|
||||
* Tx/Rx frequency in MHz, followed by flags (see below).
|
||||
* Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
|
||||
* represent an HT channel as there is not enough room in
|
||||
* the flags word.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_FHSS u_int16_t see below
|
||||
*
|
||||
* For frequency-hopping radios, the hop set (first byte)
|
||||
* and pattern (second byte).
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s
|
||||
* IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s or index
|
||||
*
|
||||
* Tx/Rx data rate
|
||||
* Tx/Rx data rate. If bit 0x80 is set then it represents an
|
||||
* an MCS index and not an IEEE rate.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
|
||||
* one milliwatt (dBm)
|
||||
@ -154,6 +162,17 @@ struct ieee80211_radiotap_header {
|
||||
*
|
||||
* Unitless indication of the Rx/Tx antenna for this packet.
|
||||
* The first antenna is antenna 0.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_XCHANNEL u_int32_t bitmap
|
||||
* u_int16_t MHz
|
||||
* u_int8_t channel number
|
||||
* u_int8_t .5 dBm
|
||||
*
|
||||
* Extended channel specification: flags (see below) followed by
|
||||
* frequency in MHz, the corresponding IEEE channel number, and
|
||||
* finally the maximum regulatory transmit power cap in .5 dBm
|
||||
* units. This property supersedes IEEE80211_RADIOTAP_CHANNEL
|
||||
* and only one of the two should be present.
|
||||
*/
|
||||
enum ieee80211_radiotap_type {
|
||||
IEEE80211_RADIOTAP_TSFT = 0,
|
||||
@ -170,17 +189,27 @@ enum ieee80211_radiotap_type {
|
||||
IEEE80211_RADIOTAP_ANTENNA = 11,
|
||||
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
|
||||
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
|
||||
IEEE80211_RADIOTAP_XCHANNEL = 14,
|
||||
IEEE80211_RADIOTAP_EXT = 31
|
||||
};
|
||||
|
||||
#ifndef _KERNEL
|
||||
/* Channel flags. */
|
||||
#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
|
||||
#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
|
||||
#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
|
||||
#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
|
||||
#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
|
||||
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
|
||||
/* Channel flags; some are used only with XCHANNEL */
|
||||
#define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */
|
||||
#define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */
|
||||
#define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */
|
||||
#define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */
|
||||
#define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */
|
||||
#define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */
|
||||
#define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */
|
||||
#define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */
|
||||
#define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */
|
||||
#define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */
|
||||
#define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */
|
||||
#define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */
|
||||
#define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */
|
||||
#define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */
|
||||
#define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
/* For IEEE80211_RADIOTAP_FLAGS */
|
||||
@ -197,5 +226,11 @@ enum ieee80211_radiotap_type {
|
||||
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
|
||||
* with fragmentation
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
|
||||
#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
|
||||
* 802.11 header and payload
|
||||
* (to 32-bit boundary)
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */
|
||||
|
||||
#endif /* _NET_IF_IEEE80211RADIOTAP_H_ */
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2001
|
||||
* Fortress Technologies, Inc. All rights reserved.
|
||||
@ -61,6 +62,27 @@ do { \
|
||||
printf(" Mbit]"); \
|
||||
} while (0)
|
||||
|
||||
static const int ieee80211_htrates[16] = {
|
||||
13, /* IFM_IEEE80211_MCS0 */
|
||||
26, /* IFM_IEEE80211_MCS1 */
|
||||
39, /* IFM_IEEE80211_MCS2 */
|
||||
52, /* IFM_IEEE80211_MCS3 */
|
||||
78, /* IFM_IEEE80211_MCS4 */
|
||||
104, /* IFM_IEEE80211_MCS5 */
|
||||
117, /* IFM_IEEE80211_MCS6 */
|
||||
130, /* IFM_IEEE80211_MCS7 */
|
||||
26, /* IFM_IEEE80211_MCS8 */
|
||||
52, /* IFM_IEEE80211_MCS9 */
|
||||
78, /* IFM_IEEE80211_MCS10 */
|
||||
104, /* IFM_IEEE80211_MCS11 */
|
||||
156, /* IFM_IEEE80211_MCS12 */
|
||||
208, /* IFM_IEEE80211_MCS13 */
|
||||
234, /* IFM_IEEE80211_MCS14 */
|
||||
260, /* IFM_IEEE80211_MCS15 */
|
||||
};
|
||||
#define PRINT_HT_RATE(_sep, _r, _suf) \
|
||||
printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf)
|
||||
|
||||
static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
|
||||
#define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
|
||||
|
||||
@ -553,6 +575,17 @@ static int
|
||||
ctrl_body_print(u_int16_t fc, const u_char *p)
|
||||
{
|
||||
switch (FC_SUBTYPE(fc)) {
|
||||
case CTRL_BAR:
|
||||
printf("BAR");
|
||||
if (!TTEST2(*p, CTRL_BAR_HDRLEN))
|
||||
return 0;
|
||||
if (!eflag)
|
||||
printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
|
||||
etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
|
||||
etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
|
||||
EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
|
||||
EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
|
||||
break;
|
||||
case CTRL_PS_POLL:
|
||||
printf("Power Save-Poll");
|
||||
if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
|
||||
@ -725,6 +758,13 @@ ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
|
||||
return;
|
||||
|
||||
switch (FC_SUBTYPE(fc)) {
|
||||
case CTRL_BAR:
|
||||
printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
|
||||
etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
|
||||
etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
|
||||
EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
|
||||
EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
|
||||
break;
|
||||
case CTRL_PS_POLL:
|
||||
printf("BSSID:%s TA:%s ",
|
||||
etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
|
||||
@ -767,6 +807,8 @@ extract_header_length(u_int16_t fc)
|
||||
return MGMT_HDRLEN;
|
||||
case T_CTRL:
|
||||
switch (FC_SUBTYPE(fc)) {
|
||||
case CTRL_BAR:
|
||||
return CTRL_BAR_HDRLEN;
|
||||
case CTRL_PS_POLL:
|
||||
return CTRL_PS_POLL_HDRLEN;
|
||||
case CTRL_RTS:
|
||||
@ -925,6 +967,64 @@ ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
|
||||
return ieee802_11_print(p, h->len, h->caplen);
|
||||
}
|
||||
|
||||
#define IEEE80211_CHAN_FHSS \
|
||||
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
|
||||
#define IEEE80211_CHAN_A \
|
||||
(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
|
||||
#define IEEE80211_CHAN_B \
|
||||
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
|
||||
#define IEEE80211_CHAN_PUREG \
|
||||
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
|
||||
#define IEEE80211_CHAN_G \
|
||||
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
|
||||
|
||||
#define IS_CHAN_FHSS(flags) \
|
||||
((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
|
||||
#define IS_CHAN_A(flags) \
|
||||
((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
|
||||
#define IS_CHAN_B(flags) \
|
||||
((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
|
||||
#define IS_CHAN_PUREG(flags) \
|
||||
((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
|
||||
#define IS_CHAN_G(flags) \
|
||||
((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
|
||||
#define IS_CHAN_ANYG(flags) \
|
||||
(IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
|
||||
|
||||
static void
|
||||
print_chaninfo(int freq, int flags)
|
||||
{
|
||||
printf("%u MHz", freq);
|
||||
if (IS_CHAN_FHSS(flags))
|
||||
printf(" FHSS");
|
||||
if (IS_CHAN_A(flags)) {
|
||||
if (flags & IEEE80211_CHAN_HALF)
|
||||
printf(" 11a/10Mhz");
|
||||
else if (flags & IEEE80211_CHAN_QUARTER)
|
||||
printf(" 11a/5Mhz");
|
||||
else
|
||||
printf(" 11a");
|
||||
}
|
||||
if (IS_CHAN_ANYG(flags)) {
|
||||
if (flags & IEEE80211_CHAN_HALF)
|
||||
printf(" 11g/10Mhz");
|
||||
else if (flags & IEEE80211_CHAN_QUARTER)
|
||||
printf(" 11g/5Mhz");
|
||||
else
|
||||
printf(" 11g");
|
||||
} else if (IS_CHAN_B(flags))
|
||||
printf(" 11b");
|
||||
if (flags & IEEE80211_CHAN_TURBO)
|
||||
printf(" Turbo");
|
||||
if (flags & IEEE80211_CHAN_HT20)
|
||||
printf(" ht/20");
|
||||
else if (flags & IEEE80211_CHAN_HT40D)
|
||||
printf(" ht/40-");
|
||||
else if (flags & IEEE80211_CHAN_HT40U)
|
||||
printf(" ht/40+");
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static int
|
||||
print_radiotap_field(struct cpack_state *s, u_int32_t bit)
|
||||
{
|
||||
@ -935,7 +1035,7 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit)
|
||||
u_int16_t u16;
|
||||
u_int32_t u32;
|
||||
u_int64_t u64;
|
||||
} u, u2;
|
||||
} u, u2, u3, u4;
|
||||
int rc;
|
||||
|
||||
switch (bit) {
|
||||
@ -970,6 +1070,18 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit)
|
||||
case IEEE80211_RADIOTAP_TSFT:
|
||||
rc = cpack_uint64(s, &u.u64);
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_XCHANNEL:
|
||||
rc = cpack_uint32(s, &u.u32);
|
||||
if (rc != 0)
|
||||
break;
|
||||
rc = cpack_uint16(s, &u2.u16);
|
||||
if (rc != 0)
|
||||
break;
|
||||
rc = cpack_uint8(s, &u3.u8);
|
||||
if (rc != 0)
|
||||
break;
|
||||
rc = cpack_uint8(s, &u4.u8);
|
||||
break;
|
||||
default:
|
||||
/* this bit indicates a field whose
|
||||
* size we do not know, so we cannot
|
||||
@ -986,15 +1098,16 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit)
|
||||
|
||||
switch (bit) {
|
||||
case IEEE80211_RADIOTAP_CHANNEL:
|
||||
printf("%u MHz ", u.u16);
|
||||
if (u2.u16 != 0)
|
||||
printf("(0x%04x) ", u2.u16);
|
||||
print_chaninfo(u.u16, u2.u16);
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_FHSS:
|
||||
printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_RATE:
|
||||
PRINT_RATE("", u.u8, " Mb/s ");
|
||||
if (u.u8 & 0x80)
|
||||
PRINT_RATE("", u.u8, " Mb/s ");
|
||||
else
|
||||
PRINT_HT_RATE("", u.u8, " Mb/s ");
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
|
||||
printf("%ddB signal ", u.i8);
|
||||
@ -1029,6 +1142,14 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit)
|
||||
printf("wep ");
|
||||
if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
|
||||
printf("fragmented ");
|
||||
#if 0
|
||||
if (u.u8 & IEEE80211_RADIOTAP_F_FCS)
|
||||
printf("fcs ");
|
||||
if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD)
|
||||
printf("datapad ");
|
||||
#endif
|
||||
if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
|
||||
printf("badfcs ");
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_ANTENNA:
|
||||
printf("antenna %d ", u.u8);
|
||||
@ -1036,6 +1157,9 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit)
|
||||
case IEEE80211_RADIOTAP_TSFT:
|
||||
printf("%" PRIu64 "us tsft ", u.u64);
|
||||
break;
|
||||
case IEEE80211_RADIOTAP_XCHANNEL:
|
||||
print_chaninfo(u2.u16, u.u32);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user