* Routines for the disassembly of the "Cisco Discovery Protocol"
* (c) Copyright Hannes R. Boehm <hannes@boehm.org>
*
- * $Id: packet-cdp.c,v 1.36 2001/03/15 09:11:00 guy Exp $
+ * $Id: packet-cdp.c,v 1.49 2002/08/28 21:00:08 jmayer Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
- *
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
-#include "config.h"
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
+#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
-#include "packet.h"
-#include "strutil.h"
+#include <epan/packet.h>
+#include <epan/strutil.h>
#include "nlpid.h"
/*
static gint ett_cdp_address = -1;
static gint ett_cdp_capabilities = -1;
+static dissector_handle_t data_handle;
+
static int
dissect_address_tlv(tvbuff_t *tvb, int offset, int length, proto_tree *tree);
static void
{ TYPE_DUPLEX, "Duplex" },
{ 0, NULL },
};
-
-static void
+
+static void
dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_item *ti;
+ proto_item *ti;
proto_tree *cdp_tree = NULL;
int offset = 0;
guint16 type;
guint32 naddresses;
int addr_length;
- 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 (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "CDP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_set_str(pinfo->cinfo, COL_INFO, "Cisco Discovery Protocol");
if (tree){
- ti = proto_tree_add_item(tree, proto_cdp, tvb, offset,
- tvb_length_remaining(tvb, offset), FALSE);
+ ti = proto_tree_add_item(tree, proto_cdp, tvb, offset, -1, FALSE);
cdp_tree = proto_item_add_subtree(ti, ett_cdp);
-
+
/* CDP header */
proto_tree_add_item(cdp_tree, hf_cdp_version, tvb, offset, 1, FALSE);
offset += 1;
while (tvb_reported_length_remaining(tvb, offset) != 0) {
type = tvb_get_ntohs(tvb, offset + TLV_TYPE);
length = tvb_get_ntohs(tvb, offset + TLV_LENGTH);
+ if (length < 4) {
+ tlvi = proto_tree_add_text(cdp_tree, tvb, offset, 4,
+ "TLV with invalid length %u (< 4)",
+ 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);
+ offset += 4;
+ break;
+ }
switch (type) {
/* the actual number of prefixes is (length-4)/5
but if the variable is not a "float" but "integer"
then length/5=(length-4)/5 :) */
-
+
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);
+ offset + TLV_TYPE, 2, type);
proto_tree_add_uint(tlv_tree, hf_cdp_tlvlength, tvb,
offset + TLV_LENGTH, 2, length);
offset += 4;
offset += length;
}
}
- dissect_data(tvb, offset, pinfo, cdp_tree);
+ call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo,
+ cdp_tree);
}
}
if (length < 1)
return -1;
- ti = proto_tree_add_notext(tree, tvb, offset, length);
+ ti = proto_tree_add_text(tree, tvb, offset, length, "Truncated address");
address_tree = proto_item_add_subtree(ti, ett_cdp_address);
protocol_type = tvb_get_guint8(tvb, offset);
proto_tree_add_text(address_tree, tvb, offset, 1, "Protocol type: %s",
offset += 1;
length -= 1;
- if (length < 1) {
- proto_item_set_text(ti, "Truncated address");
+ if (length < 1)
return -1;
- }
protocol_length = tvb_get_guint8(tvb, offset);
proto_tree_add_text(address_tree, tvb, offset, 1, "Protocol length: %u",
protocol_length);
length -= 1;
if (length < protocol_length) {
- proto_item_set_text(ti, "Truncated address");
if (length != 0) {
proto_tree_add_text(address_tree, tvb, offset, length,
"Protocol: %s (truncated)",
offset += protocol_length;
length -= protocol_length;
- if (length < 2) {
- proto_item_set_text(ti, "Truncated address");
+ if (length < 2)
return -1;
- }
address_length = tvb_get_ntohs(tvb, offset);
proto_tree_add_text(address_tree, tvb, offset, 2, "Address length: %u",
address_length);
length -= 2;
if (length < address_length) {
- proto_item_set_text(ti, "Truncated address");
if (length != 0) {
proto_tree_add_text(address_tree, tvb, offset, length,
"Address: %s (truncated)",
blanks[i] = ' ';
blanks[i] = '\0';
while (len > 0) {
- line_len = tvb_find_line_end(tvb, start, len, &next);
+ line_len = tvb_find_line_end(tvb, start, len, &next, FALSE);
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));
static hf_register_info hf[] = {
{ &hf_cdp_version,
{ "Version", "cdp.version", FT_UINT8, BASE_DEC, NULL, 0x0,
- "" }},
+ "", HFILL }},
{ &hf_cdp_ttl,
{ "TTL", "cdp.ttl", FT_UINT16, BASE_DEC, NULL, 0x0,
- "" }},
+ "", HFILL }},
{ &hf_cdp_checksum,
{ "Checksum", "cdp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
- "" }},
+ "", HFILL }},
{ &hf_cdp_tlvtype,
{ "Type", "cdp.tlv.type", FT_UINT16, BASE_HEX, VALS(type_vals), 0x0,
- "" }},
+ "", HFILL }},
{ &hf_cdp_tlvlength,
{ "Length", "cdp.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0,
- "" }},
+ "", HFILL }},
};
static gint *ett[] = {
&ett_cdp,
void
proto_reg_handoff_cdp(void)
{
- dissector_add("llc.cisco_pid", 0x2000, dissect_cdp, proto_cdp);
- dissector_add("chdlctype", 0x2000, dissect_cdp, proto_cdp);
+ dissector_handle_t cdp_handle;
+
+ data_handle = find_dissector("data");
+ cdp_handle = create_dissector_handle(dissect_cdp, proto_cdp);
+ dissector_add("llc.cisco_pid", 0x2000, cdp_handle);
+ dissector_add("chdlctype", 0x2000, cdp_handle);
+ dissector_add("ppp.protocol", 0x0207, cdp_handle);
}