Add checksum verification to the CDP dissector and add an entry for this
authorStephen Fisher <steve@stephen-fisher.com>
Thu, 14 Dec 2006 03:34:26 +0000 (03:34 -0000)
committerStephen Fisher <steve@stephen-fisher.com>
Thu, 14 Dec 2006 03:34:26 +0000 (03:34 -0000)
in the main colorfilters file.

svn path=/trunk/; revision=20134

colorfilters
epan/dissectors/packet-cdp.c

index 39d5b394117d41b15ab7330851c989a1b8cd0c7b..e4f4fecd7746a704dab56c68f54bf678a1923ab3 100644 (file)
@@ -8,7 +8,7 @@
 @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]
index 4ccd7d335a3ab61be53936ab6ef67e1e97f58e08..6c4ce5f88e840822dc7ac74f4483663f15785a51 100644 (file)
@@ -31,6 +31,7 @@
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/strutil.h>
+#include <epan/in_cksum.h>
 
 #include <epan/oui.h>
 #include <epan/nlpid.h>
@@ -57,6 +58,8 @@
 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;
@@ -65,6 +68,7 @@ static gint ett_cdp = -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;
 
@@ -136,17 +140,19 @@ static const value_string type_hello_vals[] = {
 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");
@@ -160,19 +166,49 @@ dissect_cdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        /* 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);
@@ -890,6 +926,14 @@ proto_register_cdp(void)
        { "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 }},
@@ -903,6 +947,7 @@ proto_register_cdp(void)
        &ett_cdp_tlv,
        &ett_cdp_address,
        &ett_cdp_capabilities,
+       &ett_cdp_checksum
     };
 
     proto_cdp = proto_register_protocol("Cisco Discovery Protocol",