diff options
-rw-r--r-- | epan/dissectors/packet-3com-xns.c | 18 | ||||
-rw-r--r-- | epan/dissectors/packet-ap1394.c | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-infiniband.c | 31 | ||||
-rw-r--r-- | epan/dissectors/packet-llc.c | 29 | ||||
-rw-r--r-- | epan/dissectors/packet-llc.h | 20 | ||||
-rw-r--r-- | epan/dissectors/packet-nhrp.c | 310 | ||||
-rw-r--r-- | epan/dissectors/packet-nhrp.h | 14 | ||||
-rw-r--r-- | epan/dissectors/packet-null.c | 32 |
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); } |