diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-02-15 14:46:30 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-02-15 22:47:03 +0000 |
commit | fea325d2ba86cee47bb6bf89a068906744701c88 (patch) | |
tree | 403c99ed077e31fee09090b2ce689e8ed8aac0b7 /epan | |
parent | 1917023fc157b896a23349c0eca8c95f22f2fb6f (diff) |
Handle DLT_LOOP differently from DLT_NULL.
That's a little cleaner, and lets us preserve the LINKTYPE_ value for
DLT_LOOP captures. ("Preserve" here doesn't mean "write files with a
link-layer header type of 12", as that's ambiguous; we write it with a
link-layer header type of LINKTYPE_LOOP, i.e. 108. If programs on
OpenBSD don't recognize that as DLT_LOOP, that's a bug in OpenBSD's
libpcap or in the program.)
Change-Id: I48a2e04aed41c013823ffb5c588d2a8e8b376e15
Reviewed-on: https://code.wireshark.org/review/7143
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-null.c | 96 | ||||
-rw-r--r-- | epan/dissectors/packet-null.h | 3 |
2 files changed, 85 insertions, 14 deletions
diff --git a/epan/dissectors/packet-null.c b/epan/dissectors/packet-null.c index 116bd4ae71..bad3d046b5 100644 --- a/epan/dissectors/packet-null.c +++ b/epan/dissectors/packet-null.c @@ -24,6 +24,7 @@ #include "config.h" +#include <wsutil/pint.h> #include <epan/packet.h> #include "packet-null.h" @@ -63,6 +64,7 @@ static const value_string family_vals[] = { static dissector_handle_t ppp_hdlc_handle; static dissector_handle_t data_handle; + void capture_null( const guchar *pd, int len, packet_counts *ld ) { @@ -72,9 +74,7 @@ capture_null( const guchar *pd, int len, packet_counts *ld ) * BSD drivers that use DLT_NULL - including the FreeBSD 3.2 ISDN-for-BSD * drivers, as well as the 4.4-Lite and FreeBSD loopback drivers - * stuff the AF_ value for the protocol, in *host* byte order, in the - * first four bytes. (BSD drivers that use DLT_LOOP, such as recent - * OpenBSD loopback drivers, stuff it in *network* byte order in the - * first four bytes.) + * first four bytes. * * However, the IRIX and UNICOS/mp snoop socket mechanism supplies, * on loopback devices, a 4-byte header that has a 2 byte (big-endian) @@ -191,8 +191,8 @@ capture_null( const guchar *pd, int len, packet_counts *ld ) * * Otherwise, if the upper 16 bits are non-zero, either: * - * it's a BSD DLT_NULL or DLT_LOOP header whose AF_ value - * is not in our byte order; + * it's a BSD DLT_NULL header whose AF_ value is not in our + * byte order; * * it's an IRIX or UNICOS/mp DLT_NULL header being read on * a big-endian machine; @@ -206,10 +206,10 @@ capture_null( const guchar *pd, int len, packet_counts *ld ) * of the IRIX or UNICOS/mp DLT_NULL header, we should just get * the upper 16 bits as an AF_ value. * - * If it's a BSD DLT_NULL or DLT_LOOP header whose AF_ value is not - * in our byte order, then the upper 2 hex digits would be non-zero - * and the next 2 hex digits down would be zero, as AF_ values fit in - * 8 bits, and the upper 2 hex digits are the *lower* 8 bits of the value. + * If it's a BSD DLT_NULL header whose AF_ value is not in our byte + * order, then the upper 2 hex digits would be non-zero and the next + * 2 hex digits down would be zero, as AF_ values fit in 8 bits, and + * the upper 2 hex digits are the *lower* 8 bits of the value. * * If it's an IRIX or UNICOS/mp DLT_NULL header, the upper 2 hex digits * would be zero and the next 2 hex digits down would be non-zero, as @@ -232,8 +232,8 @@ capture_null( const guchar *pd, int len, packet_counts *ld ) * * If the upper 16 bits are zero, either: * - * it's a BSD DLT_NULLor DLT_LOOP header whose AF_ value is in - * our byte order; + * it's a BSD DLT_NULL header whose AF_ value is in our byte + * order; * * it's an IRIX or UNICOS/mp DLT_NULL header being read on * a little-endian machine; @@ -245,8 +245,8 @@ capture_null( const guchar *pd, int len, packet_counts *ld ) * we should *not* byte-swap it. In the case of the IRIX or UNICOS/mp * DLT_NULL header, we should extract the AF_ value and byte-swap it. * - * If it's a BSD DLT_NULL or DLT_LOOP header whose AF_ value is - * in our byte order, the upper 6 hex digits would all be zero. + * If it's a BSD DLT_NULL header whose AF_ value is in our byte order, + * the upper 6 hex digits would all be zero. * * If it's an IRIX or UNICOS/mp DLT_NULL header, the upper 4 hex * digits would be zero and the next 2 hex digits would not be zero. @@ -340,6 +340,35 @@ capture_null( const guchar *pd, int len, packet_counts *ld ) } } +void +capture_loop( const guchar *pd, int len, packet_counts *ld ) +{ + guint32 loop_family; + + if (!BYTES_ARE_IN_FRAME(0, len, (int)sizeof(loop_family))) { + ld->other++; + return; + } + loop_family = pntoh32(&pd[0]); + + switch (loop_family) { + + case BSD_AF_INET: + capture_ip(pd, 4, len, ld); + break; + + case BSD_AF_INET6_BSD: + case BSD_AF_INET6_FREEBSD: + case BSD_AF_INET6_DARWIN: + capture_ipv6(pd, 4, len, ld); + break; + + default: + ld->other++; + break; + } +} + static void dissect_null(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -446,6 +475,42 @@ dissect_null(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } } +/* + * OpenBSD DLT_LOOP; like DLT_NULL, but with the first 4 byte *always* + * being a *big-endian* type. + */ +static void +dissect_loop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint32 loop_family; + proto_tree *fh_tree; + proto_item *ti; + tvbuff_t *next_tvb; + + /* load the top pane info. This should be overwritten by + the next protocol in the stack */ + col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A"); + col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A"); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A"); + col_set_str(pinfo->cinfo, COL_INFO, "Null/Loopback"); + + /* populate a tree in the second pane with the status of the link + layer (ie none) */ + loop_family = tvb_get_ntohl(tvb, 0); + if (tree) { + ti = proto_tree_add_item(tree, proto_null, tvb, 0, 4, ENC_NA); + fh_tree = proto_item_add_subtree(ti, ett_null); + proto_tree_add_uint(fh_tree, hf_null_family, tvb, 0, 4, loop_family); + } + + next_tvb = tvb_new_subset_remaining(tvb, 4); + if (!dissector_try_uint(null_dissector_table, loop_family, + next_tvb, pinfo, tree)) { + /* No sub-dissector found. Label rest of packet as "Data" */ + call_dissector(data_handle,next_tvb, pinfo, tree); + } +} + void proto_register_null(void) { @@ -476,7 +541,7 @@ proto_register_null(void) void proto_reg_handoff_null(void) { - dissector_handle_t null_handle; + dissector_handle_t null_handle, loop_handle; /* * Get a handle for the PPP-in-HDLC-like-framing dissector and @@ -489,6 +554,9 @@ proto_reg_handoff_null(void) null_handle = create_dissector_handle(dissect_null, proto_null); dissector_add_uint("wtap_encap", WTAP_ENCAP_NULL, null_handle); + + loop_handle = create_dissector_handle(dissect_loop, proto_null); + dissector_add_uint("wtap_encap", WTAP_ENCAP_LOOP, loop_handle); } /* diff --git a/epan/dissectors/packet-null.h b/epan/dissectors/packet-null.h index 734737337f..b5354dcd9f 100644 --- a/epan/dissectors/packet-null.h +++ b/epan/dissectors/packet-null.h @@ -27,4 +27,7 @@ WS_DLL_PUBLIC void capture_null(const guchar *, int, packet_counts *); +WS_DLL_PUBLIC +void capture_loop(const guchar *, int, packet_counts *); + #endif |