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>
This commit is contained in:
Guy Harris 2015-02-15 14:46:30 -08:00
parent 1917023fc1
commit fea325d2ba
6 changed files with 98 additions and 20 deletions

View File

@ -290,6 +290,9 @@ capture_info_packet(packet_counts *counts, gint wtap_linktype, const guchar *pd,
case WTAP_ENCAP_NULL:
capture_null(pd, caplen, counts);
break;
case WTAP_ENCAP_LOOP:
capture_loop(pd, caplen, counts);
break;
case WTAP_ENCAP_PPP:
capture_ppp_hdlc(pd, 0, caplen, counts);
break;

View File

@ -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);
}
/*

View File

@ -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

View File

@ -206,7 +206,7 @@ static const struct {
{ 105, WTAP_ENCAP_IEEE_802_11 }, /* IEEE 802.11 */
{ 106, WTAP_ENCAP_LINUX_ATM_CLIP },
{ 107, WTAP_ENCAP_FRELAY }, /* Frame Relay */
{ 108, WTAP_ENCAP_NULL }, /* OpenBSD loopback */
{ 108, WTAP_ENCAP_LOOP }, /* OpenBSD loopback */
{ 109, WTAP_ENCAP_ENC }, /* OpenBSD IPSEC enc */
#if 0
{ 110, WTAP_ENCAP_LANE_802_3 },/* ATM LANE 802.3 */
@ -481,12 +481,12 @@ static const struct {
* (it's just like DLT_NULL, only with the AF_ value in network
* rather than host byte order - Wireshark figures out the
* byte order from the data, so we don't care what byte order
* it's in), so if DLT_LOOP is defined as 12, interpret 12
* as WTAP_ENCAP_NULL, otherwise, unless DLT_C_HDLC is defined
* as 12, interpret it as WTAP_ENCAP_RAW_IP.
* it's in), so, on OpenBSD, interpret 12 as WTAP_ENCAP_LOOP,
* otherwise, if we're not on BSD/OS, interpret it as
* WTAP_ENCAP_RAW_IP.
*/
#if defined(__OpenBSD__)
{ 12, WTAP_ENCAP_NULL },
{ 12, WTAP_ENCAP_LOOP },
#elif defined(__bsdi__) /* BSD/OS */
/*
* Put entry for Cisco HDLC here.

View File

@ -259,7 +259,7 @@ static struct encap_type_info encap_table_base[] = {
{ "ATM PDUs - untruncated", "atm-pdus-untruncated" },
/* WTAP_ENCAP_NULL */
{ "NULL", "null" },
{ "NULL/Loopback", "null" },
/* WTAP_ENCAP_ASCEND */
{ "Lucent/Ascend access equipment", "ascend" },
@ -737,6 +737,9 @@ static struct encap_type_info encap_table_base[] = {
/* WTAP_ENCAP_IPMI_TRACE */
{ "IPMI Trace Data Collection", "ipmi-trace" },
/* WTAP_ENCAP_LOOP */
{ "OpenBSD loopback", "loop" },
};
WS_DLL_LOCAL

View File

@ -265,6 +265,7 @@ extern "C" {
#define WTAP_ENCAP_PKTAP 172
#define WTAP_ENCAP_EPON 173
#define WTAP_ENCAP_IPMI_TRACE 174
#define WTAP_ENCAP_LOOP 175
/* After adding new item here, please also add new item to encap_table_base array */
#define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types()