@ICMP@icmp@[49680,49737,65535][0,0,0]
@TCP RST@tcp.flags.reset eq 1@[37008,0,0][65535,63121,32911]
@Low TTL@ip.ttl < 5@[37008,0,0][65535,65535,65535]
-@Checksum Errors@edp.checksum_bad==1 || ip.checksum_bad==1 || tcp.checksum_bad==1 || udp.checksum_bad==1@[0,0,0][65535,24383,24383]
+@Checksum Errors@cdp.checksum_bad==1 || edp.checksum_bad==1 || ip.checksum_bad==1 || tcp.checksum_bad==1 || udp.checksum_bad==1@[0,0,0][65535,24383,24383]
@SMB@smb || nbss || nbns || nbipx || ipxsap || netbios@[65534,64008,39339][0,0,0]
@HTTP@http || tcp.port == 80@[36107,65535,32590][0,0,0]
@IPX@ipx || spx@[65534,58325,58808][0,0,0]
#include <glib.h>
#include <epan/packet.h>
#include <epan/strutil.h>
+#include <epan/in_cksum.h>
#include <epan/oui.h>
#include <epan/nlpid.h>
static int proto_cdp = -1;
static int hf_cdp_version = -1;
static int hf_cdp_checksum = -1;
+static int hf_cdp_checksum_good = -1;
+static int hf_cdp_checksum_bad = -1;
static int hf_cdp_ttl = -1;
static int hf_cdp_tlvtype = -1;
static int hf_cdp_tlvlength = -1;
static gint ett_cdp_tlv = -1;
static gint ett_cdp_address = -1;
static gint ett_cdp_capabilities = -1;
+static gint ett_cdp_checksum = -1;
static dissector_handle_t data_handle;
static void
dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_item *ti;
- proto_tree *cdp_tree = NULL;
+ proto_item *ti, *checksum_item;
+ proto_tree *cdp_tree = NULL, *checksum_tree;
int offset = 0;
guint16 type;
- guint16 length;
+ guint16 length, packet_checksum, computed_checksum, data_length;
+ gboolean checksum_good, checksum_bad;
proto_item *tlvi;
proto_tree *tlv_tree;
int real_length;
guint32 naddresses;
int addr_length;
guint32 ip_addr;
+ vec_t cksum_vec[1];
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "CDP");
/* CDP header */
proto_tree_add_item(cdp_tree, hf_cdp_version, tvb, offset, 1, FALSE);
offset += 1;
+
proto_tree_add_uint_format_value(cdp_tree, hf_cdp_ttl, tvb, offset, 1,
tvb_get_guint8(tvb, offset),
"%u seconds",
tvb_get_guint8(tvb, offset));
offset += 1;
- proto_tree_add_item(cdp_tree, hf_cdp_checksum, tvb, offset, 2, FALSE);
- offset += 2;
- }
- else
- {
- offset += 4; /* The version/ttl/checksum fields from above */
- }
+ } else {
+ offset += 2; /* The version/ttl fields from above */
+ }
+ /* Checksum display & verification code */
+ packet_checksum = tvb_get_ntohs(tvb, offset);
+
+ data_length = tvb_reported_length(tvb);
+
+ cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, data_length);
+ cksum_vec[0].len = data_length;
+
+ computed_checksum = in_cksum(cksum_vec, 1);
+ checksum_good = (computed_checksum == 0);
+ checksum_bad = !checksum_good;
+ if (checksum_good) {
+ checksum_item = proto_tree_add_uint_format(cdp_tree,
+ hf_cdp_checksum, tvb, offset, 2, packet_checksum,
+ "Checksum: 0x%04x [correct]", packet_checksum);
+ } else {
+ checksum_item = proto_tree_add_uint_format(cdp_tree,
+ hf_cdp_checksum, tvb, offset, 2, packet_checksum,
+ "Checksum: 0x%04x [incorrect, should be 0x%04x]",
+ packet_checksum,
+ in_cksum_shouldbe(packet_checksum, computed_checksum));
+ }
+
+ checksum_tree = proto_item_add_subtree(checksum_item, ett_cdp_checksum);
+ checksum_item = proto_tree_add_boolean(checksum_tree, hf_cdp_checksum_good,
+ tvb, offset, 2, checksum_good);
+ PROTO_ITEM_SET_GENERATED(checksum_item);
+ checksum_item = proto_tree_add_boolean(checksum_tree, hf_cdp_checksum_bad,
+ tvb, offset, 2, checksum_bad);
+ PROTO_ITEM_SET_GENERATED(checksum_item);
+
+ offset += 2;
+
while (tvb_reported_length_remaining(tvb, offset) != 0) {
type = tvb_get_ntohs(tvb, offset + TLV_TYPE);
length = tvb_get_ntohs(tvb, offset + TLV_LENGTH);
{ "Checksum", "cdp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
"", HFILL }},
+ { &hf_cdp_checksum_good,
+ { "Good", "cdp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
+
+ { &hf_cdp_checksum_bad,
+ { "Bad ", "cdp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
+
{ &hf_cdp_tlvtype,
{ "Type", "cdp.tlv.type", FT_UINT16, BASE_HEX, VALS(type_vals), 0x0,
"", HFILL }},
&ett_cdp_tlv,
&ett_cdp_address,
&ett_cdp_capabilities,
+ &ett_cdp_checksum
};
proto_cdp = proto_register_protocol("Cisco Discovery Protocol",