Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 May 2007 16:37:29 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 119571 for review
Message-ID:  <200705091637.l49GbTAS003507@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=119571

Change 119571 by sam@sam_ebb on 2007/05/09 16:36:55

	update radiotap support and add 11n

Affected files ...

.. //depot/projects/wifi/contrib/tcpdump/ieee802_11.h#2 edit
.. //depot/projects/wifi/contrib/tcpdump/ieee802_11_radio.h#2 edit
.. //depot/projects/wifi/contrib/tcpdump/print-802_11.c#4 edit

Differences ...

==== //depot/projects/wifi/contrib/tcpdump/ieee802_11.h#2 (text+ko) ====

@@ -30,6 +30,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 +73,7 @@
 /* RESERVED 			0xF  */
 
 
+#define	CTRL_BAR	0x8
 #define	CTRL_PS_POLL	0xA
 #define	CTRL_RTS	0xB
 #define	CTRL_CTS	0xC
@@ -280,6 +282,20 @@
 #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)

==== //depot/projects/wifi/contrib/tcpdump/ieee802_11_radio.h#2 (text+ko) ====

@@ -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 @@
  * 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 @@
  *
  *      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 @@
 	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 @@
 #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_ */

==== //depot/projects/wifi/contrib/tcpdump/print-802_11.c#4 (text+ko) ====

@@ -61,6 +61,27 @@
 		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 +574,17 @@
 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 +757,13 @@
 		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 +806,8 @@
 		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 +966,64 @@
 	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 +1034,7 @@
 		u_int16_t	u16;
 		u_int32_t	u32;
 		u_int64_t	u64;
-	} u, u2;
+	} u, u2, u3, u4;
 	int rc;
 
 	switch (bit) {
@@ -970,6 +1069,18 @@
 	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 +1097,16 @@
 
 	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 +1141,14 @@
 			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 +1156,9 @@
 	case IEEE80211_RADIOTAP_TSFT:
 		printf("%" PRIu64 "us tsft ", u.u64);
 		break;
+	case IEEE80211_RADIOTAP_XCHANNEL:
+		print_chaninfo(u2.u16, u.u32);
+		break;
 	}
 	return 0;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705091637.l49GbTAS003507>