aboutsummaryrefslogtreecommitdiff
path: root/contrib/tcpdump/print-802_11.c
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2005-05-29 18:17:16 +0000
committerSam Leffler <sam@FreeBSD.org>2005-05-29 18:17:16 +0000
commit1de50e9f417616cf647a842762944a2301cb1415 (patch)
treed59cebde657eda0af31fdab513367f5ad61113cd /contrib/tcpdump/print-802_11.c
parent5b0fe47811aa43b75fc69dbf7338cace232a4d48 (diff)
downloadsrc-1de50e9f417616cf647a842762944a2301cb1415.tar.gz
src-1de50e9f417616cf647a842762944a2301cb1415.zip
Virgin import of tcpdump v3.9.1 (alpha 096) from tcpdump.org
Notes
Notes: svn path=/vendor/tcpdump/dist/; revision=146773
Diffstat (limited to 'contrib/tcpdump/print-802_11.c')
-rw-r--r--contrib/tcpdump/print-802_11.c207
1 files changed, 202 insertions, 5 deletions
diff --git a/contrib/tcpdump/print-802_11.c b/contrib/tcpdump/print-802_11.c
index 56462c9448c4..c4c0ac8b1376 100644
--- a/contrib/tcpdump/print-802_11.c
+++ b/contrib/tcpdump/print-802_11.c
@@ -22,7 +22,7 @@
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.22.2.6 2003/12/10 09:52:33 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.31 2004/11/04 07:35:53 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -41,15 +41,20 @@ static const char rcsid[] _U_ =
#include "extract.h"
+#include "cpack.h"
+
#include "ieee802_11.h"
+#include "ieee802_11_radio.h"
+#define PRINT_RATE(_sep, _r, _suf) \
+ printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
#define PRINT_RATES(p) \
do { \
int z; \
const char *sep = " ["; \
for (z = 0; z < p.rates.length ; z++) { \
- printf("%s%2.1f", sep, (.5 * (p.rates.rate[z] & 0x7f))); \
- if (p.rates.rate[z] & 0x80) printf("*"); \
+ PRINT_RATE(sep, p.rates.rate[z], \
+ (p.rates.rate[z] & 0x80 ? "*" : "")); \
sep = " "; \
} \
if (p.rates.length != 0) \
@@ -910,7 +915,7 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen)
/*
* This is the top level routine of the printer. 'p' points
* to the 802.11 header of the packet, 'h->ts' is the timestamp,
- * 'h->length' is the length of the packet off the wire, and 'h->caplen'
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
* is the number of bytes actually captured.
*/
u_int
@@ -919,9 +924,201 @@ ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
return ieee802_11_print(p, h->len, h->caplen);
}
+static int
+print_radiotap_field(struct cpack_state *s, u_int32_t bit)
+{
+ union {
+ int8_t i8;
+ u_int8_t u8;
+ int16_t i16;
+ u_int16_t u16;
+ u_int32_t u32;
+ u_int64_t u64;
+ } u, u2;
+ int rc;
+
+ switch (bit) {
+ case IEEE80211_RADIOTAP_FLAGS:
+ case IEEE80211_RADIOTAP_RATE:
+ case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+ case IEEE80211_RADIOTAP_DB_ANTNOISE:
+ case IEEE80211_RADIOTAP_ANTENNA:
+ rc = cpack_uint8(s, &u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+ case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+ rc = cpack_int8(s, &u.i8);
+ break;
+ case IEEE80211_RADIOTAP_CHANNEL:
+ rc = cpack_uint16(s, &u.u16);
+ if (rc != 0)
+ break;
+ rc = cpack_uint16(s, &u2.u16);
+ break;
+ case IEEE80211_RADIOTAP_FHSS:
+ case IEEE80211_RADIOTAP_LOCK_QUALITY:
+ case IEEE80211_RADIOTAP_TX_ATTENUATION:
+ rc = cpack_uint16(s, &u.u16);
+ break;
+ case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
+ rc = cpack_uint8(s, &u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_TX_POWER:
+ rc = cpack_int8(s, &u.i8);
+ break;
+ case IEEE80211_RADIOTAP_TSFT:
+ rc = cpack_uint64(s, &u.u64);
+ break;
+ default:
+ /* this bit indicates a field whose
+ * size we do not know, so we cannot
+ * proceed.
+ */
+ printf("[0x%08x] ", bit);
+ return -1;
+ }
+
+ if (rc != 0) {
+ printf("[|802.11]");
+ return rc;
+ }
+
+ switch (bit) {
+ case IEEE80211_RADIOTAP_CHANNEL:
+ printf("%u MHz ", u.u16);
+ if (u2.u16 != 0)
+ printf("(0x%04x) ", 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 ");
+ break;
+ case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+ printf("%ddB signal ", u.i8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+ printf("%ddB noise ", u.i8);
+ break;
+ case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+ printf("%ddB signal ", u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DB_ANTNOISE:
+ printf("%ddB noise ", u.u8);
+ break;
+ case IEEE80211_RADIOTAP_LOCK_QUALITY:
+ printf("%u sq ", u.u16);
+ break;
+ case IEEE80211_RADIOTAP_TX_ATTENUATION:
+ printf("%d tx power ", -(int)u.u16);
+ break;
+ case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
+ printf("%ddB tx power ", -(int)u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_TX_POWER:
+ printf("%ddBm tx power ", u.i8);
+ break;
+ case IEEE80211_RADIOTAP_FLAGS:
+ if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
+ printf("cfp ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
+ printf("short preamble ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
+ printf("wep ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
+ printf("fragmented ");
+ break;
+ case IEEE80211_RADIOTAP_ANTENNA:
+ printf("antenna %d ", u.u8);
+ break;
+ case IEEE80211_RADIOTAP_TSFT:
+ printf("%" PRIu64 "us tsft ", u.u64);
+ break;
+ }
+ return 0;
+}
+
static u_int
ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
{
+#define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
+#define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
+#define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
+#define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
+#define BITNO_2(x) (((x) & 2) ? 1 : 0)
+#define BIT(n) (1 << n)
+#define IS_EXTENDED(__p) \
+ (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
+
+ struct cpack_state cpacker;
+ struct ieee80211_radiotap_header *hdr;
+ u_int32_t present, next_present;
+ u_int32_t *presentp, *last_presentp;
+ enum ieee80211_radiotap_type bit;
+ int bit0;
+ const u_char *iter;
+ u_int len;
+
+ if (caplen < sizeof(*hdr)) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ hdr = (struct ieee80211_radiotap_header *)p;
+
+ len = EXTRACT_LE_16BITS(&hdr->it_len);
+
+ if (caplen < len) {
+ printf("[|802.11]");
+ return caplen;
+ }
+ for (last_presentp = &hdr->it_present;
+ IS_EXTENDED(last_presentp) &&
+ (u_char*)(last_presentp + 1) <= p + len;
+ last_presentp++);
+
+ /* are there more bitmap extensions than bytes in header? */
+ if (IS_EXTENDED(last_presentp)) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ iter = (u_char*)(last_presentp + 1);
+
+ if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
+ /* XXX */
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
+ presentp++, bit0 += 32) {
+ for (present = EXTRACT_LE_32BITS(presentp); present;
+ present = next_present) {
+ /* clear the least significant bit that is set */
+ next_present = present & (present - 1);
+
+ /* extract the least significant bit that is set */
+ bit = bit0 + BITNO_32(present ^ next_present);
+
+ if (print_radiotap_field(&cpacker, bit) != 0)
+ goto out;
+ }
+ }
+out:
+ return len + ieee802_11_print(p + len, length - len, caplen - len);
+#undef BITNO_32
+#undef BITNO_16
+#undef BITNO_8
+#undef BITNO_4
+#undef BITNO_2
+#undef BIT
+}
+
+static u_int
+ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
+{
u_int32_t caphdr_len;
caphdr_len = EXTRACT_32BITS(p + 4);
@@ -972,7 +1169,7 @@ prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
}
if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
- return ieee802_11_radio_print(p, length, caplen);
+ return ieee802_11_avs_radio_print(p, length, caplen);
if (caplen < PRISM_HDR_LEN) {
printf("[|802.11]");