aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-3com-xns.c18
-rw-r--r--epan/dissectors/packet-ap1394.c16
-rw-r--r--epan/dissectors/packet-infiniband.c31
-rw-r--r--epan/dissectors/packet-llc.c29
-rw-r--r--epan/dissectors/packet-llc.h20
-rw-r--r--epan/dissectors/packet-nhrp.c310
-rw-r--r--epan/dissectors/packet-nhrp.h14
-rw-r--r--epan/dissectors/packet-null.c32
8 files changed, 338 insertions, 132 deletions
diff --git a/epan/dissectors/packet-3com-xns.c b/epan/dissectors/packet-3com-xns.c
index a9e0392521..2ea3b00540 100644
--- a/epan/dissectors/packet-3com-xns.c
+++ b/epan/dissectors/packet-3com-xns.c
@@ -43,7 +43,10 @@ static const value_string retix_bpdu_type_vals[] = {
{ 0, NULL }
};
+static dissector_table_t ethertype_subdissector_table;
+
static dissector_handle_t retix_bpdu_handle;
+static dissector_handle_t data_handle;
/*
* Apparently 3Com had some scheme for encapsulating XNS in 802.2 LLC,
@@ -65,6 +68,7 @@ dissect_3com_xns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree *subtree = NULL;
proto_tree *ti;
guint16 type;
+ tvbuff_t *next_tvb;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "3Com XNS");
@@ -77,14 +81,17 @@ dissect_3com_xns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
type = tvb_get_ntohs(tvb, 0);
+ next_tvb = tvb_new_subset(tvb, 2, -1, -1);
if (type == 0x0004) {
proto_tree_add_uint(subtree, hf_3com_xns_type_retix_bpdu,
tvb, 0, 2, type);
- call_dissector(retix_bpdu_handle,
- tvb_new_subset(tvb, 2, -1, -1), pinfo, tree);
+ call_dissector(retix_bpdu_handle, next_tvb, pinfo, tree);
} else {
- ethertype(type, tvb, 2, pinfo, tree, subtree,
- hf_3com_xns_type_ethertype, -1, 0);
+ proto_tree_add_uint(subtree, hf_3com_xns_type_ethertype,
+ tvb, 0, 2, type);
+ if (!dissector_try_port(ethertype_subdissector_table,
+ type, next_tvb, pinfo, tree))
+ call_dissector(data_handle, next_tvb, pinfo, tree);
}
}
@@ -117,6 +124,9 @@ proto_reg_handoff_3com_xns(void)
dissector_handle_t our_xns_handle;
retix_bpdu_handle = find_dissector("rbpdu");
+ data_handle = find_dissector("data");
+
+ ethertype_subdissector_table = find_dissector_table("ethertype");
our_xns_handle = create_dissector_handle(dissect_3com_xns, proto_3com_xns);
dissector_add("llc.dsap", 0x80, our_xns_handle);
diff --git a/epan/dissectors/packet-ap1394.c b/epan/dissectors/packet-ap1394.c
index 1b19d4e820..e1ac60513c 100644
--- a/epan/dissectors/packet-ap1394.c
+++ b/epan/dissectors/packet-ap1394.c
@@ -41,6 +41,10 @@ static int hf_ap1394_type = -1;
static gint ett_ap1394 = -1;
+static dissector_table_t ethertype_subdissector_table;
+
+static dissector_handle_t data_handle;
+
void
capture_ap1394(const guchar *pd, int offset, int len, packet_counts *ld)
{
@@ -66,6 +70,7 @@ dissect_ap1394(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree *fh_tree = NULL;
const guint8 *src_addr, *dst_addr;
guint16 etype;
+ tvbuff_t *next_tvb;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IP/IEEE1394");
@@ -88,7 +93,12 @@ dissect_ap1394(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_bytes(fh_tree, hf_ap1394_src, tvb, 8, 8, src_addr);
}
etype = tvb_get_ntohs(tvb, 16);
- ethertype(etype, tvb, 18, pinfo, tree, fh_tree, hf_ap1394_type, -1, 0);
+ if (tree)
+ proto_tree_add_uint(fh_tree, hf_ap1394_type, tvb, 16, 2, etype);
+ next_tvb = tvb_new_subset(tvb, 18, -1, -1);
+ if (!dissector_try_port(ethertype_subdissector_table, etype, next_tvb,
+ pinfo, tree))
+ call_dissector(data_handle, next_tvb, pinfo, tree);
}
void
@@ -120,6 +130,10 @@ proto_reg_handoff_ap1394(void)
{
dissector_handle_t ap1394_handle;
+ data_handle = find_dissector("data");
+
+ ethertype_subdissector_table = find_dissector_table("ethertype");
+
ap1394_handle = create_dissector_handle(dissect_ap1394, proto_ap1394);
dissector_add("wtap_encap", WTAP_ENCAP_APPLE_IP_OVER_IEEE1394, ap1394_handle);
}
diff --git a/epan/dissectors/packet-infiniband.c b/epan/dissectors/packet-infiniband.c
index b91e3f34e9..ec2afcc0de 100644
--- a/epan/dissectors/packet-infiniband.c
+++ b/epan/dissectors/packet-infiniband.c
@@ -35,7 +35,6 @@
#include <epan/dissectors/packet-frame.h>
#include "packet-infiniband.h"
-
/* Main Dissector */
/* Notes: */
/* 1.) Floating "offset+=" statements should probably be "functionized" but they are inline */
@@ -1024,10 +1023,13 @@ static void parse_IPvSix(proto_tree *parentTree, tvbuff_t *tvb, gint *offset, pa
static void parse_RWH(proto_tree *ah_tree, tvbuff_t *tvb, gint *offset, packet_info *pinfo)
{
guint16 ether_type;
+ tvbuff_t *next_tvb;
/* RWH - Raw Header */
proto_tree *RWH_header_tree = NULL;
proto_item *RWH_header_item = NULL;
+
+ gint captured_length, reported_length;
RWH_header_item = proto_tree_add_item(ah_tree, hf_infiniband_RWH, tvb, *offset, 4, FALSE);
proto_item_set_text(RWH_header_item, "%s", "RWH - Raw Header");
@@ -1037,19 +1039,37 @@ static void parse_RWH(proto_tree *ah_tree, tvbuff_t *tvb, gint *offset, packet_i
#if 0
ether_type = ether_type & 0x0F; /* mask off reserved bits just in case. */
#endif
+ proto_tree_add_uint(RWH_header_tree, hf_infiniband_etype, tvb, *offset, 2,
+ ether_type);
*offset += 2;
- proto_tree_add_uint(RWH_header_tree, hf_infiniband_reserved16_RWH, tvb,
- *offset, 2, tvb_get_ntohs(tvb, *offset));
+ proto_tree_add_item(RWH_header_tree, hf_infiniband_reserved16_RWH, tvb,
+ *offset, 2, FALSE);
*offset += 2;
- ethertype(ether_type, tvb, *offset, pinfo, top_tree, RWH_header_tree, hf_infiniband_etype, -1, 0);
+ /* Get the captured length and reported length of the data
+ * after the Ethernet type. */
+ captured_length = tvb_length_remaining(tvb, *offset);
+ reported_length = tvb_reported_length_remaining(tvb, *offset);
+
+ /* Construct a tvbuff for the payload after the Ethernet type,
+ * not including the FCS. */
+ if (captured_length >= 0 && reported_length >= 0) {
+ if (reported_length >= 2)
+ reported_length -= 2;
+ if (captured_length > reported_length)
+ captured_length = reported_length;
+ }
+
+ next_tvb = tvb_new_subset(tvb, *offset, captured_length, reported_length);
+ if (!dissector_try_port(ethertype_dissector_table, ether_type,
+ next_tvb, pinfo, top_tree))
+ call_dissector(data_handle, next_tvb, pinfo, top_tree);
*offset = tvb_reported_length(tvb) - 2;
/* Display the VCRC */
proto_tree_add_item(ah_tree, hf_infiniband_variant_crc, tvb, *offset, 2, FALSE);
-
}
/* Parse Subnet Management (LID Routed)
@@ -3150,4 +3170,3 @@ void proto_reg_handoff_infiniband(void)
data_handle = find_dissector("data");
ethertype_dissector_table = find_dissector_table("ethertype");
}
-
diff --git a/epan/dissectors/packet-llc.c b/epan/dissectors/packet-llc.c
index 2d1a6b30b7..f68ff333f1 100644
--- a/epan/dissectors/packet-llc.c
+++ b/epan/dissectors/packet-llc.c
@@ -244,15 +244,8 @@ const value_string type_vals[] = {
};
/*
- * Hash table for translating OUIs to a dissector table/field info pair;
- * the dissector table maps PID values to dissectors, and the field
- * corresponds to the PID for that OUI.
+ * Hash table for translating OUIs to an oui_info_t.
*/
-typedef struct {
- dissector_table_t table;
- hf_register_info *field_info;
-} oui_info_t;
-
static GHashTable *oui_info_table = NULL;
/*
@@ -747,10 +740,8 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
/*
* Do we have information for this OUI?
*/
- if (oui_info_table != NULL &&
- (oui_info =
- g_hash_table_lookup(oui_info_table,
- GUINT_TO_POINTER(oui))) != NULL) {
+ oui_info = get_snap_oui_info(oui);
+ if (oui_info != NULL) {
/*
* Yes - use it.
*/
@@ -782,6 +773,20 @@ dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
}
}
+/*
+ * Return the oui_info_t for the PID for a particular OUI value, or NULL
+ * if there isn't one.
+ */
+oui_info_t *
+get_snap_oui_info(guint32 oui)
+{
+ if (oui_info_table != NULL) {
+ return g_hash_table_lookup(oui_info_table,
+ GUINT_TO_POINTER(oui));
+ } else
+ return NULL;
+}
+
void
proto_register_llc(void)
{
diff --git a/epan/dissectors/packet-llc.h b/epan/dissectors/packet-llc.h
index 976de2f8d3..b65e1bb581 100644
--- a/epan/dissectors/packet-llc.h
+++ b/epan/dissectors/packet-llc.h
@@ -25,6 +25,9 @@
#define __PACKET_LLC_H__
void capture_llc(const guchar *, int, int, packet_counts *);
+
+extern const value_string sap_vals[];
+
void capture_snap(const guchar *, int, int, packet_counts *);
void dissect_snap(tvbuff_t *, int, packet_info *, proto_tree *,
@@ -35,6 +38,21 @@ void dissect_snap(tvbuff_t *, int, packet_info *, proto_tree *,
*/
void llc_add_oui(guint32, const char *, const char *, hf_register_info *);
-extern const value_string sap_vals[];
+/*
+ * SNAP information about the PID for a particular OUI:
+ *
+ * the dissector table to use with the PID's value;
+ * the field to use for the PID.
+ */
+typedef struct {
+ dissector_table_t table;
+ hf_register_info *field_info;
+} oui_info_t;
+
+/*
+ * Return the oui_info_t for the PID for a particular OUI value, or NULL
+ * if there isn't one.
+ */
+oui_info_t *get_snap_oui_info(guint32);
#endif
diff --git a/epan/dissectors/packet-nhrp.c b/epan/dissectors/packet-nhrp.c
index bce5248374..2b223051da 100644
--- a/epan/dissectors/packet-nhrp.c
+++ b/epan/dissectors/packet-nhrp.c
@@ -1,5 +1,6 @@
/* packet-nhrp.c
- * Routines for NBMA Next Hop Resoultion Protocol
+ * Routines for NBMA Next Hop Resolution Protocol
+ * RFC 2332 plus Cisco extensions (documented where?)
*
* $Id$
*
@@ -21,11 +22,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- *
- *
* CIE decoding for extensions and Cisco 12.4T extensions
* added by Timo Teras <timo.teras@iki.fi>
- *
*/
#ifdef HAVE_CONFIG_H
@@ -39,12 +37,16 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/addr_resolv.h>
+#include <epan/expert.h>
#include <epan/etypes.h>
#include <epan/ipproto.h>
#include <epan/greproto.h>
+#include <epan/nlpid.h>
+#include <epan/oui.h>
#include <epan/sminmpec.h>
#include <epan/afn.h>
#include <epan/in_cksum.h>
+#include <epan/dissectors/packet-llc.h>
#include "packet-nhrp.h"
/* forward reference */
@@ -55,7 +57,8 @@ void dissect_nhrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static int proto_nhrp = -1;
static int hf_nhrp_hdr_afn = -1;
static int hf_nhrp_hdr_pro_type = -1;
-static int hf_nhrp_hdr_pro_snap = -1;
+static int hf_nhrp_hdr_pro_snap_oui = -1;
+static int hf_nhrp_hdr_pro_snap_pid = -1;
static int hf_nhrp_hdr_hopcnt = -1;
static int hf_nhrp_hdr_pktsz = -1;
static int hf_nhrp_hdr_chksum = -1;
@@ -220,6 +223,27 @@ static const value_string nhrp_cie_code_vals[] = {
{ 0, NULL }
};
+static dissector_table_t osinl_subdissector_table;
+static dissector_table_t osinl_excl_subdissector_table;
+static dissector_table_t ethertype_subdissector_table;
+
+static dissector_handle_t data_handle;
+
+typedef struct _e_nhrp {
+ guint16 ar_afn;
+ guint16 ar_pro_type;
+ guint32 ar_pro_type_oui;
+ guint16 ar_pro_type_pid;
+ guint8 ar_hopCnt;
+ guint16 ar_pktsz;
+ guint16 ar_chksum;
+ guint16 ar_extoff;
+ guint8 ar_op_version;
+ guint8 ar_op_type;
+ guint8 ar_shtl;
+ guint8 ar_sstl;
+} e_nhrp_hdr;
+
static guint16 nhrp_checksum(const guint8 *ptr, int len)
{
vec_t cksum_vec[1];
@@ -230,15 +254,17 @@ static guint16 nhrp_checksum(const guint8 *ptr, int len)
}
void dissect_nhrp_hdr(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree,
gint *pOffset,
gint *pMandLen,
gint *pExtLen,
+ oui_info_t **pOuiInfo,
e_nhrp_hdr *hdr)
{
gint offset = *pOffset;
- gchar *pro_type_str = "";
- gint total_len = tvb_length(tvb);
+ const gchar *pro_type_str;
+ guint total_len = tvb_reported_length(tvb);
guint16 ipcsum, rx_chksum;
proto_item *nhrp_tree_item = NULL;
@@ -247,6 +273,7 @@ void dissect_nhrp_hdr(tvbuff_t *tvb,
proto_tree *shtl_tree = NULL;
proto_item *sstl_tree_item = NULL;
proto_tree *sstl_tree = NULL;
+ proto_item *ti;
nhrp_tree_item = proto_tree_add_text(tree, tvb, offset, 20, "NHRP Fixed Header");
nhrp_tree = proto_item_add_subtree(nhrp_tree_item, ett_nhrp_hdr);
@@ -256,33 +283,62 @@ void dissect_nhrp_hdr(tvbuff_t *tvb,
total_len = hdr->ar_pktsz;
}
- ipcsum = nhrp_checksum(tvb_get_ptr(tvb, offset, total_len), total_len);
-
hdr->ar_afn = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_afn, tvb, offset, 2, FALSE);
offset += 2;
hdr->ar_pro_type = tvb_get_ntohs(tvb, offset);
- switch (hdr->ar_pro_type) {
- case ETHERTYPE_IP:
- pro_type_str = "IPv4";
- break;
- case ETHERTYPE_IPv6:
- pro_type_str = "IPv6";
- break;
- default:
- pro_type_str = "Unknown";
- break;
+ if (hdr->ar_pro_type <= 0xFF) {
+ /* It's an NLPID */
+ pro_type_str = val_to_str(hdr->ar_pro_type, nlpid_vals,
+ "Unknown NLPID");
+ } else if (hdr->ar_pro_type <= 0x3FF) {
+ /* Reserved for future use by the IETF */
+ pro_type_str = "Reserved for future use by the IETF";
+ } else if (hdr->ar_pro_type <= 0x04FF) {
+ /* Allocated for use by the ATM Forum */
+ pro_type_str = "Allocated for use by the ATM Forum";
+ } else if (hdr->ar_pro_type <= 0x05FF) {
+ /* Experimental/Local use */
+ pro_type_str = "Experimental/Local use";
+ } else {
+ pro_type_str = val_to_str(hdr->ar_pro_type, etype_vals,
+ "Unknown Ethertype");
}
proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_pro_type, tvb, offset, 2,
- hdr->ar_pro_type,
- "Protocol Type (short form): %#x (%s)",
- hdr->ar_pro_type, pro_type_str);
+ hdr->ar_pro_type, "Protocol Type (short form): %s (0x%04x)",
+ pro_type_str, hdr->ar_pro_type);
offset += 2;
- proto_tree_add_text(nhrp_tree, tvb, offset, 5,
+
+ if (hdr->ar_pro_type == NLPID_SNAP) {
+ /*
+ * The long form protocol type is a SNAP OUI and PID.
+ */
+ hdr->ar_pro_type_oui = tvb_get_ntoh24(tvb, offset);
+ proto_tree_add_uint(nhrp_tree, hf_nhrp_hdr_pro_snap_oui,
+ tvb, offset, 3, hdr->ar_pro_type_oui);
+ offset += 3;
+
+ hdr->ar_pro_type_pid = tvb_get_ntohs(tvb, offset);
+ *pOuiInfo = get_snap_oui_info(hdr->ar_pro_type_oui);
+ if (*pOuiInfo != NULL) {
+ proto_tree_add_uint(nhrp_tree,
+ *(*pOuiInfo)->field_info->p_id,
+ tvb, offset, 2, hdr->ar_pro_type_pid);
+ } else {
+ proto_tree_add_uint(nhrp_tree, hf_nhrp_hdr_pro_snap_pid,
+ tvb, offset, 2, hdr->ar_pro_type_pid);
+ }
+ } else {
+ /*
+ * XXX - we should check that this is zero, as RFC 2332
+ * says it should be zero.
+ */
+ proto_tree_add_text(nhrp_tree, tvb, offset, 5,
"Protocol Type (long form): %s",
tvb_bytes_to_str(tvb, offset, 5));
- offset += 5;
+ offset += 5;
+ }
proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_hopcnt, tvb, offset, 1, FALSE);
offset += 1;
@@ -291,18 +347,29 @@ void dissect_nhrp_hdr(tvbuff_t *tvb,
offset += 2;
rx_chksum = tvb_get_ntohs(tvb, offset);
- if (ipcsum == 0) {
- proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
- "NHRP Packet checksum: 0x%04x [correct]", rx_chksum);
+ if (tvb_bytes_exist(tvb, 0, total_len)) {
+ ipcsum = nhrp_checksum(tvb_get_ptr(tvb, 0, total_len),
+ total_len);
+ if (ipcsum == 0) {
+ proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
+ "NHRP Packet checksum: 0x%04x [correct]", rx_chksum);
+ } else {
+ proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
+ "NHRP Packet checksum: 0x%04x [incorrect, should be 0x%04x]", rx_chksum,
+ in_cksum_shouldbe(rx_chksum, ipcsum));
+ }
} else {
proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
- "NHRP Packet checksum: 0x%04x [incorrect, should be 0x%04x]", rx_chksum,
- in_cksum_shouldbe(rx_chksum, ipcsum));
+ "NHRP Packet checksum: 0x%04x [not all data available]", rx_chksum);
}
offset += 2;
hdr->ar_extoff = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_extoff, tvb, offset, 2, FALSE);
+ ti = proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_extoff, tvb, offset, 2, FALSE);
+ if (hdr->ar_extoff < 20) {
+ expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
+ "Extension offset is less than the fixed header length");
+ }
offset += 2;
hdr->ar_op_version = tvb_get_guint8(tvb, offset);
@@ -337,11 +404,22 @@ void dissect_nhrp_hdr(tvbuff_t *tvb,
*pOffset = offset;
if (hdr->ar_extoff) {
- *pMandLen = hdr->ar_extoff - 20;
- *pExtLen = total_len - hdr->ar_extoff;
+ if (hdr->ar_extoff >= 20) {
+ *pMandLen = hdr->ar_extoff - 20;
+ *pExtLen = total_len - hdr->ar_extoff;
+ } else {
+ /* Error */
+ *pMandLen = 0;
+ *pExtLen = 0;
+ }
}
else {
- *pMandLen = total_len - 20;
+ if (total_len >= 20)
+ *pMandLen = total_len - 20;
+ else {
+ /* "Can't happen" - we would have thrown an exception */
+ *pMandLen = 0;
+ }
*pExtLen = 0;
}
}
@@ -360,10 +438,10 @@ void dissect_cie_list(tvbuff_t *tvb,
guint8 val;
while ((offset + 12) <= cieEnd) {
- gint cli_addr_len = tvb_get_guint8(tvb, offset + 8);
- gint cli_saddr_len = tvb_get_guint8(tvb, offset + 9);
- gint cli_prot_len = tvb_get_guint8(tvb, offset + 10);
- gint cie_len = 12 + cli_addr_len + cli_saddr_len + cli_prot_len;
+ guint cli_addr_len = tvb_get_guint8(tvb, offset + 8);
+ guint cli_saddr_len = tvb_get_guint8(tvb, offset + 9);
+ guint cli_prot_len = tvb_get_guint8(tvb, offset + 10);
+ guint cie_len = 12 + cli_addr_len + cli_saddr_len + cli_prot_len;
proto_item *cie_tree_item = proto_tree_add_text(tree, tvb, offset, cie_len, "Client Information Entry");
proto_tree *cie_tree = proto_item_add_subtree(cie_tree_item, ett_nhrp_cie);
@@ -418,7 +496,6 @@ void dissect_cie_list(tvbuff_t *tvb,
offset += 1;
if (cli_addr_len) {
- tvb_ensure_bytes_exist(tvb, offset, cli_addr_len);
if (cli_addr_len == 4) {
addr = tvb_get_ipv4(tvb, offset);
proto_tree_add_ipv4(cie_tree, hf_nhrp_client_nbma_addr, tvb, offset, 4, addr);
@@ -432,14 +509,12 @@ void dissect_cie_list(tvbuff_t *tvb,
}
if (cli_saddr_len) {
- tvb_ensure_bytes_exist(tvb, offset, cli_saddr_len);
proto_tree_add_text(cie_tree, tvb, offset, cli_saddr_len,
"Client NBMA Sub Address: %s",
tvb_bytes_to_str(tvb, offset, cli_saddr_len));
}
if (cli_prot_len) {
- tvb_ensure_bytes_exist(tvb, offset, cli_prot_len);
if (cli_prot_len == 4) {
addr = tvb_get_ipv4(tvb, offset);
proto_tree_add_ipv4(cie_tree, hf_nhrp_client_prot_addr, tvb, offset, 4, addr);
@@ -458,6 +533,7 @@ void dissect_nhrp_mand(tvbuff_t *tvb,
packet_info *pinfo,
proto_tree *tree,
gint *pOffset,
+ oui_info_t *oui_info,
e_nhrp_hdr *hdr,
gint mandLen)
{
@@ -555,7 +631,6 @@ void dissect_nhrp_mand(tvbuff_t *tvb,
/* TBD : Check for hdr->afn */
shl = hdr->ar_shtl & NHRP_SHTL_LEN_MASK;
if (shl) {
- tvb_ensure_bytes_exist(tvb, offset, shl);
if (shl == 4) {
addr = tvb_get_ipv4(tvb, offset);
proto_tree_add_ipv4(nhrp_tree, hf_nhrp_src_nbma_addr, tvb, offset, 4, addr);
@@ -593,7 +668,7 @@ void dissect_nhrp_mand(tvbuff_t *tvb,
if (dstLen) {
if (dstLen == 4) {
addr = tvb_get_ipv4(tvb, offset);
- proto_tree_add_ipv4(nhrp_tree, hf_nhrp_dst_prot_addr, tvb, offset, 4, addr);
+ proto_tree_add_ipv4(nhrp_tree, hf_nhrp_dst_prot_addr, tvb, offset, 4, addr);
}
else {
proto_tree_add_text(nhrp_tree, tvb, offset, dstLen,
@@ -604,19 +679,85 @@ void dissect_nhrp_mand(tvbuff_t *tvb,
}
if (isInd) {
+ gboolean save_in_error_pkt;
gint pkt_len = mandEnd - offset;
proto_item *ind_tree_item = proto_tree_add_text(tree, tvb, offset, pkt_len, "Packet Causing Indication");
proto_tree *ind_tree = proto_item_add_subtree(ind_tree_item, ett_nhrp_indication);
+ gboolean dissected;
+ tvbuff_t *sub_tvb;
+ save_in_error_pkt = pinfo->in_error_pkt;
+ pinfo->in_error_pkt = TRUE;
+ sub_tvb = tvb_new_subset(tvb, offset, -1, -1);
if (isErr) {
- tvbuff_t *sub_tvb;
-
- sub_tvb = tvb_new_subset(tvb, offset, -1, -1);
dissect_nhrp(sub_tvb, pinfo, ind_tree);
}
else {
- ethertype(hdr->ar_pro_type, tvb, offset, pinfo, ind_tree, NULL, -1, -1, 0);
+ if (hdr->ar_pro_type <= 0xFF) {
+ /* It's an NLPID */
+ if (hdr->ar_pro_type == NLPID_SNAP) {
+ /*
+ * Dissect based on the SNAP OUI
+ * and PID.
+ */
+ if (hdr->ar_pro_type_oui == 0x000000) {
+ /*
+ * "Should not happen", as
+ * the protocol type should
+ * be the Ethertype, but....
+ */
+ dissected = dissector_try_port(
+ ethertype_subdissector_table,
+ hdr->ar_pro_type_pid,
+ sub_tvb, pinfo, ind_tree);
+ } else {
+ /*
+ * If we have a dissector
+ * table, use it, otherwise
+ * just dissect as data.
+ */
+ if (oui_info != NULL) {
+ dissected = dissector_try_port(
+ oui_info->table,
+ hdr->ar_pro_type_pid,
+ sub_tvb, pinfo,
+ ind_tree);
+ } else
+ dissected = FALSE;
+ }
+ } else {
+ /*
+ * Dissect based on the NLPID.
+ */
+ dissected = dissector_try_port(
+ osinl_subdissector_table,
+ hdr->ar_pro_type, sub_tvb, pinfo,
+ ind_tree) ||
+ dissector_try_port(
+ osinl_excl_subdissector_table,
+ hdr->ar_pro_type, sub_tvb, pinfo,
+ ind_tree);
+ }
+ } else if (hdr->ar_pro_type <= 0x3FF) {
+ /* Reserved for future use by the IETF */
+ dissected = FALSE;
+ } else if (hdr->ar_pro_type <= 0x04FF) {
+ /* Allocated for use by the ATM Forum */
+ dissected = FALSE;
+ } else if (hdr->ar_pro_type <= 0x05FF) {
+ /* Experimental/Local use */
+ dissected = FALSE;
+ } else {
+ dissected = dissector_try_port(
+ ethertype_subdissector_table,
+ hdr->ar_pro_type, sub_tvb, pinfo, ind_tree);
+ }
+ if (!dissected) {
+ call_dissector(data_handle, sub_tvb, pinfo,
+ ind_tree);
+ }
}
+ pinfo->in_error_pkt = save_in_error_pkt;
offset = mandEnd;
}
@@ -679,6 +820,14 @@ void dissect_nhrp_ext(tvbuff_t *tvb,
void dissect_nhrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+ e_nhrp_hdr hdr;
+ gint mandLen = 0;
+ gint extLen = 0;
+ gint offset = 0;
+ proto_item *ti = NULL;
+ proto_tree *nhrp_tree = NULL;
+ oui_info_t *oui_info;
+
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
col_set_str(pinfo->cinfo, COL_PROTOCOL, "NHRP");
}
@@ -686,43 +835,32 @@ void dissect_nhrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_clear(pinfo->cinfo, COL_INFO);
}
- if (tree) {
- e_nhrp_hdr hdr;
- gint mandLen = 0;
- gint extLen = 0;
- gint offset = 0;
- proto_item *ti = NULL;
- proto_tree *nhrp_tree = NULL;
-
- /* Fixed header is always 20 bytes. */
- tvb_ensure_bytes_exist(tvb, offset, 20);
- memset(&hdr, 0, sizeof(e_nhrp_hdr));
+ memset(&hdr, 0, sizeof(e_nhrp_hdr));
- hdr.ar_op_type = tvb_get_guint8(tvb, 17);
-
- if (check_col(pinfo->cinfo, COL_INFO)) {
- col_add_str(pinfo->cinfo, COL_INFO,
- val_to_str(hdr.ar_op_type, nhrp_op_type_vals,
- "0x%02X - unknown"));
- }
- col_set_writable(pinfo->cinfo, FALSE);
-
- ti = proto_tree_add_protocol_format(tree, proto_nhrp, tvb, 0, -1,
- "Next Hop Resolution Protocol (%s)",
- val_to_str(hdr.ar_op_type,
- nhrp_op_type_vals,
- "0x%02X - unknown"));
- nhrp_tree = proto_item_add_subtree(ti, ett_nhrp);
+ hdr.ar_op_type = tvb_get_guint8(tvb, 17);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_str(pinfo->cinfo, COL_INFO,
+ val_to_str(hdr.ar_op_type, nhrp_op_type_vals,
+ "0x%02X - unknown"));
+ }
+ col_set_writable(pinfo->cinfo, FALSE);
+
+ ti = proto_tree_add_protocol_format(tree, proto_nhrp, tvb, 0, -1,
+ "Next Hop Resolution Protocol (%s)",
+ val_to_str(hdr.ar_op_type, nhrp_op_type_vals, "0x%02X - unknown"));
+ nhrp_tree = proto_item_add_subtree(ti, ett_nhrp);
- dissect_nhrp_hdr(tvb, nhrp_tree, &offset, &mandLen, &extLen, &hdr);
- if (mandLen) {
- dissect_nhrp_mand(tvb, pinfo, nhrp_tree, &offset, &hdr, mandLen);
- }
+ dissect_nhrp_hdr(tvb, pinfo, nhrp_tree, &offset, &mandLen, &extLen,
+ &oui_info, &hdr);
+ if (mandLen) {
+ dissect_nhrp_mand(tvb, pinfo, nhrp_tree, &offset, oui_info,
+ &hdr, mandLen);
+ }
- if (extLen) {
- dissect_nhrp_ext(tvb, nhrp_tree, &offset, extLen);
- }
- } /* End of if (tree) */
+ if (extLen) {
+ dissect_nhrp_ext(tvb, nhrp_tree, &offset, extLen);
+ }
}
void
@@ -734,8 +872,10 @@ proto_register_nhrp(void)
{ "Address Family Number", "nhrp.hdr.afn", FT_UINT16, BASE_HEX_DEC, VALS(afn_vals), 0x0, "", HFILL }},
{ &hf_nhrp_hdr_pro_type,
{ "Protocol Type (short form)", "nhrp.hdr.pro.type",FT_UINT16, BASE_HEX_DEC, NULL, 0x0, "", HFILL }},
- { &hf_nhrp_hdr_pro_snap,
- { "Protocol Type (long form)", "nhrp.hdr.pro.snap",FT_UINT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_nhrp_hdr_pro_snap_oui,
+ { "Protocol Type (long form) - OUI", "nhrp.hdr.pro.snap.oui",FT_UINT24, BASE_HEX, VALS(oui_vals), 0x0, "", HFILL }},
+ { &hf_nhrp_hdr_pro_snap_pid,
+ { "Protocol Type (long form) - PID", "nhrp.hdr.pro.snap.pid",FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_nhrp_hdr_hopcnt,
{ "Hop Count", "nhrp.hdr.hopcnt", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_nhrp_hdr_pktsz,
@@ -869,6 +1009,12 @@ proto_reg_handoff_nhrp(void)
{
dissector_handle_t nhrp_handle;
+ data_handle = find_dissector("data");
+
+ osinl_subdissector_table = find_dissector_table("osinl");
+ osinl_excl_subdissector_table = find_dissector_table("osinl.excl");
+ ethertype_subdissector_table = find_dissector_table("ethertype");
+
nhrp_handle = create_dissector_handle(dissect_nhrp, proto_nhrp);
dissector_add("ip.proto", IP_PROTO_NARP, nhrp_handle);
dissector_add("gre.proto", GRE_NHRP, nhrp_handle);
diff --git a/epan/dissectors/packet-nhrp.h b/epan/dissectors/packet-nhrp.h
index a51289392c..1b3b4f8268 100644
--- a/epan/dissectors/packet-nhrp.h
+++ b/epan/dissectors/packet-nhrp.h
@@ -26,20 +26,6 @@
#ifndef __PACKET_NHRP_H__
#define __PACKET_NHRP_H__
-typedef struct _e_nhrp {
- guint16 ar_afn;
- guint16 ar_pro_type;
- guint8 ar_pro_snap[5];
- guint8 ar_hopCnt;
- guint16 ar_pktsz;
- guint16 ar_chksum;
- guint16 ar_extoff;
- guint8 ar_op_version;
- guint8 ar_op_type;
- guint8 ar_shtl;
- guint8 ar_sstl;
-} e_nhrp_hdr;
-
void capture_nhrp(const guchar *, int, int, packet_counts *);
/* Export the DSCP value-string table for other protocols */
diff --git a/epan/dissectors/packet-null.c b/epan/dissectors/packet-null.c
index 095f2118bc..2a8eb4afb4 100644
--- a/epan/dissectors/packet-null.c
+++ b/epan/dissectors/packet-null.c
@@ -44,6 +44,7 @@
#include <epan/aftypes.h>
static dissector_table_t null_dissector_table;
+static dissector_table_t ethertype_dissector_table;
/* protocols and header fields */
static int proto_null = -1;
@@ -417,22 +418,25 @@ dissect_null(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/*
* The null header value must be greater than the IEEE 802.3 maximum
- * frame length to be a valid Ethernet type; if it is, hand it
- * to "ethertype()", otherwise treat it as a BSD AF_type (we wire
- * in the values of the BSD AF_ types, because the values
- * in the file will be BSD values, and the OS on which
- * we're building this might not have the same values or
- * might not have them defined at all; XXX - what if different
- * BSD derivatives have different values?).
+ * frame length to be a valid Ethernet type; if it is, dissect it
+ * as one, otherwise treat it as a BSD AF_type (we wire in the values
+ * of the BSD AF_ types, because the values in the file will be BSD
+ * values, and the OS on which we're building this might not have the
+ * same values or might not have them defined at all; XXX - what if
+ * different BSD derivatives have different values?).
*/
if (null_header > IEEE_802_3_MAX_LEN) {
if (tree) {
ti = proto_tree_add_item(tree, proto_null, tvb, 0, 4, FALSE);
fh_tree = proto_item_add_subtree(ti, ett_null);
- } else
- fh_tree = NULL;
- ethertype((guint16) null_header, tvb, 4, pinfo, tree, fh_tree, hf_null_etype, -1,
- 0);
+ proto_tree_add_uint(fh_tree, hf_null_etype, tvb, 0, 4,
+ (guint16) null_header);
+ }
+
+ next_tvb = tvb_new_subset(tvb, 4, -1, -1);
+ if (!dissector_try_port(ethertype_dissector_table,
+ (guint16) null_header, next_tvb, pinfo, tree))
+ call_dissector(data_handle, next_tvb, pinfo, tree);
} else {
/* populate a tree in the second pane with the status of the link
layer (ie none) */
@@ -485,10 +489,14 @@ proto_reg_handoff_null(void)
dissector_handle_t null_handle;
/*
- * Get a handle for the PPP-in-HDLC-like-framing dissector.
+ * Get a handle for the PPP-in-HDLC-like-framing dissector and
+ * the "I don't know what this is" dissector.
*/
ppp_hdlc_handle = find_dissector("ppp_hdlc");
data_handle = find_dissector("data");
+
+ ethertype_dissector_table = find_dissector_table("ethertype");
+
null_handle = create_dissector_handle(dissect_null, proto_null);
dissector_add("wtap_encap", WTAP_ENCAP_NULL, null_handle);
}