forked from osmocom/wireshark
Have a flag in the "packet_info" structure, which indicates whether the
stuff currently being dissected is part of a packet included in an error packet (e.g., an ICMP Unreachable packet). Have the TCP dissector not bother doing reassembly if the TCP segment is part of an error packet, rather than an actual TCP transmission; other dissectors might want to treat those packets specially as well. Add to the "tcpinfo" structure a flag indicating whether the URG flag was set, rather than having the zero or non-zero value of the urgent pointer indicate that. (Yes, at least as I read RFC 793, a zero urgent pointer value isn't useful, as it means "the stuff before this segment is urgent", but it's certainly possible to put onto the wire a TCP segment with URG set and a zero urgent pointer.) Don't dissect the TCP header by grabbing the entire header with "tvb_memcpy()" and then pulling stuff out of it - extract stuff with individual tvbuff calls, and put stuff into the protocol tree and the Info column as we extract it, so that we can dissect a partial header. This lets us, for example, get the source and destination ports from the TCP header of the part of a TCP segment included in a minimum-length ICMPv4 error packet. svn path=/trunk/; revision=3986
This commit is contained in:
parent
3869ff8bfb
commit
d627904aba
|
@ -1,7 +1,7 @@
|
|||
/* packet_info.c
|
||||
* Routines for handling packet information
|
||||
*
|
||||
* $Id: packet_info.c,v 1.2 2001/08/04 04:04:35 guy Exp $
|
||||
* $Id: packet_info.c,v 1.3 2001/10/01 08:29:37 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -40,6 +40,8 @@ void blank_packetinfo(void)
|
|||
pi.dst.type = AT_NONE;
|
||||
pi.ethertype = 0;
|
||||
pi.ipproto = 0;
|
||||
pi.ipxptype = 0;
|
||||
pi.in_error_pkt = FALSE;
|
||||
pi.ptype = PT_NONE;
|
||||
pi.srcport = 0;
|
||||
pi.destport = 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* packet_info.h
|
||||
* Definitions for packet info structures and routines
|
||||
*
|
||||
* $Id: packet_info.h,v 1.6 2001/09/13 07:53:53 guy Exp $
|
||||
* $Id: packet_info.h,v 1.7 2001/10/01 08:29:37 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -104,6 +104,7 @@ typedef struct _packet_info {
|
|||
guint32 ipproto; /* IP protocol, if this is an IP packet */
|
||||
guint32 ipxptype; /* IPX packet type, if this is an IPX packet */
|
||||
gboolean fragmented; /* TRUE if the protocol is only a fragment */
|
||||
gboolean in_error_pkt; /* TRUE if we're inside an {ICMP,CLNP,...} error packet */
|
||||
port_type ptype; /* type of the following two port numbers */
|
||||
guint32 srcport; /* source port */
|
||||
guint32 destport; /* destination port */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* packet-clnp.c
|
||||
* Routines for ISO/OSI network and transport protocol packet disassembly
|
||||
*
|
||||
* $Id: packet-clnp.c,v 1.34 2001/09/27 10:35:40 guy Exp $
|
||||
* $Id: packet-clnp.c,v 1.35 2001/10/01 08:29:34 guy Exp $
|
||||
* Laurent Deniel <deniel@worldnet.fr>
|
||||
* Ralf Schneider <Ralf.Schneider@t-online.de>
|
||||
*
|
||||
|
@ -1592,6 +1592,7 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
address save_net_dst;
|
||||
address save_src;
|
||||
address save_dst;
|
||||
gboolean save_in_error_pkt;
|
||||
fragment_data *fd_head;
|
||||
tvbuff_t *volatile next_tvb;
|
||||
packet_info save_pi;
|
||||
|
@ -2022,10 +2023,20 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
save_src = pinfo->src;
|
||||
save_dst = pinfo->dst;
|
||||
|
||||
/* Save the current value of the "we're inside an error packet"
|
||||
flag, and set that flag; subdissectors may treat packets
|
||||
that are the payload of error packets differently from
|
||||
"real" packets. */
|
||||
save_in_error_pkt = pinfo->in_error_pkt;
|
||||
pinfo->in_error_pkt = TRUE;
|
||||
|
||||
/* Dissect the contained packet.
|
||||
Catch ReportedBoundsError, and do nothing if we see it,
|
||||
because it's not an error if the contained packet is short;
|
||||
there's no guarantee that all of it was included. */
|
||||
there's no guarantee that all of it was included.
|
||||
|
||||
XXX - should catch BoundsError, and re-throw it after cleaning
|
||||
up. */
|
||||
ti = proto_tree_add_text(clnp_tree, tvb, offset, next_length,
|
||||
"Discarded PDU");
|
||||
discpdu_tree = proto_item_add_subtree(ti, ett_clnp_disc_pdu);
|
||||
|
@ -2037,6 +2048,9 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
}
|
||||
ENDTRY;
|
||||
|
||||
/* Restore the "we're inside an error packet" flag. */
|
||||
pinfo->in_error_pkt = save_in_error_pkt;
|
||||
|
||||
/* Restore the addresses. */
|
||||
pinfo->dl_src = save_dl_src;
|
||||
pinfo->dl_dst = save_dl_dst;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* packet-icmpv6.c
|
||||
* Routines for ICMPv6 packet disassembly
|
||||
*
|
||||
* $Id: packet-icmpv6.c,v 1.52 2001/09/27 10:35:40 guy Exp $
|
||||
* $Id: packet-icmpv6.c,v 1.53 2001/10/01 08:29:34 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -116,6 +116,7 @@ dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tr
|
|||
address save_net_dst;
|
||||
address save_src;
|
||||
address save_dst;
|
||||
gboolean save_in_error_pkt;
|
||||
|
||||
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
|
||||
|
||||
|
@ -139,10 +140,20 @@ dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tr
|
|||
save_src = pinfo->src;
|
||||
save_dst = pinfo->dst;
|
||||
|
||||
/* Save the current value of the "we're inside an error packet"
|
||||
flag, and set that flag; subdissectors may treat packets
|
||||
that are the payload of error packets differently from
|
||||
"real" packets. */
|
||||
save_in_error_pkt = pinfo->in_error_pkt;
|
||||
pinfo->in_error_pkt = TRUE;
|
||||
|
||||
/* Dissect the contained packet.
|
||||
Catch ReportedBoundsError, and do nothing if we see it,
|
||||
because it's not an error if the contained packet is short;
|
||||
there's no guarantee that all of it was included. */
|
||||
there's no guarantee that all of it was included.
|
||||
|
||||
XXX - should catch BoundsError, and re-throw it after cleaning
|
||||
up. */
|
||||
TRY {
|
||||
call_dissector(ipv6_handle, next_tvb, pinfo, tree);
|
||||
}
|
||||
|
@ -151,6 +162,9 @@ dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tr
|
|||
}
|
||||
ENDTRY;
|
||||
|
||||
/* Restore the "we're inside an error packet" flag. */
|
||||
pinfo->in_error_pkt = save_in_error_pkt;
|
||||
|
||||
/* Restore the addresses. */
|
||||
pinfo->dl_src = save_dl_src;
|
||||
pinfo->dl_dst = save_dl_dst;
|
||||
|
|
18
packet-ip.c
18
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.141 2001/09/27 10:35:40 guy Exp $
|
||||
* $Id: packet-ip.c,v 1.142 2001/10/01 08:29:34 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -1174,6 +1174,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
address save_net_dst;
|
||||
address save_src;
|
||||
address save_dst;
|
||||
gboolean save_in_error_pkt;
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
if (check_col(pinfo->fd, COL_PROTOCOL))
|
||||
|
@ -1368,10 +1369,20 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
save_src = pinfo->src;
|
||||
save_dst = pinfo->dst;
|
||||
|
||||
/* Save the current value of the "we're inside an error packet"
|
||||
flag, and set that flag; subdissectors may treat packets
|
||||
that are the payload of error packets differently from
|
||||
"real" packets. */
|
||||
save_in_error_pkt = pinfo->in_error_pkt;
|
||||
pinfo->in_error_pkt = TRUE;
|
||||
|
||||
/* Dissect the contained packet.
|
||||
Catch ReportedBoundsError, and do nothing if we see it,
|
||||
because it's not an error if the contained packet is short;
|
||||
there's no guarantee that all of it was included. */
|
||||
there's no guarantee that all of it was included.
|
||||
|
||||
XXX - should catch BoundsError, and re-throw it after cleaning
|
||||
up. */
|
||||
next_tvb = tvb_new_subset(tvb, 8, -1, -1);
|
||||
TRY {
|
||||
call_dissector(ip_handle, next_tvb, pinfo, icmp_tree);
|
||||
|
@ -1381,6 +1392,9 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
}
|
||||
ENDTRY;
|
||||
|
||||
/* Restore the "we're inside an error packet" flag. */
|
||||
pinfo->in_error_pkt = save_in_error_pkt;
|
||||
|
||||
/* Restore the addresses. */
|
||||
pinfo->dl_src = save_dl_src;
|
||||
pinfo->dl_dst = save_dl_dst;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Routines for unix rlogin packet dissection
|
||||
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
|
||||
*
|
||||
* $Id: packet-rlogin.c,v 1.20 2001/09/30 23:14:43 guy Exp $
|
||||
* $Id: packet-rlogin.c,v 1.21 2001/10/01 08:29:35 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -198,7 +198,13 @@ static void rlogin_display( rlogin_hash_entry_t *hash_info, tvbuff_t *tvb,
|
|||
if ( length == 0) /* exit if no captured data */
|
||||
return;
|
||||
|
||||
if ( tcpinfo->urgent_pointer && /* if control message */
|
||||
/*
|
||||
* XXX - this works only if the urgent pointer points to something
|
||||
* in this segment; to make it work if the urgent pointer points
|
||||
* to something past this segment, we'd have to remember the urgent
|
||||
* pointer setting for this conversation.
|
||||
*/
|
||||
if ( tcpinfo->urgent && /* if urgent pointer set */
|
||||
length >= tcpinfo->urgent_pointer) { /* and it's in this frame */
|
||||
|
||||
int urgent_offset = tcpinfo->urgent_pointer - 1;
|
||||
|
@ -338,6 +344,7 @@ dissect_rlogin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
struct tcpinfo *tcpinfo = pinfo->private;
|
||||
conversation_t *conversation;
|
||||
rlogin_hash_entry_t *hash_info;
|
||||
guint length;
|
||||
gint ti_offset;
|
||||
|
||||
/* Lookup this connection*/
|
||||
|
@ -374,29 +381,33 @@ dissect_rlogin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
else
|
||||
temp[0] = 0;
|
||||
|
||||
if ( tvb_get_guint8(tvb, 0) == '\0')
|
||||
strcat( temp, "Start Handshake");
|
||||
else if ( tcpinfo->urgent_pointer)
|
||||
strcat( temp, "Control Message");
|
||||
length = tvb_length(tvb);
|
||||
if (length != 0) {
|
||||
if ( tvb_get_guint8(tvb, 0) == '\0')
|
||||
strcat( temp, "Start Handshake");
|
||||
else if ( tcpinfo->urgent &&
|
||||
length >= tcpinfo->urgent_pointer )
|
||||
strcat( temp, "Control Message");
|
||||
|
||||
else { /* check for terminal info */
|
||||
ti_offset = tvb_find_guint8(tvb, 0, -1, 0xff);
|
||||
if (ti_offset != -1 &&
|
||||
tvb_bytes_exist(tvb, ti_offset + 1, 1) &&
|
||||
tvb_get_guint8(tvb, ti_offset + 1) == 0xff)
|
||||
strcat( temp, "Terminal Info");
|
||||
else {
|
||||
int i;
|
||||
int bytes_to_copy;
|
||||
else { /* check for terminal info */
|
||||
ti_offset = tvb_find_guint8(tvb, 0, -1, 0xff);
|
||||
if (ti_offset != -1 &&
|
||||
tvb_bytes_exist(tvb, ti_offset + 1, 1) &&
|
||||
tvb_get_guint8(tvb, ti_offset + 1) == 0xff)
|
||||
strcat( temp, "Terminal Info");
|
||||
else {
|
||||
int i;
|
||||
int bytes_to_copy;
|
||||
|
||||
strcat( temp, "Data: ");
|
||||
i = strlen( temp);
|
||||
bytes_to_copy = tvb_length(tvb);
|
||||
if (bytes_to_copy > 128)
|
||||
bytes_to_copy = 128;
|
||||
tvb_memcpy(tvb, (guint8 *)&temp[i], 0,
|
||||
bytes_to_copy);
|
||||
temp[i + bytes_to_copy] = '\0';
|
||||
strcat( temp, "Data: ");
|
||||
i = strlen( temp);
|
||||
bytes_to_copy = tvb_length(tvb);
|
||||
if (bytes_to_copy > 128)
|
||||
bytes_to_copy = 128;
|
||||
tvb_memcpy(tvb, (guint8 *)&temp[i], 0,
|
||||
bytes_to_copy);
|
||||
temp[i + bytes_to_copy] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
250
packet-tcp.c
250
packet-tcp.c
|
@ -1,7 +1,7 @@
|
|||
/* packet-tcp.c
|
||||
* Routines for TCP packet disassembly
|
||||
*
|
||||
* $Id: packet-tcp.c,v 1.110 2001/09/30 23:14:43 guy Exp $
|
||||
* $Id: packet-tcp.c,v 1.111 2001/10/01 08:29:35 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -92,13 +92,6 @@ static conv_dissector_list_t conv_subdissector_list;
|
|||
|
||||
/* TCP structs and definitions */
|
||||
|
||||
typedef struct _e_tcphdr {
|
||||
guint16 th_sport;
|
||||
guint16 th_dport;
|
||||
guint32 th_seq;
|
||||
guint32 th_ack;
|
||||
guint8 th_off_x2; /* combines th_off and th_x2 */
|
||||
guint8 th_flags;
|
||||
#define TH_FIN 0x01
|
||||
#define TH_SYN 0x02
|
||||
#define TH_RST 0x04
|
||||
|
@ -107,10 +100,6 @@ typedef struct _e_tcphdr {
|
|||
#define TH_URG 0x20
|
||||
#define TH_ECN 0x40
|
||||
#define TH_CWR 0x80
|
||||
guint16 th_win;
|
||||
guint16 th_sum;
|
||||
guint16 th_urp;
|
||||
} e_tcphdr;
|
||||
|
||||
/* Minimum TCP header length. */
|
||||
#define TCPH_MIN_LEN 20
|
||||
|
@ -824,10 +813,17 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
static void
|
||||
dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
struct tcpinfo tcpinfo;
|
||||
e_tcphdr th;
|
||||
guint16 th_sport;
|
||||
guint16 th_dport;
|
||||
guint32 th_seq;
|
||||
guint32 th_ack;
|
||||
guint8 th_off_x2; /* combines th_off and th_x2 */
|
||||
guint8 th_flags;
|
||||
guint16 th_win;
|
||||
guint16 th_sum;
|
||||
guint16 th_urp;
|
||||
proto_tree *tcp_tree = NULL, *field_tree = NULL;
|
||||
proto_item *ti, *tf;
|
||||
proto_item *ti = NULL, *tf;
|
||||
int offset = 0;
|
||||
gchar flags[64] = "<None>";
|
||||
gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
|
||||
|
@ -843,6 +839,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
guint32 phdr[2];
|
||||
guint16 computed_cksum;
|
||||
guint length_remaining;
|
||||
struct tcpinfo tcpinfo;
|
||||
|
||||
if (check_col(pinfo->fd, COL_PROTOCOL))
|
||||
col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
|
||||
|
@ -851,29 +848,44 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
if (check_col(pinfo->fd, COL_INFO))
|
||||
col_clear(pinfo->fd, COL_INFO);
|
||||
|
||||
/* Avoids alignment problems on many architectures. */
|
||||
tvb_memcpy(tvb, (guint8 *)&th, offset, sizeof(e_tcphdr));
|
||||
th.th_sport = ntohs(th.th_sport);
|
||||
th.th_dport = ntohs(th.th_dport);
|
||||
th.th_win = ntohs(th.th_win);
|
||||
th.th_sum = ntohs(th.th_sum);
|
||||
th.th_urp = ntohs(th.th_urp);
|
||||
th.th_seq = ntohl(th.th_seq);
|
||||
th.th_ack = ntohl(th.th_ack);
|
||||
|
||||
/* Export the urgent pointer, for the benefit of protocols such as
|
||||
rlogin. */
|
||||
tcpinfo.urgent_pointer = th.th_urp;
|
||||
|
||||
/* Assume we'll pass un-reassembled data to subdissectors. */
|
||||
tcpinfo.is_reassembled = FALSE;
|
||||
|
||||
pinfo->private = &tcpinfo;
|
||||
th_sport = tvb_get_ntohs(tvb, offset);
|
||||
th_dport = tvb_get_ntohs(tvb, offset + 2);
|
||||
if (check_col(pinfo->fd, COL_INFO)) {
|
||||
col_append_fstr(pinfo->fd, COL_INFO, "%s > %s",
|
||||
get_tcp_port(th_sport), get_tcp_port(th_dport));
|
||||
}
|
||||
|
||||
if (tree) {
|
||||
if (tcp_summary_in_tree) {
|
||||
ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0,
|
||||
tvb_length(tvb),
|
||||
"Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
|
||||
get_tcp_port(th_sport), th_sport,
|
||||
get_tcp_port(th_dport), th_dport);
|
||||
}
|
||||
else {
|
||||
ti = proto_tree_add_item(tree, proto_tcp, tvb, 0,
|
||||
tvb_length(tvb), FALSE);
|
||||
}
|
||||
tcp_tree = proto_item_add_subtree(ti, ett_tcp);
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th_sport,
|
||||
"Source port: %s (%u)", get_tcp_port(th_sport), th_sport);
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th_dport,
|
||||
"Destination port: %s (%u)", get_tcp_port(th_dport), th_dport);
|
||||
proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th_sport);
|
||||
proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th_dport);
|
||||
}
|
||||
|
||||
th_seq = tvb_get_ntohl(tvb, offset + 4);
|
||||
th_ack = tvb_get_ntohl(tvb, offset + 8);
|
||||
th_off_x2 = tvb_get_guint8(tvb, offset + 12);
|
||||
th_flags = tvb_get_guint8(tvb, offset + 13);
|
||||
th_win = tvb_get_ntohs(tvb, offset + 14);
|
||||
|
||||
if (check_col(pinfo->fd, COL_INFO) || tree) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
bpos = 1 << i;
|
||||
if (th.th_flags & bpos) {
|
||||
if (th_flags & bpos) {
|
||||
if (fpos) {
|
||||
strcpy(&flags[fpos], ", ");
|
||||
fpos += 2;
|
||||
|
@ -884,8 +896,35 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
}
|
||||
flags[fpos] = '\0';
|
||||
}
|
||||
|
||||
hlen = hi_nibble(th.th_off_x2) * 4; /* TCP header length, in bytes */
|
||||
|
||||
if (check_col(pinfo->fd, COL_INFO)) {
|
||||
col_append_fstr(pinfo->fd, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
|
||||
flags, th_seq, th_ack, th_win);
|
||||
}
|
||||
|
||||
if (tree) {
|
||||
if (tcp_summary_in_tree)
|
||||
proto_item_append_text(ti, ", Seq: %u", th_seq);
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th_seq);
|
||||
}
|
||||
|
||||
hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
|
||||
|
||||
if (hlen < TCPH_MIN_LEN) {
|
||||
/* Give up at this point; we put the source and destination port in
|
||||
the tree, before fetching the header length, so that they'll
|
||||
show up if this is in the failing packet in an ICMP error packet,
|
||||
but it's now time to give up if the header length is bogus. */
|
||||
if (check_col(pinfo->fd, COL_INFO))
|
||||
col_append_fstr(pinfo->fd, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
|
||||
hlen, TCPH_MIN_LEN);
|
||||
if (tree) {
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
|
||||
"Header length: %u bytes (bogus, must be at least %u)", hlen,
|
||||
TCPH_MIN_LEN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
reported_len = tvb_reported_length(tvb);
|
||||
len = tvb_length(tvb);
|
||||
|
@ -894,80 +933,47 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
seglen = reported_len - hlen;
|
||||
|
||||
/* Compute the sequence number of next octet after this segment. */
|
||||
nxtseq = th.th_seq + seglen;
|
||||
nxtseq = th_seq + seglen;
|
||||
|
||||
if (hlen < TCPH_MIN_LEN) {
|
||||
if (check_col(pinfo->fd, COL_INFO))
|
||||
col_add_fstr(pinfo->fd, COL_INFO, "Bogus TCP header length (%u, must be at least %u)",
|
||||
hlen, TCPH_MIN_LEN);
|
||||
ti = proto_tree_add_item(tree, proto_tcp, tvb, offset, hlen, FALSE);
|
||||
tcp_tree = proto_item_add_subtree(ti, ett_tcp);
|
||||
if (tree) {
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset, 1, hlen,
|
||||
"Header length: %u bytes (bogus, must be at least %u)", hlen,
|
||||
TCPH_MIN_LEN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_col(pinfo->fd, COL_INFO)) {
|
||||
if (th.th_flags & TH_URG)
|
||||
col_append_fstr(pinfo->fd, COL_INFO, "%s > %s [%s] Seq=%u Ack=%u Win=%u Urg=%u Len=%d",
|
||||
get_tcp_port(th.th_sport), get_tcp_port(th.th_dport), flags,
|
||||
th.th_seq, th.th_ack, th.th_win, th.th_urp, seglen);
|
||||
else
|
||||
col_append_fstr(pinfo->fd, COL_INFO, "%s > %s [%s] Seq=%u Ack=%u Win=%u Len=%d",
|
||||
get_tcp_port(th.th_sport), get_tcp_port(th.th_dport), flags,
|
||||
th.th_seq, th.th_ack, th.th_win, seglen);
|
||||
}
|
||||
|
||||
if (tree) {
|
||||
if (tcp_summary_in_tree && hlen >= TCPH_MIN_LEN) {
|
||||
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 {
|
||||
ti = proto_tree_add_item(tree, proto_tcp, tvb, offset, hlen, FALSE);
|
||||
}
|
||||
tcp_tree = proto_item_add_subtree(ti, ett_tcp);
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th.th_sport,
|
||||
"Source port: %s (%u)", get_tcp_port(th.th_sport), th.th_sport);
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th.th_dport,
|
||||
"Destination port: %s (%u)", get_tcp_port(th.th_dport), th.th_dport);
|
||||
proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th.th_sport);
|
||||
proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th.th_dport);
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th.th_seq);
|
||||
if (nxtseq != th.th_seq)
|
||||
if (tcp_summary_in_tree)
|
||||
proto_item_append_text(ti, ", Ack: %u", th_ack);
|
||||
proto_item_set_len(ti, hlen);
|
||||
if (nxtseq != th_seq)
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
|
||||
if (th.th_flags & TH_ACK)
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th.th_ack);
|
||||
if (th_flags & TH_ACK)
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th_ack);
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
|
||||
"Header length: %u bytes", hlen);
|
||||
tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
|
||||
th.th_flags, "Flags: 0x%04x (%s)", th.th_flags, flags);
|
||||
th_flags, "Flags: 0x%04x (%s)", th_flags, flags);
|
||||
field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th.th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th.th_flags);
|
||||
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_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th_flags);
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th_win);
|
||||
}
|
||||
|
||||
/* Assume we'll pass un-reassembled data to subdissectors. */
|
||||
tcpinfo.is_reassembled = FALSE;
|
||||
|
||||
pinfo->private = &tcpinfo;
|
||||
|
||||
/*
|
||||
* Assume, initially, that we can't desegment.
|
||||
*/
|
||||
pinfo->can_desegment = FALSE;
|
||||
|
||||
th_sum = tvb_get_ntohs(tvb, offset + 16);
|
||||
if (!pinfo->fragmented && len >= reported_len) {
|
||||
/* The packet isn't part of a fragmented datagram and isn't
|
||||
truncated, so we can checksum it.
|
||||
/* The packet isn't part of a fragmented datagram, isn't being
|
||||
returned inside an ICMP error packet, and isn't truncated, so we
|
||||
can checksum it.
|
||||
XXX - make a bigger scatter-gather list once we do fragment
|
||||
reassembly? */
|
||||
|
||||
|
@ -1005,31 +1011,49 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
* Is desegmentation enabled?
|
||||
*/
|
||||
if (tcp_desegment) {
|
||||
/* Yes - indicate that we will desegment. */
|
||||
pinfo->can_desegment = TRUE;
|
||||
/* Yes - is this segment being returned in an error packet? */
|
||||
if (!pinfo->in_error_pkt) {
|
||||
/* No - indicate that we will desegment.
|
||||
We do NOT want to desegment segments returned in error
|
||||
packets, as they're not part of a TCP connection. */
|
||||
pinfo->can_desegment = TRUE;
|
||||
}
|
||||
}
|
||||
proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
|
||||
offset + 16, 2, th.th_sum, "Checksum: 0x%04x (correct)", th.th_sum);
|
||||
offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
|
||||
} else {
|
||||
proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
|
||||
offset + 16, 2, TRUE);
|
||||
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));
|
||||
offset + 16, 2, th_sum,
|
||||
"Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
|
||||
in_cksum_shouldbe(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);
|
||||
offset + 16, 2, th_sum, "Checksum: 0x%04x", 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);
|
||||
if (th_flags & TH_URG) {
|
||||
th_urp = tvb_get_ntohs(tvb, offset + 18);
|
||||
/* Export the urgent pointer, for the benefit of protocols such as
|
||||
rlogin. */
|
||||
tcpinfo.urgent = TRUE;
|
||||
tcpinfo.urgent_pointer = th_urp;
|
||||
if (check_col(pinfo->fd, COL_INFO))
|
||||
col_append_fstr(pinfo->fd, COL_INFO, " Urg=%u", th_urp);
|
||||
if (tcp_tree != NULL)
|
||||
proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
|
||||
} else
|
||||
tcpinfo.urgent = FALSE;
|
||||
|
||||
if (check_col(pinfo->fd, COL_INFO))
|
||||
col_append_fstr(pinfo->fd, COL_INFO, " Len=%d", seglen);
|
||||
|
||||
/* Decode TCP options, if any. */
|
||||
if (tree && hlen > sizeof (e_tcphdr)) {
|
||||
if (tree && hlen > TCPH_MIN_LEN) {
|
||||
/* There's more than just the fixed-length header. Decode the
|
||||
options. */
|
||||
optlen = hlen - sizeof (e_tcphdr); /* length of options, in bytes */
|
||||
optlen = hlen - TCPH_MIN_LEN; /* length of options, in bytes */
|
||||
tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
|
||||
"Options: (%d bytes)", optlen);
|
||||
field_tree = proto_item_add_subtree(tf, ett_tcp_options);
|
||||
|
@ -1041,14 +1065,14 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
offset += hlen;
|
||||
|
||||
pinfo->ptype = PT_TCP;
|
||||
pinfo->srcport = th.th_sport;
|
||||
pinfo->destport = th.th_dport;
|
||||
pinfo->srcport = th_sport;
|
||||
pinfo->destport = th_dport;
|
||||
|
||||
/* Check the packet length to see if there's more data
|
||||
(it could be an ACK-only packet) */
|
||||
length_remaining = tvb_length_remaining(tvb, offset);
|
||||
if (length_remaining != 0) {
|
||||
if (th.th_flags & TH_RST) {
|
||||
if (th_flags & TH_RST) {
|
||||
/*
|
||||
* RFC1122 says:
|
||||
*
|
||||
|
@ -1071,20 +1095,20 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/* Can we desegment this segment? */
|
||||
if (pinfo->can_desegment) {
|
||||
/* Yes. */
|
||||
desegment_tcp(tvb, pinfo, offset, th.th_seq, nxtseq, th.th_sport, th.th_dport, tree, tcp_tree);
|
||||
desegment_tcp(tvb, pinfo, offset, th_seq, nxtseq, th_sport, th_dport, tree, tcp_tree);
|
||||
} else {
|
||||
/* No - just call the subdissector. */
|
||||
decode_tcp_ports(tvb, offset, pinfo, tree, th.th_sport, th.th_dport);
|
||||
decode_tcp_ports(tvb, offset, pinfo, tree, th_sport, th_dport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( data_out_file ) {
|
||||
reassemble_tcp( th.th_seq, /* sequence number */
|
||||
reassemble_tcp( th_seq, /* sequence number */
|
||||
seglen, /* data length */
|
||||
tvb_get_ptr(tvb, offset, length_remaining), /* data */
|
||||
length_remaining, /* captured data length */
|
||||
( th.th_flags & TH_SYN ), /* is syn set? */
|
||||
( th_flags & TH_SYN ), /* is syn set? */
|
||||
&pinfo->net_src,
|
||||
&pinfo->net_dst,
|
||||
pinfo->srcport,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* packet-tcp.h
|
||||
*
|
||||
* $Id: packet-tcp.h,v 1.7 2001/09/30 23:14:43 guy Exp $
|
||||
* $Id: packet-tcp.h,v 1.8 2001/10/01 08:29:35 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
struct tcpinfo {
|
||||
gboolean is_reassembled; /* This is reassembled data. */
|
||||
gboolean urgent; /* TRUE if "urgent_pointer is valid */
|
||||
guint16 urgent_pointer; /* Urgent pointer value for the current packet. */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue