aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2006-10-29 13:53:07 +0000
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2006-10-29 13:53:07 +0000
commitc6d3a11ee7c2a13a4e76085f24444307a39fd0fc (patch)
treed47e439e87f6e7f9f5a29fff9cdc01f8b78f503f
parenta1bfe6b8fb544455c6adc23b968abbb0f44b6d47 (diff)
make the checksum fields visible for TCP and UDP
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@19727 f5534014-38df-0310-8fa8-9805f1628bb7
-rw-r--r--colorfilters2
-rw-r--r--epan/dissectors/packet-tcp.c69
-rw-r--r--epan/dissectors/packet-udp.c142
3 files changed, 148 insertions, 65 deletions
diff --git a/colorfilters b/colorfilters
index a4fd7d89d7..39d5b39411 100644
--- a/colorfilters
+++ b/colorfilters
@@ -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 || udp.checksum_bad@[0,0,0][65535,24383,24383]
+@Checksum Errors@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]
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 228f4295a8..acc926f136 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -88,6 +88,7 @@ static int hf_tcp_flags_fin = -1;
static int hf_tcp_window_size = -1;
static int hf_tcp_checksum = -1;
static int hf_tcp_checksum_bad = -1;
+static int hf_tcp_checksum_good = -1;
static int hf_tcp_len = -1;
static int hf_tcp_urgent_pointer = -1;
static int hf_tcp_analysis_flags = -1;
@@ -147,6 +148,7 @@ static gint ett_tcp_analysis = -1;
static gint ett_tcp_analysis_faults = -1;
static gint ett_tcp_segments = -1;
static gint ett_tcp_segment = -1;
+static gint ett_tcp_checksum = -1;
/* not all of the hf_fields below make sense for TCP but we have to provide
@@ -2076,6 +2078,9 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
struct tcpheader *tcph;
proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
struct tcp_analysis *tcpd=NULL;
+ proto_item *item;
+ proto_tree *checksum_tree;
+
tcph=ep_alloc(sizeof(struct tcpheader));
SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
@@ -2355,31 +2360,48 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
cksum_vec[3].len = reported_len;
computed_cksum = in_cksum(&cksum_vec[0], 4);
if (computed_cksum == 0) {
- proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
+ item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
+ checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
+ offset + 16, 2, TRUE);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+
/* Checksum is valid, so we're willing to desegment it. */
desegment_ok = TRUE;
} else if (th_sum == 0) {
/* checksum is probably fine but checksum offload is used */
- proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
+ item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
offset + 16, 2, th_sum, "Checksum: 0x%04x [Checksum Offloaded]", th_sum);
+ checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+
/* Checksum is (probably) valid, so we're willing to desegment it. */
desegment_ok = TRUE;
} else {
- proto_item *item;
-
item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
offset + 16, 2, th_sum,
- "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by checksum offloading?)]", th_sum,
+ "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by \"TCP checksum offload\"?)]", th_sum,
in_cksum_shouldbe(th_sum, computed_cksum));
- expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
- item = proto_tree_add_boolean(tcp_tree, hf_tcp_checksum_bad, tvb,
+
+ checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
offset + 16, 2, TRUE);
PROTO_ITEM_SET_GENERATED(item);
- /* XXX - don't use hidden fields for checksums */
- PROTO_ITEM_SET_HIDDEN(item);
+ expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
@@ -2389,18 +2411,34 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
pinfo->noreassembly_reason = " [incorrect TCP checksum]";
}
} else {
- proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
+ item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
+ checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+
/* We didn't check the checksum, and don't care if it's valid,
so we're willing to desegment it. */
desegment_ok = TRUE;
}
} else {
/* We don't have all the packet data, so we can't checksum it... */
- proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
+ item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
+ checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
+ offset + 16, 2, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+
/* ...and aren't willing to desegment it. */
desegment_ok = FALSE;
}
@@ -2649,9 +2687,13 @@ proto_register_tcp(void)
{ "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
"Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
+ { &hf_tcp_checksum_good,
+ { "Good Checksum", "tcp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
+
{ &hf_tcp_checksum_bad,
{ "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "Maybe caused by checksum offloading, see: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
+ "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
{ &hf_tcp_analysis_flags,
{ "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
@@ -2866,7 +2908,8 @@ proto_register_tcp(void)
&ett_tcp_analysis_faults,
&ett_tcp_analysis,
&ett_tcp_segments,
- &ett_tcp_segment
+ &ett_tcp_segment,
+ &ett_tcp_checksum
};
module_t *tcp_module;
diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c
index 842ee36d70..a8a685a5e6 100644
--- a/epan/dissectors/packet-udp.c
+++ b/epan/dissectors/packet-udp.c
@@ -58,9 +58,11 @@ static int hf_udp_length = -1;
static int hf_udplite_checksum_coverage = -1;
static int hf_udplite_checksum_coverage_bad = -1;
static int hf_udp_checksum = -1;
+static int hf_udp_checksum_good = -1;
static int hf_udp_checksum_bad = -1;
static gint ett_udp = -1;
+static gint ett_udp_checksum = -1;
/* Preferences */
@@ -176,6 +178,8 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
int offset = 0;
static e_udphdr udphstruct[4], *udph;
static int udph_count=0;
+ proto_tree *checksum_tree;
+ proto_item *item;
udph_count++;
if(udph_count>=4){
@@ -272,12 +276,22 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
if (udph->uh_sum == 0) {
/* No checksum supplied in the packet. */
if (ip_proto == IP_PROTO_UDP) {
- proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
+ item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
"Checksum: 0x%04x (none)", 0);
+
+ checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
+ offset + 6, 2, FALSE);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
+ offset + 6, 2, FALSE);
} else {
- proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
+ item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
"Checksum: 0x%04x (Illegal)", 0);
- proto_tree_add_boolean_hidden(udp_tree, hf_udp_checksum_bad, tvb,
+
+ checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
+ offset + 6, 2, FALSE);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
offset + 6, 2, TRUE);
}
} else if (!pinfo->fragmented && len >= reported_len &&
@@ -290,54 +304,75 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
if (((ip_proto == IP_PROTO_UDP) && (udp_check_checksum)) ||
((ip_proto == IP_PROTO_UDPLITE) && (udplite_check_checksum))) {
- /* Set up the fields of the pseudo-header. */
- cksum_vec[0].ptr = pinfo->src.data;
- cksum_vec[0].len = pinfo->src.len;
- cksum_vec[1].ptr = pinfo->dst.data;
- cksum_vec[1].len = pinfo->dst.len;
- cksum_vec[2].ptr = (const guint8 *)&phdr;
- switch (pinfo->src.type) {
-
- case AT_IPv4:
- phdr[0] = g_htonl((ip_proto<<16) + reported_len);
- cksum_vec[2].len = 4;
- break;
-
- case AT_IPv6:
- phdr[0] = g_htonl(reported_len);
- phdr[1] = g_htonl(ip_proto);
- cksum_vec[2].len = 8;
- break;
-
- default:
- /* UDP runs only atop IPv4 and IPv6.... */
- DISSECTOR_ASSERT_NOT_REACHED();
- break;
- }
- cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, udph->uh_sum_cov);
- cksum_vec[3].len = udph->uh_sum_cov;
- computed_cksum = in_cksum(&cksum_vec[0], 4);
- if (computed_cksum == 0) {
- proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
- offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [correct]", udph->uh_sum);
- } else {
- proto_tree_add_boolean_hidden(udp_tree, hf_udp_checksum_bad, tvb,
- offset + 6, 2, TRUE);
- proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
- offset + 6, 2, udph->uh_sum,
- "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by checksum offloading?)]", udph->uh_sum,
- in_cksum_shouldbe(udph->uh_sum, computed_cksum));
- }
+ /* Set up the fields of the pseudo-header. */
+ cksum_vec[0].ptr = pinfo->src.data;
+ cksum_vec[0].len = pinfo->src.len;
+ cksum_vec[1].ptr = pinfo->dst.data;
+ cksum_vec[1].len = pinfo->dst.len;
+ cksum_vec[2].ptr = (const guint8 *)&phdr;
+ switch (pinfo->src.type) {
+
+ case AT_IPv4:
+ phdr[0] = g_htonl((ip_proto<<16) + reported_len);
+ cksum_vec[2].len = 4;
+ break;
+
+ case AT_IPv6:
+ phdr[0] = g_htonl(reported_len);
+ phdr[1] = g_htonl(ip_proto);
+ cksum_vec[2].len = 8;
+ break;
+
+ default:
+ /* UDP runs only atop IPv4 and IPv6.... */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ break;
+ }
+ cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, udph->uh_sum_cov);
+ cksum_vec[3].len = udph->uh_sum_cov;
+ computed_cksum = in_cksum(&cksum_vec[0], 4);
+ if (computed_cksum == 0) {
+ item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
+ offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [correct]", udph->uh_sum);
+
+ checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
+ offset + 6, 2, TRUE);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
+ offset + 6, 2, FALSE);
} else {
- proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
- offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [validation disabled]", udph->uh_sum);
+ item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
+ offset + 6, 2, udph->uh_sum,
+ "Checksum: 0x%04x [incorrect, should be 0x%04x]", udph->uh_sum,
+ in_cksum_shouldbe(udph->uh_sum, computed_cksum));
+
+ checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
+ offset + 6, 2, FALSE);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
+ offset + 6, 2, TRUE);
}
} else {
- proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
+ item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
+ offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [validation disabled]", udph->uh_sum);
+ checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
+ offset + 6, 2, FALSE);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
+ offset + 6, 2, FALSE);
+ }
+ } else {
+ item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x", udph->uh_sum);
+
+ checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
+ offset + 6, 2, FALSE);
+ proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
+ offset + 6, 2, FALSE);
}
}
-
+
/* Skip over header */
offset += 8;
@@ -396,15 +431,19 @@ proto_register_udp(void)
{ &hf_udp_length,
{ "Length", "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "", HFILL }},
+
+ { &hf_udp_checksum,
+ { "Checksum", "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
"Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
+ { &hf_udp_checksum_good,
+ { "Good Checksum", "udp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
+
{ &hf_udp_checksum_bad,
{ "Bad Checksum", "udp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
- "Maybe caused by checksum offloading, see: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
-
- { &hf_udp_checksum,
- { "Checksum", "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
- "", HFILL }}
+ "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }}
};
static hf_register_info hf_lite[] = {
@@ -418,7 +457,8 @@ proto_register_udp(void)
};
static gint *ett[] = {
- &ett_udp
+ &ett_udp,
+ &ett_udp_checksum
};
proto_udp = proto_register_protocol("User Datagram Protocol",