diff options
author | Guy Harris <guy@alum.mit.edu> | 2000-12-28 09:49:09 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2000-12-28 09:49:09 +0000 |
commit | d13901155d5108fc756bf2b4a4608fa9af73a146 (patch) | |
tree | a3fc4e9de7e42980ada10de139813e9937956393 /packet-cdp.c | |
parent | f69876eece2a86501b309e9aecfdcd69b95dc500 (diff) | |
download | wireshark-d13901155d5108fc756bf2b4a4608fa9af73a146.tar.gz wireshark-d13901155d5108fc756bf2b4a4608fa9af73a146.tar.bz2 wireshark-d13901155d5108fc756bf2b4a4608fa9af73a146.zip |
Tvbuffify the CDP, CGMP, ISL, and VTP dissectors.
Add a new subdissector table in the LLC dissector for protocol IDs with
a Cisco OUI, and register the CDP, CGMP, and VTMP dissectors in that
table, rather than calling them via a switch statement.
Register the ISL dissector by name, and have the Ethernet dissector call
it via a handle.
Fix the handling of the checksum field in the CDP dissector.
The strings in CDP are counted, not null-terminated; treat them as such.
Fix the handling of the encapsulated frame CRC, and the encapsulated
frame, in the ISL dissector, at least for Ethernet frames; it may not be
correct for encapsulated Token Ring frames.
svn path=/trunk/; revision=2792
Diffstat (limited to 'packet-cdp.c')
-rw-r--r-- | packet-cdp.c | 492 |
1 files changed, 244 insertions, 248 deletions
diff --git a/packet-cdp.c b/packet-cdp.c index f33b7424af..2b55293d57 100644 --- a/packet-cdp.c +++ b/packet-cdp.c @@ -2,7 +2,7 @@ * Routines for the disassembly of the "Cisco Discovery Protocol" * (c) Copyright Hannes R. Boehm <hannes@boehm.org> * - * $Id: packet-cdp.c,v 1.27 2000/11/19 08:53:56 guy Exp $ + * $Id: packet-cdp.c,v 1.28 2000/12/28 09:49:09 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -52,7 +52,7 @@ static int proto_cdp = -1; static int hf_cdp_version = -1; -static int hf_cdp_flags = -1; +static int hf_cdp_checksum = -1; static int hf_cdp_ttl = -1; static int hf_cdp_tlvtype = -1; static int hf_cdp_tlvlength = -1; @@ -63,12 +63,12 @@ static gint ett_cdp_address = -1; static gint ett_cdp_capabilities = -1; static int -dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree); +dissect_address_tlv(tvbuff_t *tvb, int offset, int length, proto_tree *tree); static void -dissect_capabilities(const u_char *pd, int offset, int length, proto_tree *tree); +dissect_capabilities(tvbuff_t *tvb, int offset, int length, proto_tree *tree); static void -add_multi_line_string_to_tree(proto_tree *tree, gint start, gint len, - const gchar *prefix, const gchar *string); +add_multi_line_string_to_tree(proto_tree *tree, tvbuff_t *tvb, gint start, + gint len, const gchar *prefix); #define TYPE_DEVICE_ID 0x0001 #define TYPE_ADDRESS 0x0002 @@ -87,193 +87,190 @@ static const value_string type_vals[] = { { 0, NULL }, }; -void -dissect_cdp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +static void +dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *cdp_tree = NULL; + int offset = 0; guint16 type; guint16 length; - char *type_str; - char *stringmem; proto_item *tlvi; proto_tree *tlv_tree; int real_length; guint32 naddresses; int addr_length; - OLD_CHECK_DISPLAY_AS_DATA(proto_cdp, pd, offset, fd, tree); + CHECK_DISPLAY_AS_DATA(proto_cdp, tvb, pinfo, tree); - if (check_col(fd, COL_PROTOCOL)) - col_set_str(fd, COL_PROTOCOL, "CDP"); - if (check_col(fd, COL_INFO)) - col_set_str(fd, COL_INFO, "Cisco Discovery Protocol"); + pinfo->current_proto = "CDP"; - if(tree){ - ti = proto_tree_add_item(tree, proto_cdp, NullTVB, offset, END_OF_FRAME, FALSE); + if (check_col(pinfo->fd, COL_PROTOCOL)) + col_set_str(pinfo->fd, COL_PROTOCOL, "CDP"); + if (check_col(pinfo->fd, COL_INFO)) + col_set_str(pinfo->fd, COL_INFO, "Cisco Discovery Protocol"); + + if (tree){ + ti = proto_tree_add_item(tree, proto_cdp, tvb, offset, + tvb_length_remaining(tvb, offset), FALSE); cdp_tree = proto_item_add_subtree(ti, ett_cdp); /* CDP header */ - proto_tree_add_uint(cdp_tree, hf_cdp_version, NullTVB, offset, 1, pd[offset]); + proto_tree_add_item(cdp_tree, hf_cdp_version, tvb, offset, 1, FALSE); offset += 1; - proto_tree_add_uint_format(cdp_tree, hf_cdp_ttl, NullTVB, offset, 1, - pntohs(&pd[offset]), - "TTL: %u seconds", pd[offset]); + proto_tree_add_uint_format(cdp_tree, hf_cdp_ttl, tvb, offset, 1, + tvb_get_guint8(tvb, offset), + "TTL: %u seconds", + tvb_get_guint8(tvb, offset)); offset += 1; - proto_tree_add_uint_format(cdp_tree, hf_cdp_flags, NullTVB, offset, 2, - pd[offset], - "Checksum: 0x%04x", pntohs(&pd[offset])); + proto_tree_add_item(cdp_tree, hf_cdp_checksum, tvb, offset, 2, FALSE); offset += 2; - while( IS_DATA_IN_FRAME(offset) ){ - type = pntohs(&pd[offset + TLV_TYPE]); - length = pntohs(&pd[offset + TLV_LENGTH]); - type_str = val_to_str(type, type_vals, - "Unknown (0x%04x)"); - - switch( type ){ - case TYPE_DEVICE_ID: - /* Device ID */ - tlvi = proto_tree_add_text(cdp_tree, NullTVB, offset, - length, "Device ID: %s", - &pd[offset+4]); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, NullTVB, offset + 4, - length - 4, "Device ID: %s", - &pd[offset+4]); - offset+=length; - break; - case TYPE_ADDRESS: - /* Addresses */ - tlvi = proto_tree_add_text(cdp_tree, NullTVB, offset, - length, "Addresses"); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - offset += 4; - length -= 4; - naddresses = pntohl(&pd[offset]); - proto_tree_add_text(tlv_tree, NullTVB, offset, 4, - "Number of addresses: %u", naddresses); - offset += 4; - length -= 4; - while (naddresses != 0) { - addr_length = dissect_address_tlv(pd, - offset, length, tlv_tree); - if (addr_length < 0) - break; - offset += addr_length; - length -= addr_length; - - naddresses--; - } - offset += length; - break; - case TYPE_PORT_ID: - real_length = length; - if (pd[offset + real_length] != 0x00) { - /* The length in the TLV doesn't - appear to be the length of the - TLV, as the byte just past it - isn't the first byte of a 2-byte - big-endian small integer; make - the length of the TLV the length - in the TLV, plus 4 bytes for the - TLV type and length, minus 1 - because that's what makes one - capture work. */ - real_length = length + 3; - } - tlvi = proto_tree_add_text(cdp_tree, NullTVB, offset, - real_length, "Port ID: %s", - &pd[offset+4]); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, NullTVB, offset + 4, - real_length - 4, - "Sent through Interface: %s", - &pd[offset+4]); - offset += real_length; - break; - case TYPE_CAPABILITIES: - tlvi = proto_tree_add_text(cdp_tree, NullTVB, offset, - length, "Capabilities"); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - offset += 4; - length -= 4; - dissect_capabilities(pd, offset, length, - tlv_tree); - offset += length; - break; - case TYPE_IOS_VERSION: - tlvi = proto_tree_add_text(cdp_tree, NullTVB, offset, - length, "Software Version"); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - add_multi_line_string_to_tree(tlv_tree, - offset + 4, length - 4, "Software Version: ", - &pd[offset+4] ); - offset += length; - break; - case TYPE_PLATFORM: - /* ??? platform */ - stringmem = malloc(length); - memset(stringmem, '\0', length); - memcpy(stringmem, &pd[offset+4], length - 4 ); - tlvi = proto_tree_add_text(cdp_tree, NullTVB, - offset, length, "Platform: %s", - stringmem); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - proto_tree_add_text(tlv_tree, NullTVB, offset + 4, - length - 4, "Platform: %s", stringmem); - free(stringmem); - offset+=length; - break; - default: - tlvi = proto_tree_add_text(cdp_tree, NullTVB, offset, - length, "Type: %s, length: %u", - type_str, length); - tlv_tree = proto_item_add_subtree(tlvi, - ett_cdp_tlv); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, NullTVB, - offset + TLV_TYPE, 2, type); - proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, NullTVB, - offset + TLV_LENGTH, 2, length); - if (length > 4) { - proto_tree_add_text(tlv_tree, NullTVB, - offset + 4, length - 4, "Data"); - } else - return; - offset+=length; + while (tvb_reported_length_remaining(tvb, offset) != 0) { + type = tvb_get_ntohs(tvb, offset + TLV_TYPE); + length = tvb_get_ntohs(tvb, offset + TLV_LENGTH); + + switch (type) { + + case TYPE_DEVICE_ID: + /* Device ID */ + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Device ID: %.*s", + length - 4, + tvb_get_ptr(tvb, offset + 4, length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Device ID: %.*s", + length - 4, + tvb_get_ptr(tvb, offset + 4, length - 4)); + offset += length; + break; + + case TYPE_ADDRESS: + /* Addresses */ + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Addresses"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + offset += 4; + length -= 4; + naddresses = tvb_get_ntohl(tvb, offset); + proto_tree_add_text(tlv_tree, tvb, offset, 4, + "Number of addresses: %u", naddresses); + offset += 4; + length -= 4; + while (naddresses != 0) { + addr_length = dissect_address_tlv(tvb, offset, length, + tlv_tree); + if (addr_length < 0) + break; + offset += addr_length; + length -= addr_length; + + naddresses--; + } + offset += length; + break; + + case TYPE_PORT_ID: + real_length = length; + if (tvb_get_guint8(tvb, offset + real_length) != 0x00) { + /* The length in the TLV doesn't appear to be the + length of the TLV, as the byte just past it + isn't the first byte of a 2-byte big-endian + small integer; make the length of the TLV the length + in the TLV, plus 4 bytes for the TLV type and length, + minus 1 because that's what makes one capture work. */ + real_length = length + 3; } + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + real_length, "Port ID: %.*s", + real_length - 4, + tvb_get_ptr(tvb, offset + 4, real_length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + real_length - 4, + "Sent through Interface: %.*s", + real_length - 4, + tvb_get_ptr(tvb, offset + 4, real_length - 4)); + offset += real_length; + break; + + case TYPE_CAPABILITIES: + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Capabilities"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + offset += 4; + length -= 4; + dissect_capabilities(tvb, offset, length, tlv_tree); + offset += length; + break; + + case TYPE_IOS_VERSION: + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Software Version"); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + add_multi_line_string_to_tree(tlv_tree, tvb, offset + 4, + length - 4, "Software Version: "); + offset += length; + break; + + case TYPE_PLATFORM: + /* ??? platform */ + tlvi = proto_tree_add_text(cdp_tree, tvb, + offset, length, "Platform: %.*s", + length - 4, + tvb_get_ptr(tvb, offset + 4, length - 4)); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Platform: %.*s", + length - 4, + tvb_get_ptr(tvb, offset + 4, length - 4)); + offset += length; + break; + + default: + tlvi = proto_tree_add_text(cdp_tree, tvb, offset, + length, "Type: %s, length: %u", + val_to_str(type, type_vals, "Unknown (0x%04x)"), + length); + tlv_tree = proto_item_add_subtree(tlvi, ett_cdp_tlv); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvtype, tvb, + offset + TLV_TYPE, 2, type); + proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb, + offset + TLV_LENGTH, 2, length); + if (length > 4) { + proto_tree_add_text(tlv_tree, tvb, offset + 4, + length - 4, "Data"); + } else + return; + offset += length; + } } - old_dissect_data(pd, offset, fd, cdp_tree); + dissect_data(tvb, offset, pinfo, cdp_tree); } } @@ -287,7 +284,7 @@ static const value_string proto_type_vals[] = { }; static int -dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) +dissect_address_tlv(tvbuff_t *tvb, int offset, int length, proto_tree *tree) { proto_item *ti; proto_tree *address_tree; @@ -301,10 +298,10 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) if (length < 1) return -1; - ti = proto_tree_add_notext(tree, NullTVB, offset, length); + ti = proto_tree_add_notext(tree, tvb, offset, length); address_tree = proto_item_add_subtree(ti, ett_cdp_address); - protocol_type = pd[offset]; - proto_tree_add_text(address_tree, NullTVB, offset, 1, "Protocol type: %s", + protocol_type = tvb_get_guint8(tvb, offset); + proto_tree_add_text(address_tree, tvb, offset, 1, "Protocol type: %s", val_to_str(protocol_type, proto_type_vals, "Unknown (0x%02x)")); offset += 1; length -= 1; @@ -313,8 +310,8 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) proto_item_set_text(ti, "Truncated address"); return -1; } - protocol_length = pd[offset]; - proto_tree_add_text(address_tree, NullTVB, offset, 1, "Protocol length: %u", + protocol_length = tvb_get_guint8(tvb, offset); + proto_tree_add_text(address_tree, tvb, offset, 1, "Protocol length: %u", protocol_length); offset += 1; length -= 1; @@ -322,20 +319,21 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) if (length < protocol_length) { proto_item_set_text(ti, "Truncated address"); if (length != 0) { - proto_tree_add_text(address_tree, NullTVB, offset, length, - "Protocol: %s (truncated)", bytes_to_str(&pd[offset], length)); + proto_tree_add_text(address_tree, tvb, offset, length, + "Protocol: %s (truncated)", + tvb_bytes_to_str(tvb, offset, length)); } return -1; } protocol_str = NULL; if (protocol_type == PROTO_TYPE_NLPID && protocol_length == 1) { - nlpid = pd[offset]; + nlpid = tvb_get_guint8(tvb, offset); protocol_str = val_to_str(nlpid, nlpid_vals, "Unknown (0x%02x)"); } else nlpid = -1; if (protocol_str == NULL) - protocol_str = bytes_to_str(&pd[offset], protocol_length); - proto_tree_add_text(address_tree, NullTVB, offset, protocol_length, + protocol_str = tvb_bytes_to_str(tvb, offset, protocol_length); + proto_tree_add_text(address_tree, tvb, offset, protocol_length, "Protocol: %s", protocol_str); offset += protocol_length; length -= protocol_length; @@ -344,8 +342,8 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) proto_item_set_text(ti, "Truncated address"); return -1; } - address_length = pntohs(&pd[offset]); - proto_tree_add_text(address_tree, NullTVB, offset, 2, "Address length: %u", + address_length = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(address_tree, tvb, offset, 2, "Address length: %u", address_length); offset += 2; length -= 2; @@ -353,8 +351,9 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) if (length < address_length) { proto_item_set_text(ti, "Truncated address"); if (length != 0) { - proto_tree_add_text(address_tree, NullTVB, offset, length, - "Address: %s (truncated)", bytes_to_str(&pd[offset], length)); + proto_tree_add_text(address_tree, tvb, offset, length, + "Address: %s (truncated)", + tvb_bytes_to_str(tvb, offset, length)); } return -1; } @@ -373,7 +372,7 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) if (address_length == 4) { /* The address is an IP address. */ address_type_str = "IP address"; - address_str = ip_to_str(&pd[offset]); + address_str = ip_to_str(tvb_get_ptr(tvb, offset, 4)); } break; } @@ -381,16 +380,16 @@ dissect_address_tlv(const u_char *pd, int offset, int length, proto_tree *tree) if (address_type_str == NULL) address_type_str = "Address"; if (address_str == NULL) { - address_str = bytes_to_str(&pd[offset], address_length); + address_str = tvb_bytes_to_str(tvb, offset, address_length); } proto_item_set_text(ti, "%s: %s", address_type_str, address_str); - proto_tree_add_text(address_tree, NullTVB, offset, address_length, "%s: %s", + proto_tree_add_text(address_tree, tvb, offset, address_length, "%s: %s", address_type_str, address_str); return 2 + protocol_length + 2 + address_length; } static void -dissect_capabilities(const u_char *pd, int offset, int length, proto_tree *tree) +dissect_capabilities(tvbuff_t *tvb, int offset, int length, proto_tree *tree) { proto_item *ti; proto_tree *capabilities_tree; @@ -398,48 +397,48 @@ dissect_capabilities(const u_char *pd, int offset, int length, proto_tree *tree) if (length < 4) return; - capabilities = pntohl(&pd[offset]); - ti = proto_tree_add_text(tree, NullTVB, offset, length, "Capabilities: 0x%08x", + capabilities = tvb_get_ntohl(tvb, offset); + ti = proto_tree_add_text(tree, tvb, offset, length, "Capabilities: 0x%08x", capabilities); capabilities_tree = proto_item_add_subtree(ti, ett_cdp_capabilities); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x01, 4*8, "Performs level 3 routing", "Doesn't perform level 3 routing")); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x02, 4*8, "Performs level 2 transparent bridging", "Doesn't perform level 2 transparent bridging")); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x04, 4*8, "Performs level 2 source-route bridging", "Doesn't perform level 2 source-route bridging")); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x08, 4*8, "Performs level 2 switching", "Doesn't perform level 2 switching")); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x10, 4*8, "Sends and receives packets for network-layer protocols", "Doesn't send or receive packets for network-layer protocols")); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x20, 4*8, "Doesn't forward IGMP Report packets on nonrouter ports", "Forwards IGMP Report packets on nonrouter ports")); - proto_tree_add_text(capabilities_tree, NullTVB, offset, 4, + proto_tree_add_text(capabilities_tree, tvb, offset, 4, decode_boolean_bitfield(capabilities, 0x40, 4*8, "Provides level 1 functionality", "Doesn't provide level 1 functionality")); } static void -add_multi_line_string_to_tree(proto_tree *tree, gint start, gint len, - const gchar *prefix, const gchar *string) +add_multi_line_string_to_tree(proto_tree *tree, tvbuff_t *tvb, gint start, + gint len, const gchar *prefix) { int prefix_len; int i; char blanks[64+1]; - const gchar *p, *q; + gint next; int line_len; int data_len; @@ -449,22 +448,13 @@ add_multi_line_string_to_tree(proto_tree *tree, gint start, gint len, for (i = 0; i < prefix_len; i++) blanks[i] = ' '; blanks[i] = '\0'; - p = string; - for (;;) { - q = strchr(p, '\n'); - if (q != NULL) { - line_len = q - p; - data_len = line_len + 1; - } else { - line_len = strlen(p); - data_len = line_len; - } - proto_tree_add_text(tree, NullTVB, start, data_len, "%s%.*s", prefix, - line_len, p); - if (q == NULL) - break; - p += data_len; + while (len > 0) { + line_len = tvb_find_line_end(tvb, start, len, &next); + data_len = next - start; + proto_tree_add_text(tree, tvb, start, data_len, "%s%.*s", prefix, + line_len, tvb_get_ptr(tvb, start, line_len)); start += data_len; + len -= data_len; prefix = blanks; } } @@ -472,35 +462,41 @@ add_multi_line_string_to_tree(proto_tree *tree, gint start, gint len, void proto_register_cdp(void) { - static hf_register_info hf[] = { - { &hf_cdp_version, - { "Version", "cdp.version", FT_UINT8, BASE_DEC, NULL, 0x0, - "" }}, - - { &hf_cdp_flags, - { "Flags", "cdp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, - "" }}, - - { &hf_cdp_ttl, - { "TTL", "cdp.ttl", FT_UINT16, BASE_DEC, NULL, 0x0, - "" }}, - - { &hf_cdp_tlvtype, - { "Type", "cdp.tlv.type", FT_UINT16, BASE_HEX, VALS(type_vals), 0x0, - "" }}, - - { &hf_cdp_tlvlength, - { "Length", "cdp.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, - "" }}, - }; - static gint *ett[] = { - &ett_cdp, - &ett_cdp_tlv, - &ett_cdp_address, - &ett_cdp_capabilities, - }; - - proto_cdp = proto_register_protocol("Cisco Discovery Protocol", "cdp"); - proto_register_field_array(proto_cdp, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); + static hf_register_info hf[] = { + { &hf_cdp_version, + { "Version", "cdp.version", FT_UINT8, BASE_DEC, NULL, 0x0, + "" }}, + + { &hf_cdp_ttl, + { "TTL", "cdp.ttl", FT_UINT16, BASE_DEC, NULL, 0x0, + "" }}, + + { &hf_cdp_checksum, + { "Checksum", "cdp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, + "" }}, + + { &hf_cdp_tlvtype, + { "Type", "cdp.tlv.type", FT_UINT16, BASE_HEX, VALS(type_vals), 0x0, + "" }}, + + { &hf_cdp_tlvlength, + { "Length", "cdp.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, + "" }}, + }; + static gint *ett[] = { + &ett_cdp, + &ett_cdp_tlv, + &ett_cdp_address, + &ett_cdp_capabilities, + }; + + proto_cdp = proto_register_protocol("Cisco Discovery Protocol", "cdp"); + proto_register_field_array(proto_cdp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_cdp(void) +{ + dissector_add("llc.cisco_pid", 0x2000, dissect_cdp); } |