aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--capture_info.c4
-rw-r--r--epan/dissectors/packet-ieee80211.c21
-rw-r--r--epan/dissectors/packet-ieee80211.h1
-rw-r--r--epan/dissectors/packet-radiotap.c68
4 files changed, 76 insertions, 18 deletions
diff --git a/capture_info.c b/capture_info.c
index a385886295..d9bc8fbfcd 100644
--- a/capture_info.c
+++ b/capture_info.c
@@ -50,6 +50,7 @@
#include <epan/dissectors/packet-sll.h>
#include <epan/dissectors/packet-tr.h>
#include <epan/dissectors/packet-ieee80211.h>
+#include <epan/dissectors/packet-radiotap.h>
#include <epan/dissectors/packet-chdlc.h>
#include <epan/dissectors/packet-prism.h>
#include <epan/dissectors/packet-ipfc.h>
@@ -191,6 +192,9 @@ capture_info_packet(packet_counts *counts, gint wtap_linktype, const guchar *pd,
case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
capture_ieee80211(pd, 0, caplen, counts);
break;
+ case WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP:
+ capture_radiotap(pd, 0, caplen, counts);
+ break;
case WTAP_ENCAP_CHDLC:
capture_chdlc(pd, 0, caplen, counts);
break;
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index e872a904a6..fae0b430c9 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -739,7 +739,8 @@ find_header_length (guint16 fcf)
/* ************************************************************************* */
static void
capture_ieee80211_common (const guchar * pd, int offset, int len,
- packet_counts * ld, gboolean fixed_length_header)
+ packet_counts * ld, gboolean fixed_length_header,
+ gboolean datapad)
{
guint16 fcf, hdr_length;
@@ -748,7 +749,7 @@ capture_ieee80211_common (const guchar * pd, int offset, int len,
return;
}
- fcf = pletohs (&pd[0]);
+ fcf = pletohs (&pd[offset]);
if (IS_PROTECTED(FCF_FLAGS(fcf)))
{
@@ -768,6 +769,8 @@ capture_ieee80211_common (const guchar * pd, int offset, int len,
hdr_length = DATA_LONG_HDR_LEN;
else
hdr_length = find_header_length (fcf);
+ if (datapad)
+ hdr_length = roundup2(hdr_length, 4);
/* I guess some bridges take Netware Ethernet_802_3 frames,
which are 802.3 frames (with a length field rather than
a type field, but with no 802.2 header in the payload),
@@ -803,7 +806,17 @@ capture_ieee80211_common (const guchar * pd, int offset, int len,
void
capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
{
- capture_ieee80211_common (pd, offset, len, ld, FALSE);
+ capture_ieee80211_common (pd, offset, len, ld, FALSE, FALSE);
+}
+
+/*
+ * Handle 802.11 with a variable-length link-layer header and data padding.
+ */
+void
+capture_ieee80211_datapad (const guchar * pd, int offset, int len,
+ packet_counts * ld)
+{
+ capture_ieee80211_common (pd, offset, len, ld, FALSE, TRUE);
}
/*
@@ -813,7 +826,7 @@ capture_ieee80211 (const guchar * pd, int offset, int len, packet_counts * ld)
void
capture_ieee80211_fixed (const guchar * pd, int offset, int len, packet_counts * ld)
{
- capture_ieee80211_common (pd, offset, len, ld, TRUE);
+ capture_ieee80211_common (pd, offset, len, ld, TRUE, FALSE);
}
diff --git a/epan/dissectors/packet-ieee80211.h b/epan/dissectors/packet-ieee80211.h
index 6ab638d2c4..3760c76f6d 100644
--- a/epan/dissectors/packet-ieee80211.h
+++ b/epan/dissectors/packet-ieee80211.h
@@ -28,6 +28,7 @@
*/
void capture_ieee80211 (const guchar *, int, int, packet_counts *);
+void capture_ieee80211_datapad (const guchar *, int, int, packet_counts *);
void capture_ieee80211_fixed (const guchar *, int, int, packet_counts *);
void ieee_80211_add_tagged_parameters (tvbuff_t * tvb, int offset,
diff --git a/epan/dissectors/packet-radiotap.c b/epan/dissectors/packet-radiotap.c
index 24cf9870e6..84ff2db803 100644
--- a/epan/dissectors/packet-radiotap.c
+++ b/epan/dissectors/packet-radiotap.c
@@ -156,23 +156,75 @@ static dissector_handle_t ieee80211_datapad_handle;
static void
dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+#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)
+
void
capture_radiotap(const guchar *pd, int offset, int len, packet_counts *ld)
{
const struct ieee80211_radiotap_header *hdr;
+ guint16 it_len;
+ guint32 present;
+ guint8 rflags;
+ int rt_offset;
if(!BYTES_ARE_IN_FRAME(offset, len, (int)sizeof(*hdr))) {
ld->other ++;
return;
}
hdr = (const struct ieee80211_radiotap_header *)pd;
- if(!BYTES_ARE_IN_FRAME(offset, len, hdr->it_len)) {
+ it_len = pletohs(&hdr->it_len);
+ if(!BYTES_ARE_IN_FRAME(offset, len, it_len)) {
ld->other ++;
return;
}
+ if(it_len > len) {
+ /* Header length is bigger than total packet length */
+ ld->other ++;
+ return;
+ }
+
+ if(it_len < sizeof(*hdr)) {
+ /* Header length is shorter than fixed-length portion of header */
+ ld->other ++;
+ return;
+ }
+
+ present = pletohl(&hdr->it_present);
+ rt_offset = sizeof(*hdr);
+
+ rflags = 0;
+
+ /*
+ * IEEE80211_RADIOTAP_TSFT is the lowest-order bit.
+ */
+ if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
+ /* That field is present, and it's 8 bits long. */
+ rt_offset += 8;
+ }
+
+ /*
+ * IEEE80211_RADIOTAP_FLAGS is the next bit.
+ */
+ if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
+ /* That field is present; fetch it. */
+ if(!BYTES_ARE_IN_FRAME(rt_offset, len, 1)) {
+ ld->other ++;
+ return;
+ }
+ rflags = pd[rt_offset];
+ }
+
/* 802.11 header follows */
- capture_ieee80211(pd, offset + hdr->it_len, len, ld);
+ if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
+ capture_ieee80211_datapad(pd, offset + it_len, len, ld);
+ else
+ capture_ieee80211(pd, offset + it_len, len, ld);
}
void
@@ -314,12 +366,6 @@ ieee80211_mhz2ieee(int freq, int flags)
static void
dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-#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)
proto_tree *radiotap_tree = NULL;
proto_tree *pt, *present_tree;
proto_item *ti;
@@ -507,12 +553,6 @@ dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
call_dissector((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ?
ieee80211_datapad_handle : ieee80211_handle,
tvb_new_subset(tvb, length, -1, -1), pinfo, tree);
-#undef BITNO_32
-#undef BITNO_16
-#undef BITNO_8
-#undef BITNO_4
-#undef BITNO_2
-#undef BIT
}
void