aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-11-12 19:38:12 -0800
committerGuy Harris <guy@alum.mit.edu>2018-11-13 03:38:58 +0000
commitc348dd4b106621f85079ebaf8202229c689ea93b (patch)
treef65a4fcb71ed0be57edb909791b3cc869e2cf54f /epan
parent3faa45d4ec9214fbe4b15c3b6d9bc875f8fb780c (diff)
Fix dissection of 802.11+radiotap frames in Linux "cooked" captures.
Those frames *don't* have their link-layer headers stripped, even on PF_PACKET/SOCK_DGRAM captures (hopefully, nobody will consider that a bug and "fix" it). The "hatype" field is the ARPHRD_ value for the adapter, as returned by SIOCGIFHWADDR; in monitor mode, those frames will have an hatype of ARPHRD_IEEE80211_RADIOTAP. Add an "sll.hatype" dissector table, which we check before checking the "sll.ltype" dissector table, and have the radiotap dissector register in that table. We still use the special hack for an hatype of ARPHRD_NETLINK, because, for *those* frames, the "protocol" field of the nominal SLL header is the netlink family, not an Ethertype or anything else that the SLL dissector would handle. Change-Id: If503a7daa9133adf1b8c330ec28c4c824d4f551d Reviewed-on: https://code.wireshark.org/review/30592 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-ieee80211-radiotap.c9
-rw-r--r--epan/dissectors/packet-sll.c61
-rw-r--r--epan/dissectors/packet-sll.h13
3 files changed, 67 insertions, 16 deletions
diff --git a/epan/dissectors/packet-ieee80211-radiotap.c b/epan/dissectors/packet-ieee80211-radiotap.c
index ec165b560c..8a3ed8ab7e 100644
--- a/epan/dissectors/packet-ieee80211-radiotap.c
+++ b/epan/dissectors/packet-ieee80211-radiotap.c
@@ -26,6 +26,7 @@
#include <epan/expert.h>
#include "packet-ieee80211.h"
#include "packet-ieee80211-radiotap-iter.h"
+#include "packet-sll.h"
void proto_register_radiotap(void);
void proto_reg_handoff_radiotap(void);
@@ -4437,6 +4438,14 @@ void proto_reg_handoff_radiotap(void)
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_RADIOTAP,
radiotap_handle);
+ /*
+ * The radiotap and 802.11 headers aren't stripped off for
+ * monitor-mode packets in Linux cooked captures, so dissect
+ * those frames.
+ */
+ dissector_add_uint("sll.hatype", LINUX_SLL_ARPHRD_IEEE80211_RADIOTAP,
+ radiotap_handle);
+
radiotap_cap_handle = create_capture_dissector_handle(capture_radiotap, proto_radiotap);
capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_RADIOTAP, radiotap_cap_handle);
diff --git a/epan/dissectors/packet-sll.c b/epan/dissectors/packet-sll.c
index c5f560df65..9d6af1e4a1 100644
--- a/epan/dissectors/packet-sll.c
+++ b/epan/dissectors/packet-sll.c
@@ -69,7 +69,6 @@ static const value_string ltype_vals[] = {
{ LINUX_SLL_P_IRDA_LAP, "IrDA LAP" },
{ LINUX_SLL_P_ISI, "ISI" },
{ LINUX_SLL_P_IEEE802154, "IEEE 802.15.4" },
- { LINUX_SLL_P_NETLINK, "Netlink" },
{ 0, NULL }
};
@@ -140,7 +139,8 @@ static header_field_info hfi_sll_trailer SLL_HFI_INIT =
static gint ett_sll = -1;
-static dissector_table_t sll_linux_dissector_table;
+static dissector_table_t sll_hatype_dissector_table;
+static dissector_table_t sll_ltype_dissector_table;
static dissector_table_t gre_dissector_table;
static void sll_prompt(packet_info *pinfo, gchar* result)
@@ -218,6 +218,7 @@ sll_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, cons
static gboolean
capture_sll(const guchar *pd, int offset _U_, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
{
+ guint16 hatype;
guint16 protocol;
if (!BYTES_ARE_IN_FRAME(0, len, SLL_HEADER_SIZE))
@@ -229,6 +230,10 @@ capture_sll(const guchar *pd, int offset _U_, int len, capture_packet_info_t *cp
* "proto" is *not* a length field, it's a Linux internal
* protocol type.
*/
+ hatype = pntoh16(&pd[2]);
+ if (try_capture_dissector("sll.hatype", hatype, pd,
+ SLL_HEADER_SIZE, len, cpinfo, pseudo_header))
+ return TRUE;
return try_capture_dissector("sll.ltype", protocol, pd, SLL_HEADER_SIZE, len, cpinfo, pseudo_header);
} else {
return try_capture_dissector("ethertype", protocol, pd, SLL_HEADER_SIZE, len, cpinfo, pseudo_header);
@@ -270,12 +275,18 @@ dissect_sll(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
hatype = tvb_get_ntohs(tvb, 2);
halen = tvb_get_ntohs(tvb, 4);
- /* the netlink dissector can parse our entire header, we can
- pass it our complete tvb
- XXX - are there any other protocols that use the same header
- format as sll? if so, we should add a dissector table
- sll.hatpye */
- if (hatype == LINUX_SLL_P_NETLINK) {
+ /*
+ * XXX - special purpose hack. Netlink packets have a hardware
+ * address type of LINUX_SLL_ARPHRD_NETLINK, but the protocol
+ * type value indicates the Netlink message type; we just hand
+ * the netlink dissector our *entire* packet.
+ *
+ * That's different from link-layer types such as 802.11+radiotap,
+ * where the payload follows the complete SLL header, and the
+ * protocol field in the SLL header is irrelevant; for those,
+ * we have the sll.hatype dissector table.
+ */
+ if (hatype == LINUX_SLL_ARPHRD_NETLINK) {
return call_dissector(netlink_handle, tvb, pinfo, tree);
}
@@ -338,11 +349,13 @@ dissect_sll(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
proto_tree_add_uint(fh_tree, &hfi_sll_ltype, tvb, 14, 2,
protocol);
- p_add_proto_data(pinfo->pool, pinfo, proto_sll, 0, GUINT_TO_POINTER((guint)protocol));
-
- if(!dissector_try_uint(sll_linux_dissector_table, protocol,
- next_tvb, pinfo, tree)) {
- call_data_dissector(next_tvb, pinfo, tree);
+ if (!dissector_try_uint(sll_hatype_dissector_table, hatype,
+ next_tvb, pinfo, tree)) {
+ p_add_proto_data(pinfo->pool, pinfo, proto_sll, 0, GUINT_TO_POINTER((guint)protocol));
+ if (!dissector_try_uint(sll_ltype_dissector_table,
+ protocol, next_tvb, pinfo, tree)) {
+ call_data_dissector(next_tvb, pinfo, tree);
+ }
}
} else {
switch (hatype) {
@@ -419,7 +432,27 @@ proto_register_sll(void)
sll_handle = create_dissector_handle(dissect_sll, proto_sll);
sll_tap = register_tap("sll");
- sll_linux_dissector_table = register_dissector_table (
+ /*
+ * Sigh.
+ *
+ * For some packets, the link-layer header *isn't* been stripped
+ * off in a cooked capture; the hardware address type is the
+ * device ARPTYPE, so, for those packets, we should call the
+ * dissector for that value.
+ *
+ * We define a "sll.hatype" dissector table; we try dissecting
+ * with that first, and then try the protocol type if nothing
+ * is found in sll.hatype.
+ */
+ sll_hatype_dissector_table = register_dissector_table (
+ "sll.hatype",
+ "Linux SLL ARPHRD_ type",
+ proto_sll, FT_UINT16,
+ BASE_DEC
+ );
+ register_capture_dissector_table("sll.hatype", "Linux SLL ARPHRD_ type");
+
+ sll_ltype_dissector_table = register_dissector_table (
"sll.ltype",
"Linux SLL protocol type",
proto_sll, FT_UINT16,
diff --git a/epan/dissectors/packet-sll.h b/epan/dissectors/packet-sll.h
index 7aa464d27f..179d6a1746 100644
--- a/epan/dissectors/packet-sll.h
+++ b/epan/dissectors/packet-sll.h
@@ -14,7 +14,7 @@
/*
* The LINUX_SLL_ values for "sll_protocol".
- * https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_ether.h ?
+ * https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_ether.h
*/
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_ETHERNET 0x0003 /* Ethernet */
@@ -25,6 +25,15 @@
#define LINUX_SLL_P_IRDA_LAP 0x0017 /* IrDA Link Access Protocol */
#define LINUX_SLL_P_ISI 0x00F5 /* Intelligent Service Interface */
#define LINUX_SLL_P_IEEE802154 0x00f6 /* 802.15.4 on monitor inteface */
-#define LINUX_SLL_P_NETLINK 0x0338 /* Netlink */
+
+/*
+ * The LINUX_SLL_ values for ARPHRD_ types that get treated specially,
+ * because their packets do *not* get the link-layer header stripped
+ * in a cooked capture.
+ *
+ * https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_arp.h
+ */
+#define LINUX_SLL_ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
+#define LINUX_SLL_ARPHRD_NETLINK 824 /* Netlink header */
#endif