forked from osmocom/wireshark
Add code to check the checksums of TCP segments and UDP datagrams;
replace the existing checksummer with a modified version of the BSD checksumming code. Add a flag to the "packet_info" structure to indicate that a packet is the first fragment of a fragmented datagram, so that the checksummers won't try to checksum those. (It doesn't seem to add a lot of CPU overhead, so we don't introduce a flag to disable it, yet. Further checks may be necessary to see whether the overhead is just swamped by other overheads when scanning through a capture dissecting all frames, or if it truly is negligible.) Make the Boolean preference option controlling whether to make the top-level protocol tree item for TCP display a packet summary static to the TCP dissector (it doesn't need to be accessible outside the TCP dissector). svn path=/trunk/; revision=2751
This commit is contained in:
parent
10022aee67
commit
677a1c6dc2
|
@ -1,7 +1,7 @@
|
|||
# Makefile.am
|
||||
# Automake file for Ethereal
|
||||
#
|
||||
# $Id: Makefile.am,v 1.257 2000/12/03 09:18:20 guy Exp $
|
||||
# $Id: Makefile.am,v 1.258 2000/12/13 02:24:21 guy Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@zing.org>
|
||||
|
@ -277,6 +277,8 @@ ETHEREAL_COMMON_SOURCES = \
|
|||
etypes.h \
|
||||
follow.c \
|
||||
follow.h \
|
||||
in_cksum.c \
|
||||
in_cksum.h \
|
||||
ipproto.c \
|
||||
llcsaps.h \
|
||||
nlpid.h \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## Makefile for building ethereal.exe with Microsoft C and nmake
|
||||
## Use: nmake -f makefile.nmake
|
||||
#
|
||||
# $Id: Makefile.nmake,v 1.66 2000/11/30 09:31:50 guy Exp $
|
||||
# $Id: Makefile.nmake,v 1.67 2000/12/13 02:24:21 guy Exp $
|
||||
|
||||
include config.nmake
|
||||
|
||||
|
@ -174,6 +174,7 @@ ETHEREAL_COMMON_OBJECTS = \
|
|||
column.obj \
|
||||
follow.obj \
|
||||
getopt.obj \
|
||||
in_cksum.obj \
|
||||
ipproto.obj \
|
||||
prefs.obj \
|
||||
print.obj \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* packet.h
|
||||
* Definitions for packet disassembly structures and routines
|
||||
*
|
||||
* $Id: packet.h,v 1.14 2000/12/04 06:37:46 guy Exp $
|
||||
* $Id: packet.h,v 1.15 2000/12/13 02:24:23 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -170,7 +170,8 @@ typedef struct _packet_info {
|
|||
address net_dst; /* network-layer destination address */
|
||||
address src; /* source address (net if present, DL otherwise )*/
|
||||
address dst; /* destination address (net if present, DL otherwise )*/
|
||||
guint32 ipproto;
|
||||
guint32 ipproto; /* IP protocol, if this is an IP packet */
|
||||
gboolean fragmented; /* TRUE if the protocol is only a fragment */
|
||||
port_type ptype; /* type of the following two port numbers */
|
||||
guint32 srcport; /* source port */
|
||||
guint32 destport; /* destination port */
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
/* in_cksum.c
|
||||
* 4.4-Lite-2 Internet checksum routine, modified to take a vector of
|
||||
* pointers/lengths giving the pieces to be checksummed.
|
||||
*
|
||||
* $Id: in_cksum.c,v 1.1 2000/12/13 02:24:22 guy Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "in_cksum.h"
|
||||
|
||||
/*
|
||||
* Checksum routine for Internet Protocol family headers (Portable Version).
|
||||
*
|
||||
* This routine is very heavily used in the network
|
||||
* code and should be modified for each CPU to be as fast as possible.
|
||||
*/
|
||||
|
||||
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
|
||||
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
|
||||
|
||||
int
|
||||
in_cksum(const vec_t *vec, int veclen)
|
||||
{
|
||||
register const guint16 *w;
|
||||
register int sum = 0;
|
||||
register int mlen = 0;
|
||||
int byte_swapped = 0;
|
||||
|
||||
union {
|
||||
char c[2];
|
||||
guint16 s;
|
||||
} s_util;
|
||||
union {
|
||||
guint16 s[2];
|
||||
long l;
|
||||
} l_util;
|
||||
|
||||
for (; veclen != 0; vec++, veclen--) {
|
||||
if (vec->len == 0)
|
||||
continue;
|
||||
w = (const guint16 *)vec->ptr;
|
||||
if (mlen == -1) {
|
||||
/*
|
||||
* The first byte of this chunk is the continuation
|
||||
* of a word spanning between this chunk and the
|
||||
* last chunk.
|
||||
*
|
||||
* s_util.c[0] is already saved when scanning previous
|
||||
* chunk.
|
||||
*/
|
||||
s_util.c[1] = *(char *)w;
|
||||
sum += s_util.s;
|
||||
w = (const guint16 *)((const guint8 *)w + 1);
|
||||
mlen = vec->len - 1;
|
||||
} else
|
||||
mlen = vec->len;
|
||||
/*
|
||||
* Force to even boundary.
|
||||
*/
|
||||
if ((1 & (int) w) && (mlen > 0)) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
s_util.c[0] = *(const guint8 *)w;
|
||||
w = (const guint16 *)((const guint8 *)w + 1);
|
||||
mlen--;
|
||||
byte_swapped = 1;
|
||||
}
|
||||
/*
|
||||
* Unroll the loop to make overhead from
|
||||
* branches &c small.
|
||||
*/
|
||||
while ((mlen -= 32) >= 0) {
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
|
||||
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
|
||||
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
|
||||
w += 16;
|
||||
}
|
||||
mlen += 32;
|
||||
while ((mlen -= 8) >= 0) {
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
w += 4;
|
||||
}
|
||||
mlen += 8;
|
||||
if (mlen == 0 && byte_swapped == 0)
|
||||
continue;
|
||||
REDUCE;
|
||||
while ((mlen -= 2) >= 0) {
|
||||
sum += *w++;
|
||||
}
|
||||
if (byte_swapped) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
byte_swapped = 0;
|
||||
if (mlen == -1) {
|
||||
s_util.c[1] = *(char *)w;
|
||||
sum += s_util.s;
|
||||
mlen = 0;
|
||||
} else
|
||||
mlen = -1;
|
||||
} else if (mlen == -1)
|
||||
s_util.c[0] = *(char *)w;
|
||||
}
|
||||
if (mlen == -1) {
|
||||
/* The last mbuf has odd # of bytes. Follow the
|
||||
standard (the odd byte may be shifted left by 8 bits
|
||||
or not as determined by endian-ness of the machine) */
|
||||
s_util.c[1] = 0;
|
||||
sum += s_util.s;
|
||||
}
|
||||
REDUCE;
|
||||
return (~sum & 0xffff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the host-byte-order value of the checksum field in a packet
|
||||
* header, and the one's complement negation of the host-byte-order
|
||||
* checksum of the packet, compute what the checksum field *should*
|
||||
* have been.
|
||||
*/
|
||||
guint16
|
||||
in_cksum_shouldbe(guint16 sum, guint16 computed_sum)
|
||||
{
|
||||
guint32 shouldbe;
|
||||
|
||||
/*
|
||||
* The value that should have gone into the checksum field
|
||||
* is the negative of the value gotten by summing up everything
|
||||
* *but* the checksum field.
|
||||
*
|
||||
* We can compute that by subtracting the value of the checksum
|
||||
* field from the sum of all the data in the packet, and then
|
||||
* computing the negative of that value.
|
||||
*
|
||||
* "sum" is the value of the checksum field, and "computed_sum"
|
||||
* is the negative of the sum of all the data in the packets,
|
||||
* so that's -(-computed_sum - sum), or (sum + computed_sum).
|
||||
*
|
||||
* All the arithmetic in question is one's complement, so the
|
||||
* addition must include an end-around carry; we do this by
|
||||
* doing the arithmetic in 32 bits (with no sign-extension),
|
||||
* and then adding the upper 16 bits of the sum, which contain
|
||||
* the carry, to the lower 16 bits of the sum, and then do it
|
||||
* again in case *that* sum produced a carry.
|
||||
*
|
||||
* As RFC 1071 notes, the checksum can be computed without
|
||||
* byte-swapping the 16-bit words; summing 16-bit words
|
||||
* on a big-endian machine gives a big-endian checksum, which
|
||||
* can be directly stuffed into the big-endian checksum fields
|
||||
* in protocol headers, and summing words on a little-endian
|
||||
* machine gives a little-endian checksum, which must be
|
||||
* byte-swapped before being stuffed into a big-endian checksum
|
||||
* field.
|
||||
*
|
||||
* "computed_sum" is a host-byte-order value, so we must put
|
||||
* it in network byte order before subtracting it from the
|
||||
* network-byte-order value from the header; the adjusted
|
||||
* checksum will be in network byte order, which is what
|
||||
* we'll return.
|
||||
*/
|
||||
shouldbe = sum;
|
||||
shouldbe += htons(computed_sum);
|
||||
shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
|
||||
shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
|
||||
return shouldbe;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* in_cksum.h
|
||||
* Declaration of Internet checksum routine.
|
||||
*
|
||||
* $Id: in_cksum.h,v 1.1 2000/12/13 02:24:22 guy Exp $
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const guint8 *ptr;
|
||||
int len;
|
||||
} vec_t;
|
||||
|
||||
extern int in_cksum(const vec_t *vec, int veclen);
|
||||
|
||||
extern guint16 in_cksum_shouldbe(guint16 sum, guint16 computed_sum);
|
62
packet-ip.c
62
packet-ip.c
|
@ -1,7 +1,7 @@
|
|||
/* packet-ip.c
|
||||
* Routines for IP and miscellaneous IP protocol packet disassembly
|
||||
*
|
||||
* $Id: packet-ip.c,v 1.109 2000/12/08 22:53:08 guy Exp $
|
||||
* $Id: packet-ip.c,v 1.110 2000/12/13 02:24:21 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -52,6 +52,7 @@
|
|||
#include "aftypes.h"
|
||||
#include "packet-ip.h"
|
||||
#include "packet-ipsec.h"
|
||||
#include "in_cksum.h"
|
||||
|
||||
static void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *);
|
||||
static void dissect_igmp(tvbuff_t *, packet_info *, proto_tree *);
|
||||
|
@ -749,49 +750,11 @@ static const true_false_string flags_set_truth = {
|
|||
|
||||
static guint16 ip_checksum(const guint8 *ptr, int len)
|
||||
{
|
||||
unsigned long Sum;
|
||||
const unsigned char *Ptr, *PtrEnd;
|
||||
vec_t cksum_vec[1];
|
||||
|
||||
Sum = 0;
|
||||
PtrEnd = ptr + len;
|
||||
for (Ptr = ptr; Ptr < PtrEnd; Ptr += 2) {
|
||||
Sum += pntohs(Ptr);
|
||||
}
|
||||
Sum = (Sum & 0xFFFF) + (Sum >> 16);
|
||||
Sum = (Sum & 0xFFFF) + (Sum >> 16);
|
||||
|
||||
return (guint16)~Sum;
|
||||
}
|
||||
|
||||
static guint16 ip_checksum_shouldbe(guint16 sum, guint16 computed_sum)
|
||||
{
|
||||
guint32 shouldbe;
|
||||
|
||||
/*
|
||||
* The value that should have gone into the checksum field
|
||||
* is the negative of the value gotten by summing up everything
|
||||
* *but* the checksum field.
|
||||
*
|
||||
* We can compute that by subtracting the value of the checksum
|
||||
* field from the sum of all the data in the packet, and then
|
||||
* computing the negative of that value.
|
||||
*
|
||||
* "sum" is the value of the checksum field, and "computed_sum"
|
||||
* is the negative of the sum of all the data in the packets,
|
||||
* so that's -(-computed_sum - sum), or (sum + computed_sum).
|
||||
*
|
||||
* All the arithmetic in question is one's complement, so the
|
||||
* addition must include an end-around carry; we do this by
|
||||
* doing the arithmetic in 32 bits (with no sign-extension),
|
||||
* and then adding the upper 16 bits of the sum, which contain
|
||||
* the carry, to the lower 16 bits of the sum, and then do it
|
||||
* again in case *that* sum produced a carry.
|
||||
*/
|
||||
shouldbe = sum;
|
||||
shouldbe += computed_sum;
|
||||
shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
|
||||
shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
|
||||
return shouldbe;
|
||||
cksum_vec[0].ptr = ptr;
|
||||
cksum_vec[0].len = len;
|
||||
return in_cksum(&cksum_vec[0], 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -902,7 +865,7 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
else {
|
||||
proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum,
|
||||
"Header checksum: 0x%04x (incorrect, should be 0x%04x)", iph.ip_sum,
|
||||
ip_checksum_shouldbe(iph.ip_sum, ipsum));
|
||||
in_cksum_shouldbe(iph.ip_sum, ipsum));
|
||||
}
|
||||
|
||||
proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, iph.ip_src);
|
||||
|
@ -945,6 +908,15 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is the first fragment, but not the only fragment,
|
||||
* tell the next protocol that.
|
||||
*/
|
||||
if (iph.ip_off & IP_MF)
|
||||
pinfo->fragmented = TRUE;
|
||||
else
|
||||
pinfo->fragmented = FALSE;
|
||||
|
||||
/* Hand off to the next protocol.
|
||||
|
||||
XXX - setting the columns only after trying various dissectors means
|
||||
|
@ -1126,7 +1098,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2,
|
||||
cksum,
|
||||
"Checksum: 0x%04x (incorrect, should be 0x%04x)",
|
||||
cksum, ip_checksum_shouldbe(cksum, computed_cksum));
|
||||
cksum, in_cksum_shouldbe(cksum, computed_cksum));
|
||||
}
|
||||
} else {
|
||||
proto_tree_add_uint(icmp_tree, hf_icmp_checksum, tvb, 2, 2, cksum);
|
||||
|
|
68
packet-tcp.c
68
packet-tcp.c
|
@ -1,7 +1,7 @@
|
|||
/* packet-tcp.c
|
||||
* Routines for TCP packet disassembly
|
||||
*
|
||||
* $Id: packet-tcp.c,v 1.91 2000/12/04 06:37:44 guy Exp $
|
||||
* $Id: packet-tcp.c,v 1.92 2000/12/13 02:24:21 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -38,6 +38,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include "in_cksum.h"
|
||||
|
||||
#ifdef NEED_SNPRINTF_H
|
||||
# include "snprintf.h"
|
||||
|
@ -54,7 +55,7 @@
|
|||
#include "strutil.h"
|
||||
|
||||
/* Place TCP summary in proto tree */
|
||||
gboolean g_tcp_summary_in_tree = TRUE;
|
||||
static gboolean tcp_summary_in_tree = TRUE;
|
||||
|
||||
extern FILE* data_out_file;
|
||||
|
||||
|
@ -434,6 +435,11 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
guint optlen;
|
||||
guint32 seglen;
|
||||
guint32 nxtseq;
|
||||
guint len;
|
||||
guint reported_len;
|
||||
vec_t cksum_vec[4];
|
||||
guint32 phdr[2];
|
||||
guint16 computed_cksum;
|
||||
guint length_remaining;
|
||||
|
||||
CHECK_DISPLAY_AS_DATA(proto_tcp, tvb, pinfo, tree);
|
||||
|
@ -478,8 +484,11 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
|
||||
hlen = hi_nibble(th.th_off_x2) * 4; /* TCP header length, in bytes */
|
||||
|
||||
reported_len = tvb_reported_length(tvb);
|
||||
len = tvb_length(tvb);
|
||||
|
||||
/* Compute the length of data in this segment. */
|
||||
seglen = tvb_reported_length(tvb) - hlen;
|
||||
seglen = reported_len - hlen;
|
||||
|
||||
/* Compute the sequence number of next octet after this segment. */
|
||||
nxtseq = th.th_seq + seglen;
|
||||
|
@ -496,7 +505,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
}
|
||||
|
||||
if (tree) {
|
||||
if (g_tcp_summary_in_tree) {
|
||||
if (tcp_summary_in_tree) {
|
||||
ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, offset, hlen, "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u), Seq: %u, Ack: %u", get_tcp_port(th.th_sport), th.th_sport, get_tcp_port(th.th_dport), th.th_dport, th.th_seq, th.th_ack);
|
||||
}
|
||||
else {
|
||||
|
@ -528,7 +537,52 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th.th_win);
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_checksum, tvb, offset + 16, 2, th.th_sum);
|
||||
if (!pinfo->fragmented && len >= reported_len) {
|
||||
/* The packet isn't part of a fragmented datagram and isn't
|
||||
truncated, so we can checksum it.
|
||||
XXX - make a bigger scatter-gather list once we do fragment
|
||||
reassembly? */
|
||||
|
||||
/* 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] = htonl((IP_PROTO_TCP<<16) + reported_len);
|
||||
cksum_vec[2].len = 4;
|
||||
break;
|
||||
|
||||
case AT_IPv6:
|
||||
phdr[0] = htonl(reported_len);
|
||||
phdr[1] = htonl(IP_PROTO_TCP);
|
||||
cksum_vec[2].len = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TCP runs only atop IPv4 and IPv6.... */
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
|
||||
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,
|
||||
offset + 16, 2, th.th_sum, "Checksum: 0x%04x (correct)", th.th_sum);
|
||||
} else {
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
|
||||
offset + 16, 2, th.th_sum,
|
||||
"Checksum: 0x%04x (incorrect, should be 0x%04x)", th.th_sum,
|
||||
in_cksum_shouldbe(th.th_sum, computed_cksum));
|
||||
}
|
||||
} else {
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
|
||||
offset + 16, 2, th.th_sum, "Checksum: 0x%04x", th.th_sum);
|
||||
}
|
||||
if (th.th_flags & TH_URG)
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th.th_urp);
|
||||
}
|
||||
|
@ -689,12 +743,12 @@ proto_register_tcp(void)
|
|||
subdissector_table = register_dissector_table("tcp.port");
|
||||
register_heur_dissector_list("tcp", &heur_subdissector_list);
|
||||
|
||||
/* Register a configuration preferences */
|
||||
/* Register configuration preferences */
|
||||
tcp_module = prefs_register_module("tcp", "TCP", NULL);
|
||||
prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
|
||||
"Show TCP summary in protocol tree",
|
||||
"Whether the TCP summary line should be shown in the protocol tree",
|
||||
&g_tcp_summary_in_tree);
|
||||
&tcp_summary_in_tree);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
62
packet-udp.c
62
packet-udp.c
|
@ -1,7 +1,7 @@
|
|||
/* packet-udp.c
|
||||
* Routines for UDP packet disassembly
|
||||
*
|
||||
* $Id: packet-udp.c,v 1.79 2000/11/19 08:54:10 guy Exp $
|
||||
* $Id: packet-udp.c,v 1.80 2000/12/13 02:24:21 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
|
@ -44,6 +44,7 @@
|
|||
#include <glib.h>
|
||||
#include "globals.h"
|
||||
#include "resolv.h"
|
||||
#include "in_cksum.h"
|
||||
|
||||
#include "plugins.h"
|
||||
#include "packet-udp.h"
|
||||
|
@ -144,6 +145,11 @@ dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
guint16 uh_sport, uh_dport, uh_ulen, uh_sum;
|
||||
proto_tree *udp_tree;
|
||||
proto_item *ti;
|
||||
guint len;
|
||||
guint reported_len;
|
||||
vec_t cksum_vec[4];
|
||||
guint32 phdr[2];
|
||||
guint16 computed_cksum;
|
||||
int offset = 0;
|
||||
|
||||
CHECK_DISPLAY_AS_DATA(proto_udp, tvb, pinfo, tree);
|
||||
|
@ -176,8 +182,58 @@ dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset+2, 2, uh_dport);
|
||||
|
||||
proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2, uh_ulen);
|
||||
proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, uh_sum,
|
||||
"Checksum: 0x%04x", uh_sum);
|
||||
reported_len = tvb_reported_length(tvb);
|
||||
len = tvb_length(tvb);
|
||||
if (uh_sum == 0) {
|
||||
/* No checksum supplied in the packet. */
|
||||
proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
|
||||
offset + 6, 2, uh_sum, "Checksum: 0x%04x (none)", uh_sum);
|
||||
} else if (!pinfo->fragmented && len >= reported_len) {
|
||||
/* The packet isn't part of a fragmented datagram and isn't
|
||||
truncated, so we can checksum it.
|
||||
XXX - make a bigger scatter-gather list once we do fragment
|
||||
reassembly? */
|
||||
|
||||
/* 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] = htonl((IP_PROTO_UDP<<16) + reported_len);
|
||||
cksum_vec[2].len = 4;
|
||||
break;
|
||||
|
||||
case AT_IPv6:
|
||||
phdr[0] = htonl(reported_len);
|
||||
phdr[1] = htonl(IP_PROTO_UDP);
|
||||
cksum_vec[2].len = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TCP runs only atop IPv4 and IPv6.... */
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
|
||||
cksum_vec[3].len = reported_len;
|
||||
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, uh_sum, "Checksum: 0x%04x (correct)", uh_sum);
|
||||
} else {
|
||||
proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
|
||||
offset + 6, 2, uh_sum,
|
||||
"Checksum: 0x%04x (incorrect, should be 0x%04x)", uh_sum,
|
||||
in_cksum_shouldbe(uh_sum, computed_cksum));
|
||||
}
|
||||
} else {
|
||||
proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
|
||||
offset + 6, 2, uh_sum, "Checksum: 0x%04x", uh_sum);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip over header */
|
||||
|
|
Loading…
Reference in New Issue