diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-ieee80211-radiotap.c | 9 | ||||
-rw-r--r-- | epan/dissectors/packet-sll.c | 61 | ||||
-rw-r--r-- | epan/dissectors/packet-sll.h | 13 |
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 |