diff options
author | Ulf Lamping <ulf.lamping@web.de> | 2006-10-29 13:53:07 +0000 |
---|---|---|
committer | Ulf Lamping <ulf.lamping@web.de> | 2006-10-29 13:53:07 +0000 |
commit | 68187697a00c2f9ce158b6acfae573a1c9457a14 (patch) | |
tree | d47e439e87f6e7f9f5a29fff9cdc01f8b78f503f /epan | |
parent | ffce5685f0fb9be7fb028ef35af4aca58718ea3e (diff) |
make the checksum fields visible for TCP and UDP
svn path=/trunk/; revision=19727
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-tcp.c | 69 | ||||
-rw-r--r-- | epan/dissectors/packet-udp.c | 142 |
2 files changed, 147 insertions, 64 deletions
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", |