diff options
| author | guy <guy> | 2007-07-22 23:14:14 +0000 |
|---|---|---|
| committer | guy <guy> | 2007-07-22 23:14:14 +0000 |
| commit | eeca6a6c30e3f64e09d1470bfd2ea12972a17fb8 (patch) | |
| tree | c8c1ed46dfa8739ba8ef17351f337d8577a0d761 | |
| parent | 1e201ad0609a8b908662067aa5de2603adc485c1 (diff) | |
| download | tcpdump-eeca6a6c30e3f64e09d1470bfd2ea12972a17fb8.tar.gz | |
Handle the padding that Atheros adapters helpfully introduce between the
802.2 header and the body.
| -rw-r--r-- | print-802_11.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/print-802_11.c b/print-802_11.c index 0f6f5d33..70124a70 100644 --- a/print-802_11.c +++ b/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.31.2.14 2007-07-22 22:01:05 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.31.2.15 2007-07-22 23:14:14 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -906,8 +906,12 @@ ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, } } +#ifndef roundup2 +#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ +#endif + static u_int -ieee802_11_print(const u_char *p, u_int length, u_int caplen) +ieee802_11_print(const u_char *p, u_int length, u_int caplen, int pad) { u_int16_t fc; u_int hdrlen; @@ -921,6 +925,8 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen) fc = EXTRACT_LE_16BITS(p); hdrlen = extract_header_length(fc); + if (pad) + hdrlen = roundup2(hdrlen, 4); if (caplen < hdrlen) { printf("[|802.11]"); @@ -993,11 +999,11 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen) u_int ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p) { - return ieee802_11_print(p, h->len, h->caplen); + return ieee802_11_print(p, h->len, h->caplen, 0); } static int -print_radiotap_field(struct cpack_state *s, u_int32_t bit) +print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad) { union { int8_t i8; @@ -1011,6 +1017,10 @@ print_radiotap_field(struct cpack_state *s, u_int32_t bit) switch (bit) { case IEEE80211_RADIOTAP_FLAGS: + rc = cpack_uint8(s, &u.u8); + if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD) + *pad = 1; + break; case IEEE80211_RADIOTAP_RATE: case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: @@ -1133,6 +1143,7 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) int bit0; const u_char *iter; u_int len; + int pad; if (caplen < sizeof(*hdr)) { printf("[|802.11]"); @@ -1166,6 +1177,8 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) return caplen; } + /* Assume no Atheros padding between 802.11 header and body */ + pad = 0; for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; presentp++, bit0 += 32) { for (present = EXTRACT_LE_32BITS(presentp); present; @@ -1177,12 +1190,12 @@ ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) bit = (enum ieee80211_radiotap_type) (bit0 + BITNO_32(present ^ next_present)); - if (print_radiotap_field(&cpacker, bit) != 0) + if (print_radiotap_field(&cpacker, bit, &pad) != 0) goto out; } } out: - return len + ieee802_11_print(p + len, length - len, caplen - len); + return len + ieee802_11_print(p + len, length - len, caplen - len, pad); #undef BITNO_32 #undef BITNO_16 #undef BITNO_8 @@ -1213,7 +1226,7 @@ ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen) } return caphdr_len + ieee802_11_print(p + caphdr_len, - length - caphdr_len, caplen - caphdr_len); + length - caphdr_len, caplen - caphdr_len, 0); } #define PRISM_HDR_LEN 144 @@ -1252,7 +1265,7 @@ prism_if_print(const struct pcap_pkthdr *h, const u_char *p) } return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN, - length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN); + length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0); } /* |
