2 * Routines for TCP packet disassembly
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/in_cksum.h>
34 #include <epan/packet.h>
35 #include <epan/addr_resolv.h>
36 #include <epan/ipproto.h>
37 #include <epan/ip_opts.h>
38 #include <epan/follow.h>
39 #include <epan/prefs.h>
40 #include "packet-tcp.h"
41 #include "packet-ip.h"
42 #include "packet-frame.h"
43 #include <epan/conversation.h>
44 #include <epan/strutil.h>
45 #include <epan/reassemble.h>
47 #include <epan/emem.h>
48 #include <epan/slab.h>
49 #include <epan/expert.h>
51 static int tcp_tap = -1;
53 /* Place TCP summary in proto tree */
54 static gboolean tcp_summary_in_tree = TRUE;
57 * Flag to control whether to check the TCP checksum.
59 * In at least some Solaris network traces, there are packets with bad
60 * TCP checksums, but the traffic appears to indicate that the packets
61 * *were* received; the packets were probably sent by the host on which
62 * the capture was being done, on a network interface to which
63 * checksumming was offloaded, so that DLPI supplied an un-checksummed
64 * packet to the capture program but a checksummed packet got put onto
67 static gboolean tcp_check_checksum = TRUE;
69 extern FILE* data_out_file;
71 static int proto_tcp = -1;
72 static int hf_tcp_srcport = -1;
73 static int hf_tcp_dstport = -1;
74 static int hf_tcp_port = -1;
75 static int hf_tcp_seq = -1;
76 static int hf_tcp_nxtseq = -1;
77 static int hf_tcp_ack = -1;
78 static int hf_tcp_hdr_len = -1;
79 static int hf_tcp_flags = -1;
80 static int hf_tcp_flags_cwr = -1;
81 static int hf_tcp_flags_ecn = -1;
82 static int hf_tcp_flags_urg = -1;
83 static int hf_tcp_flags_ack = -1;
84 static int hf_tcp_flags_push = -1;
85 static int hf_tcp_flags_reset = -1;
86 static int hf_tcp_flags_syn = -1;
87 static int hf_tcp_flags_fin = -1;
88 static int hf_tcp_window_size = -1;
89 static int hf_tcp_checksum = -1;
90 static int hf_tcp_checksum_bad = -1;
91 static int hf_tcp_len = -1;
92 static int hf_tcp_urgent_pointer = -1;
93 static int hf_tcp_analysis_flags = -1;
94 static int hf_tcp_analysis_acks_frame = -1;
95 static int hf_tcp_analysis_ack_rtt = -1;
96 static int hf_tcp_analysis_rto = -1;
97 static int hf_tcp_analysis_rto_frame = -1;
98 static int hf_tcp_analysis_retransmission = -1;
99 static int hf_tcp_analysis_fast_retransmission = -1;
100 static int hf_tcp_analysis_out_of_order = -1;
101 static int hf_tcp_analysis_lost_packet = -1;
102 static int hf_tcp_analysis_ack_lost_packet = -1;
103 static int hf_tcp_analysis_window_update = -1;
104 static int hf_tcp_analysis_window_full = -1;
105 static int hf_tcp_analysis_keep_alive = -1;
106 static int hf_tcp_analysis_keep_alive_ack = -1;
107 static int hf_tcp_analysis_duplicate_ack = -1;
108 static int hf_tcp_analysis_duplicate_ack_num = -1;
109 static int hf_tcp_analysis_duplicate_ack_frame = -1;
110 static int hf_tcp_analysis_zero_window = -1;
111 static int hf_tcp_analysis_zero_window_probe = -1;
112 static int hf_tcp_analysis_zero_window_violation = -1;
113 static int hf_tcp_continuation_to = -1;
114 static int hf_tcp_pdu_time = -1;
115 static int hf_tcp_pdu_last_frame = -1;
116 static int hf_tcp_reassembled_in = -1;
117 static int hf_tcp_segments = -1;
118 static int hf_tcp_segment = -1;
119 static int hf_tcp_segment_overlap = -1;
120 static int hf_tcp_segment_overlap_conflict = -1;
121 static int hf_tcp_segment_multiple_tails = -1;
122 static int hf_tcp_segment_too_long_fragment = -1;
123 static int hf_tcp_segment_error = -1;
124 static int hf_tcp_option_mss = -1;
125 static int hf_tcp_option_mss_val = -1;
126 static int hf_tcp_option_wscale = -1;
127 static int hf_tcp_option_wscale_val = -1;
128 static int hf_tcp_option_sack_perm = -1;
129 static int hf_tcp_option_sack = -1;
130 static int hf_tcp_option_sack_sle = -1;
131 static int hf_tcp_option_sack_sre = -1;
132 static int hf_tcp_option_echo = -1;
133 static int hf_tcp_option_echo_reply = -1;
134 static int hf_tcp_option_time_stamp = -1;
135 static int hf_tcp_option_cc = -1;
136 static int hf_tcp_option_ccnew = -1;
137 static int hf_tcp_option_ccecho = -1;
138 static int hf_tcp_option_md5 = -1;
140 static gint ett_tcp = -1;
141 static gint ett_tcp_flags = -1;
142 static gint ett_tcp_options = -1;
143 static gint ett_tcp_option_sack = -1;
144 static gint ett_tcp_analysis = -1;
145 static gint ett_tcp_analysis_faults = -1;
146 static gint ett_tcp_segments = -1;
147 static gint ett_tcp_segment = -1;
150 /* not all of the hf_fields below make sense for TCP but we have to provide
151 them anyways to comply with the api (which was aimed for ip fragment
153 static const fragment_items tcp_segment_items = {
158 &hf_tcp_segment_overlap,
159 &hf_tcp_segment_overlap_conflict,
160 &hf_tcp_segment_multiple_tails,
161 &hf_tcp_segment_too_long_fragment,
162 &hf_tcp_segment_error,
163 &hf_tcp_reassembled_in,
167 static dissector_table_t subdissector_table;
168 static heur_dissector_list_t heur_subdissector_list;
169 static dissector_handle_t data_handle;
171 /* TCP structs and definitions */
174 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
175 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
176 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment);
178 /* **************************************************************************
179 * stuff to analyze TCP sequencenumbers for retransmissions, missing segments,
180 * RTT and reltive sequence numbers.
181 * **************************************************************************/
182 static gboolean tcp_analyze_seq = TRUE;
183 static gboolean tcp_relative_seq = TRUE;
185 typedef struct _tcp_unacked_t {
186 struct _tcp_unacked_t *next;
192 /* this is to keep track of zero window and zero window probe */
198 /* SLAB allocator for tcp_unacked structures
200 SLAB_ITEM_TYPE_DEFINE(tcp_unacked_t)
201 static SLAB_FREE_LIST_DEFINE(tcp_unacked_t)
202 #define TCP_UNACKED_NEW(fi) \
203 SLAB_ALLOC(fi, tcp_unacked_t)
204 #define TCP_UNACKED_FREE(fi) \
205 SLAB_FREE(fi, tcp_unacked_t)
208 /* Idea for gt: either x > y, or y is much bigger (assume wrap) */
209 #define GT_SEQ(x, y) ((gint32)((y) - (x)) < 0)
210 #define LT_SEQ(x, y) ((gint32)((x) - (y)) < 0)
211 #define GE_SEQ(x, y) ((gint32)((y) - (x)) <= 0)
212 #define LE_SEQ(x, y) ((gint32)((x) - (y)) <= 0)
213 #define EQ_SEQ(x, y) ((x) == (y))
215 #define TCP_A_RETRANSMISSION 0x0001
216 #define TCP_A_LOST_PACKET 0x0002
217 #define TCP_A_ACK_LOST_PACKET 0x0004
218 #define TCP_A_KEEP_ALIVE 0x0008
219 #define TCP_A_DUPLICATE_ACK 0x0010
220 #define TCP_A_ZERO_WINDOW 0x0020
221 #define TCP_A_ZERO_WINDOW_PROBE 0x0040
222 #define TCP_A_ZERO_WINDOW_VIOLATION 0x0080
223 #define TCP_A_KEEP_ALIVE_ACK 0x0100
224 #define TCP_A_OUT_OF_ORDER 0x0200
225 #define TCP_A_FAST_RETRANSMISSION 0x0400
226 #define TCP_A_WINDOW_UPDATE 0x0800
227 #define TCP_A_WINDOW_FULL 0x1000
233 nstime_t rto_ts; /* Time since previous packet for
236 guint32 dupack_num; /* dup ack number */
237 guint32 dupack_frame; /* dup ack to frame # */
239 static GHashTable *tcp_analyze_acked_table = NULL;
246 static GHashTable *tcp_rel_seq_table = NULL;
248 struct tcp_analysis {
249 /* These two structs are managed based on comparing the source
250 * and destination addresses and, if they're equal, comparing
251 * the source and destination ports.
253 * If the source is greater than the destination, then stuff
254 * sent from src is in ual1.
256 * If the source is less than the destination, then stuff
257 * sent from src is in ual2.
259 * XXX - if the addresses and ports are equal, we don't guarantee
262 tcp_unacked_t *ual1; /* UnAcked List 1*/
264 tcp_unacked_t *ual2; /* UnAcked List 2*/
266 gint16 win_scale1, win_scale2;
269 guint32 ack1_frame, ack2_frame;
270 nstime_t ack1_time, ack2_time;
271 guint32 num1_acks, num2_acks;
273 /* these two lists are used to track when PDUs may start
276 struct tcp_next_pdu *pdu_seq1;
277 struct tcp_next_pdu *pdu_seq2;
281 struct tcp_next_pdu {
282 struct tcp_next_pdu *next;
287 nstime_t last_frame_time;
289 static GHashTable *tcp_pdu_tracking_table = NULL;
290 static GHashTable *tcp_pdu_skipping_table = NULL;
291 static GHashTable *tcp_pdu_time_table = NULL;
294 static struct tcp_analysis *
295 get_tcp_conversation_data(packet_info *pinfo)
297 conversation_t *conv=NULL;
298 struct tcp_analysis *tcpd=NULL;
300 /* Have we seen this conversation before? */
301 if( (conv=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
302 /* No this is a new conversation. */
303 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
306 /* check if we have any data for this conversation */
307 tcpd=conversation_get_proto_data(conv, proto_tcp);
309 /* No no such data yet. Allocate and init it */
310 tcpd=se_alloc(sizeof(struct tcp_analysis));
317 tcpd->ack1_time.secs=0;
318 tcpd->ack1_time.nsecs=0;
326 tcpd->ack2_time.secs=0;
327 tcpd->ack2_time.nsecs=0;
333 conversation_add_proto_data(conv, proto_tcp, tcpd);
339 /* This function is called from the tcp analysis code to provide
340 clues on how the seq and ack numbers are changed.
341 To prevent the next_pdu lists from growing uncontrollable in size we
342 use this function to do the following :
343 IF we see an ACK then we assume that the left edge of the window has changed
344 at least to this point and assuming it is rare with reordering and
345 trailing duplicate/retransmitted segments, we just assume that after
346 we have seen the ACK we will not see any more segments prior to the
348 If we will not see any segments prior to the ACK value then we can just
349 delete all next_pdu entries that describe pdu's starting prior to the
351 If this heuristics is prooved to be too simplistic we can just enhance it
354 /* XXX this function should be ehnanced to handle sequence number wrapping */
355 /* XXX to handle retransmissions and reordered packets maybe we should only
356 discard entries that are more than (guesstimate) 50kb older than the
357 specified sequence number ?
360 prune_next_pdu_list(struct tcp_next_pdu **tnp, guint32 seq)
362 struct tcp_next_pdu *tmptnp;
368 for(tmptnp=*tnp;tmptnp;tmptnp=tmptnp->next){
369 if(tmptnp->nxtpdu<=seq){
370 struct tcp_next_pdu *oldtnp;
381 for(tmptnp=*tnp;tmptnp;tmptnp=tmptnp->next){
382 if(tmptnp->next==oldtnp){
383 tmptnp->next=oldtnp->next;
397 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_next_pdu *tnp)
401 if (check_col(pinfo->cinfo, COL_INFO)){
402 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", tnp->first_frame);
404 item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
405 tvb, 0, 0, tnp->first_frame);
406 PROTO_ITEM_SET_GENERATED(item);
409 /* if we know that a PDU starts inside this segment, return the adjusted
410 offset to where that PDU starts or just return offset back
411 and let TCP try to find out what it can about this segment
414 scan_for_next_pdu(tvbuff_t *tvb, proto_tree *tcp_tree, packet_info *pinfo, int offset, guint32 seq, guint32 nxtseq)
416 struct tcp_analysis *tcpd=NULL;
417 struct tcp_next_pdu *tnp=NULL;
420 if(!pinfo->fd->flags.visited){
421 /* find(or create if needed) the conversation for this tcp session */
422 tcpd=get_tcp_conversation_data(pinfo);
423 /* check direction and get pdu start lists */
424 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
425 /* if the addresses are equal, match the ports instead */
427 direction= (pinfo->srcport > pinfo->destport)*2-1;
435 /* scan and see if we find any pdus starting inside this tvb */
436 for(;tnp;tnp=tnp->next){
437 /* XXX here we should also try to handle sequence number
440 /* If this segment is completely within a previous PDU
441 * then we just skip this packet
443 if(seq>tnp->seq && nxtseq<=tnp->nxtpdu){
444 tnp->last_frame=pinfo->fd->num;
445 tnp->last_frame_time=pinfo->fd->abs_ts;
446 g_hash_table_insert(tcp_pdu_skipping_table,
447 GINT_TO_POINTER(pinfo->fd->num), (void *)tnp);
448 print_pdu_tracking_data(pinfo, tvb, tcp_tree, tnp);
452 if(seq<tnp->nxtpdu && nxtseq>tnp->nxtpdu){
453 g_hash_table_insert(tcp_pdu_tracking_table,
454 GINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(tnp->nxtpdu));
455 offset+=tnp->nxtpdu-seq;
462 tnp=(struct tcp_next_pdu *)g_hash_table_lookup(tcp_pdu_time_table, GINT_TO_POINTER(pinfo->fd->num));
467 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, tnp->last_frame);
468 PROTO_ITEM_SET_GENERATED(item);
470 nstime_delta(&ns, &tnp->last_frame_time, &pinfo->fd->abs_ts);
471 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
473 PROTO_ITEM_SET_GENERATED(item);
476 /* check if this is a segment in the middle of a pdu */
477 tnp=(struct tcp_next_pdu *)g_hash_table_lookup(tcp_pdu_skipping_table, GINT_TO_POINTER(pinfo->fd->num));
479 print_pdu_tracking_data(pinfo, tvb, tcp_tree, tnp);
483 pduseq=GPOINTER_TO_UINT(g_hash_table_lookup(tcp_pdu_tracking_table, GINT_TO_POINTER(pinfo->fd->num)));
492 /* if we saw a PDU that extended beyond the end of the segment,
493 use this function to remember where the next pdu starts
496 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu)
498 struct tcp_analysis *tcpd=NULL;
499 struct tcp_next_pdu *tnp=NULL;
502 /* find(or create if needed) the conversation for this tcp session */
503 tcpd=get_tcp_conversation_data(pinfo);
505 tnp=se_alloc(sizeof(struct tcp_next_pdu));
508 tnp->first_frame=pinfo->fd->num;
509 tnp->last_frame=pinfo->fd->num;
510 tnp->last_frame_time=pinfo->fd->abs_ts;
512 /* check direction and get pdu start list */
513 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
514 /* if the addresses are equal, match the ports instead */
516 direction= (pinfo->srcport > pinfo->destport)*2-1;
519 tnp->next=tcpd->pdu_seq1;
522 tnp->next=tcpd->pdu_seq2;
526 Add check for ACKs and purge list of sequence numbers
529 g_hash_table_insert(tcp_pdu_time_table, GINT_TO_POINTER(pinfo->fd->num), (void *)tnp);
532 /* This is called for SYN+ACK packets and the purpose is to verify that we
533 * have seen window scaling in both directions.
534 * If we cant find window scaling being set in both directions
535 * that means it was present in the SYN but not in the SYN+ACK
536 * (or the SYN was missing) and then we disable the window scaling
537 * for this tcp session.
539 static void verify_tcp_window_scaling(packet_info *pinfo)
541 struct tcp_analysis *tcpd=NULL;
543 /* find(or create if needed) the conversation for this tcp session */
544 tcpd=get_tcp_conversation_data(pinfo);
546 if( (tcpd->win_scale1==-1) || (tcpd->win_scale2==-1) ){
552 /* if we saw a window scaling option, store it for future reference
554 static void pdu_store_window_scale_option(packet_info *pinfo, guint8 ws)
556 struct tcp_analysis *tcpd=NULL;
559 /* find(or create if needed) the conversation for this tcp session */
560 tcpd=get_tcp_conversation_data(pinfo);
562 /* check direction and get pdu start list */
563 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
564 /* if the addresses are equal, match the ports instead */
566 direction= (pinfo->srcport > pinfo->destport)*2-1;
576 tcp_get_relative_seq_ack(guint32 frame, guint32 *seq, guint32 *ack, guint32 *win)
578 struct tcp_rel_seq *trs;
580 trs=g_hash_table_lookup(tcp_rel_seq_table, GUINT_TO_POINTER(frame));
585 (*seq) -= trs->seq_base;
586 (*ack) -= trs->ack_base;
587 if(trs->win_scale!=-1){
588 (*win)<<=trs->win_scale;
592 static struct tcp_acked *
593 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag)
595 struct tcp_acked *ta;
597 ta=g_hash_table_lookup(tcp_analyze_acked_table, GUINT_TO_POINTER(frame));
598 if((!ta) && createflag){
599 ta=se_alloc(sizeof(struct tcp_acked));
606 g_hash_table_insert(tcp_analyze_acked_table, GUINT_TO_POINTER(frame), ta);
612 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint32 window)
614 struct tcp_analysis *tcpd=NULL;
616 tcp_unacked_t *ual1=NULL;
617 tcp_unacked_t *ual2=NULL;
618 tcp_unacked_t *ual=NULL;
622 guint32 ack1_frame, ack2_frame;
623 nstime_t *ack1_time, *ack2_time;
624 guint32 num1_acks, num2_acks;
626 gint16 win_scale1,win_scale2;
627 struct tcp_next_pdu **tnp=NULL;
629 /* find(or create if needed) the conversation for this tcp session */
630 tcpd=get_tcp_conversation_data(pinfo);
632 /* check direction and get ua lists */
633 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
634 /* if the addresses are equal, match the ports instead */
636 direction= (pinfo->srcport > pinfo->destport)*2-1;
643 ack1_frame=tcpd->ack1_frame;
644 ack2_frame=tcpd->ack2_frame;
645 ack1_time=&tcpd->ack1_time;
646 ack2_time=&tcpd->ack2_time;
647 num1_acks=tcpd->num1_acks;
648 num2_acks=tcpd->num2_acks;
650 base_seq=(tcp_relative_seq && (ual1==NULL))?seq:tcpd->base_seq1;
651 base_ack=(tcp_relative_seq && (ual2==NULL))?ack:tcpd->base_seq2;
652 win_scale1=tcpd->win_scale1;
654 win_scale2=tcpd->win_scale2;
661 ack1_frame=tcpd->ack2_frame;
662 ack2_frame=tcpd->ack1_frame;
663 ack1_time=&tcpd->ack2_time;
664 ack2_time=&tcpd->ack1_time;
665 num1_acks=tcpd->num2_acks;
666 num2_acks=tcpd->num1_acks;
668 base_seq=(tcp_relative_seq && (ual1==NULL))?seq:tcpd->base_seq2;
669 base_ack=(tcp_relative_seq && (ual2==NULL))?ack:tcpd->base_seq1;
670 win_scale1=tcpd->win_scale2;
672 win_scale2=tcpd->win_scale1;
678 ack2_frame=pinfo->fd->num;
680 *ack2_time=pinfo->fd->abs_ts;
682 } else if(GT_SEQ(ack, ack2)){
683 ack2_frame=pinfo->fd->num;
685 *ack2_time=pinfo->fd->abs_ts;
691 /* useful debug ouput
692 * it prints the two lists of the sliding window emulation
695 tcp_unacked_t *u=NULL;
697 printf("analyze_sequence_number(frame:%d seq:%d nextseq:%d ack:%d baseseq:0x%08x baseack:0x%08x)\n",pinfo->fd->num,seq,seq+seglen,ack,base_seq,base_ack);
699 for(u=ual1;u;u=u->next){
700 printf(" Frame:%d seq:%d nseq:%d time:%d.%09d ack:%d:%d\n",u->frame,u->seq,u->nextseq,u->ts.secs,u->ts.nsecs,ack1,ack2);
703 for(u=ual2;u;u=u->next){
704 printf(" Frame:%d seq:%d nseq:%d time:%d.%09d ack:%d:%d\n",u->frame,u->seq,u->nextseq,u->ts.secs,u->ts.nsecs,ack1,ack2);
709 /* To handle FIN, just add 1 to the length.
710 else the ACK following the FIN-ACK will look like it was
711 outside the window. */
716 /* handle the sequence numbers */
717 /* if this was a SYN packet, then remove existing list and
718 * put SEQ+1 first the list, just "forget" the existing nodes */
720 for(ual=ual1;ual1;ual1=ual){
722 TCP_UNACKED_FREE(ual1);
724 TCP_UNACKED_NEW(ual1);
726 ual1->frame=pinfo->fd->num;
735 ual1->ts=pinfo->fd->abs_ts;
738 if(tcp_relative_seq){
740 /* if this was an SYN|ACK packet then set base_ack
741 * reflect the start of the sequence, i.e. one less
752 /* if this is the first segment we see then just add it */
754 TCP_UNACKED_NEW(ual1);
756 ual1->frame=pinfo->fd->num;
758 ual1->nextseq=seq+seglen;
759 ual1->ts=pinfo->fd->abs_ts;
762 if(tcp_relative_seq){
769 /* if we get past here we know that ual1 points to a segment */
772 /* if seq is beyond ual1->nextseq we have lost a segment */
773 if (GT_SEQ(seq, ual1->nextseq)) {
774 struct tcp_acked *ta;
776 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
777 ta->flags|=TCP_A_LOST_PACKET;
779 /* just add the segment to the beginning of the list */
780 TCP_UNACKED_NEW(ual);
782 ual->frame=pinfo->fd->num;
784 ual->nextseq=seq+seglen;
785 ual->ts=pinfo->fd->abs_ts;
792 /* keep-alives are empty segments with a sequence number -1 of what
795 * Solaris is an exception, Solaris does not really use KeepAlives
796 * according to RFC793, instead they move the left window edge one
797 * byte to the left and makes up a fake byte to fill in this position
798 * of the enlarged window.
799 * This means that Solaris will do "weird" KeepAlives that actually
800 * contains a one-byte segment with "random" junk data which the
801 * Solaris host then will try to transmit, and posisbly retransmit
802 * to the other side. Of course the other side will ignore this junk
803 * byte since it is outside (left of) the window.
804 * This is actually a brilliant trick that gives them, for free,
805 * semi-reliable KeepAlives.
806 * (since normal retransmission will handle any lost keepalive segments
809 if( (seglen<=1) && EQ_SEQ(seq, (ual1->nextseq-1)) ){
810 if(!(flags&TH_FIN)){ /* FIN segments are not keepalives */
811 struct tcp_acked *ta;
813 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
814 ta->flags|=TCP_A_KEEP_ALIVE;
815 ual1->flags|=TCP_A_KEEP_ALIVE;
820 /* if this is an empty segment, just skip it all */
825 /* check if the sequence number is lower than expected, i.e. either a
826 * retransmission a fast retransmission or an out of order segment
828 if( LT_SEQ(seq, ual1->nextseq )){
830 tcp_unacked_t *tu,*ntu;
832 /* assume it is a fast retransmission if
833 * 1 we have seen >=3 dupacks in the other direction for this
834 * segment (i.e. >=4 acks)
835 * 2 if this segment is the next unacked segment
836 * 3 this segment came within 10ms of the last dupack
837 * (10ms is arbitrary but should be low enough not to be
838 * confused with a retransmission timeout
840 if( (num1_acks>=4) && (seq==ack1) ){
843 t=(pinfo->fd->abs_ts.secs-ack1_time->secs)*1000000000;
844 t=t+(pinfo->fd->abs_ts.nsecs)-ack1_time->nsecs;
846 /* has to be a retransmission then */
847 struct tcp_acked *ta;
849 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
850 ta->flags|=TCP_A_FAST_RETRANSMISSION;
855 /* check it is a suspected out of order segment.
856 * we assume it is an out of order segment if
857 * 1 it has not been ACKed yet.
858 * 2 we have not seen the segment before
859 * 3 it arrived within (arbitrary value) 4ms of the
860 * next semgent in the sequence.
861 * 4 there were no dupacks in the opposite direction.
865 /* dont do this test. For full-duplex capture devices that
866 * capture in both directions using two NICs it is more common
867 * than one would expect for this to happen since they often
868 * lose the time integrity between the two NICs
870 /* 1 has it already been ACKed ? */
871 if(LT_SEQ(seq,ack1)){
875 /* 2 have we seen this segment before ? */
876 for(tu=ual1;tu;tu=tu->next){
877 if((tu->frame)&&(tu->seq==seq)){
881 /* 3 was it received within 4ms of the next segment ?*/
883 for(tu=ual1;tu;tu=tu->next){
884 if(LT_SEQ(seq,tu->seq)){
891 if(pinfo->fd->abs_ts.secs > ntu->ts.secs+2){
893 } else if(pinfo->fd->abs_ts.secs+2 < ntu->ts.secs){
898 t=(ntu->ts.secs-pinfo->fd->abs_ts.secs)*1000000000;
899 t=t+ntu->ts.nsecs-(pinfo->fd->abs_ts.nsecs);
909 struct tcp_acked *ta;
911 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
912 ta->flags|=TCP_A_OUT_OF_ORDER;
914 /* has to be a retransmission then */
915 struct tcp_acked *ta;
917 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
918 ta->flags|=TCP_A_RETRANSMISSION;
921 /* The code in the block here and is ifdeffed out tries to measure the RTO
922 * as the delta between the time the original pakcet was lost and this packet,
923 * which is essentially what the RTO is all about. We dont do that here.
925 * Instead we define the RTO as the delta between the retransmitted packet
926 * and the last previous data segment on the same session.
927 * This is an metric on how long the link were idle due to the RTO
928 * and thus since this reflects the real damage to performance this is much
929 * more interesting for most people.
930 * Measuring the RTO in this way, while technically not entirely correct,
931 * allows us to SUM(tcp.analysis.rto) for a session and we will have the amount
932 * of time for that session that was spent waiting for a retransmission instead
933 * of pushing data across.
935 /* measure RTO from the most recent frame we have in
936 * the sliding window that has a sequence number equal
937 * to or less than the retransmitted frame.
940 for(tu=ual1;tu;tu=tu->next){
941 if(GE_SEQ(seq,tu->seq)){
951 /* Set RTO to the delta since the previous
952 * segment with an equal or lower sequence
955 nstime_delta(&ta->rto_ts, &pinfo->fd->abs_ts, &ntu->ts);
956 ta->rto_frame=ntu->frame;
958 /* we didnt see any previous packet so we
959 * cant calculate the RTO
966 /* did this segment contain any more data we havent seen yet?
967 * if so we can just increase nextseq
969 if(GT_SEQ((seq+seglen), ual1->nextseq)){
970 ual1->nextseq=seq+seglen;
971 ual1->frame=pinfo->fd->num;
972 ual1->ts=pinfo->fd->abs_ts;
978 /* just add the segment to the beginning of the list */
979 TCP_UNACKED_NEW(ual);
981 ual->frame=pinfo->fd->num;
983 ual->nextseq=seq+seglen;
984 ual->ts=pinfo->fd->abs_ts;
993 /* handle the ack numbers */
995 /* if we dont have the ack flag its not much we can do */
996 if( !(flags&TH_ACK)){
1000 /* if we havent seen anything yet in the other direction we dont
1001 * know what this one acks */
1006 /* if we dont have any real segments in the other direction not
1007 * acked yet (as we see from the magic frame==0 entry)
1008 * then there is no point in continuing
1014 /* if we get here we know ual2 is valid */
1016 /* if we are acking beyong what we have seen in the other direction
1017 * we must have lost packets. Not much point in keeping the segments
1018 * in the other direction either. Just "forget" the old nodes.
1020 if( GT_SEQ(ack, ual2->nextseq )){
1021 struct tcp_acked *ta;
1023 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1024 ta->flags|=TCP_A_ACK_LOST_PACKET;
1025 for(ual=ual2;ual2;ual2=ual){
1027 TCP_UNACKED_FREE(ual2);
1029 prune_next_pdu_list(tnp, ack-base_ack);
1034 /* does this ACK ack all semgents we have seen in the other direction?*/
1035 if( EQ_SEQ(ack, ual2->nextseq )){
1036 struct tcp_acked *ta;
1038 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1039 ta->frame_acked=ual2->frame;
1040 nstime_delta(&ta->ts, &pinfo->fd->abs_ts, &ual2->ts);
1042 /* its all been ACKed so we dont need to keep them anymore */
1043 for(ual=ual2;ual2;ual2=ual){
1045 TCP_UNACKED_FREE(ual2);
1047 prune_next_pdu_list(tnp, ack-base_ack);
1051 /* ok it only ACKs part of what we have seen. Find out how much
1052 * update and remove the ACKed segments
1054 for(ual=ual2;ual->next;ual=ual->next){
1055 if( GE_SEQ(ack, ual->next->nextseq)){
1060 tcp_unacked_t *tmpual=NULL;
1061 tcp_unacked_t *ackedual=NULL;
1062 struct tcp_acked *ta;
1067 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1068 ta->frame_acked=ackedual->frame;
1069 nstime_delta(&ta->ts, &pinfo->fd->abs_ts, &ackedual->ts);
1071 /* just delete all ACKed segments */
1074 for(ual=tmpual;ual;ual=tmpual){
1076 TCP_UNACKED_FREE(ual);
1078 prune_next_pdu_list(tnp, ack-base_ack);
1082 /* we might have deleted the entire ual2 list, if this is an ACK,
1083 make sure ual2 at least has a dummy entry for the current ACK */
1084 if( (!ual2) && (flags&TH_ACK) ){
1085 TCP_UNACKED_NEW(ual2);
1092 ual2->window=window;
1096 /* update the ACK counter and check for
1098 /* go to the oldest segment in the list of segments
1099 in the other direction */
1100 /* XXX we should guarantee ual2 to always be non NULL here
1101 so we can skip the ual/ual2 tests */
1102 for(ual=ual2;ual&&ual->next;ual=ual->next)
1105 /* we only consider this being a potential duplicate ack
1106 if the segment length is 0 (ack only segment)
1107 and if it acks something previous to oldest segment
1108 in the other direction */
1109 if((!seglen)&&LE_SEQ(ack,ual->seq)){
1110 /* if this is the first ack to keep track of, it is not
1114 ack2_frame=pinfo->fd->num;
1116 /* if this ack is different, store this one
1117 instead and forget the previous one(s) */
1118 } else if(ack2!=ack){
1120 ack2_frame=pinfo->fd->num;
1122 /* this has to be a duplicate ack */
1127 /* is this an ACK to a KeepAlive? */
1128 if( (ual->flags&TCP_A_KEEP_ALIVE)
1129 && (ack==ual->seq) ){
1130 struct tcp_acked *ta;
1131 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1132 ta->flags|=TCP_A_KEEP_ALIVE_ACK;
1133 ual->flags^=TCP_A_KEEP_ALIVE;
1134 } else if(num2_acks>1) {
1135 /* ok we have found a potential duplicate ack */
1136 struct tcp_acked *ta;
1137 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1138 /* keepalives are not dupacks and
1139 * netiher are RST/FIN segments
1141 if( (!(ta->flags&TCP_A_KEEP_ALIVE))
1142 &&(!(flags&(TH_RST|TH_FIN))) ){
1144 * this could then either be a dupack
1145 * or maybe just a window update.
1147 if(win1==(gint32)window){
1148 ta->flags|=TCP_A_DUPLICATE_ACK;
1149 ta->dupack_num=num2_acks-1;
1150 ta->dupack_frame=ack2_frame;
1152 ta->flags|=TCP_A_WINDOW_UPDATE;
1160 /* see if this semgent has filled up the window completely,
1161 * i.e. same thing as if the other side would start sending
1162 * zero windows back to us.
1164 if( !(flags&TH_RST)){ /* RST segments are never WindowFull segments*/
1166 if( EQ_SEQ( (seq+seglen), (win2+ack1) ) ){
1167 struct tcp_acked *ta;
1168 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1169 ta->flags|=TCP_A_WINDOW_FULL;
1172 if( EQ_SEQ( (seq+seglen), ((win2<<win_scale2)+ack1) ) ){
1173 struct tcp_acked *ta;
1174 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1175 ta->flags|=TCP_A_WINDOW_FULL;
1180 /* check for zero window probes
1181 a zero window probe is when a TCP tries to write 1 byte segments
1182 where the remote side has advertised a window of 0 bytes.
1183 We only do this check if we actually have seen anything from the
1184 other side of this connection.
1186 We also assume ual still points to the last entry in the ual2
1187 list from the section above.
1189 At the same time, check for violations, i.e. attempts to write >1
1190 byte to a zero-window.
1192 /* XXX we should not need to do the ual->frame check here?
1193 might be a bug somewhere. look for it later .
1195 if(ual2&&(ual->frame)){
1196 if((seglen==1)&&(ual->window==0)){
1197 struct tcp_acked *ta;
1198 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1199 ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
1201 if((seglen>1)&&(ual->window==0)){
1202 struct tcp_acked *ta;
1203 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1204 ta->flags|=TCP_A_ZERO_WINDOW_VIOLATION;
1208 /* check for zero window
1209 * dont check for RST/FIN segments since the window field is
1210 * meaningless for those
1213 &&(!(flags&(TH_RST|TH_FIN))) ){
1214 struct tcp_acked *ta;
1215 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
1216 ta->flags|=TCP_A_ZERO_WINDOW;
1220 /* store the lists back in our struct */
1223 * XXX - if direction == 0, that'll be true for packets
1224 * from both sides of the connection, so this won't
1227 * That'd be a connection from a given port on a machine
1228 * to that same port on the same machine; does that ever
1235 tcpd->ack1_frame=ack1_frame;
1236 tcpd->ack2_frame=ack2_frame;
1237 tcpd->num1_acks=num1_acks;
1238 tcpd->num2_acks=num2_acks;
1239 tcpd->base_seq1=base_seq;
1240 tcpd->base_seq2=base_ack;
1247 tcpd->ack1_frame=ack2_frame;
1248 tcpd->ack2_frame=ack1_frame;
1249 tcpd->num1_acks=num2_acks;
1250 tcpd->num2_acks=num1_acks;
1251 tcpd->base_seq2=base_seq;
1252 tcpd->base_seq1=base_ack;
1257 if(tcp_relative_seq){
1258 struct tcp_rel_seq *trs;
1259 /* remember relative seq/ack number base for this packet */
1260 trs=se_alloc(sizeof(struct tcp_rel_seq));
1261 trs->seq_base=base_seq;
1262 trs->ack_base=base_ack;
1263 trs->win_scale=win_scale1;
1264 g_hash_table_insert(tcp_rel_seq_table, GINT_TO_POINTER(pinfo->fd->num), trs);
1269 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree)
1271 struct tcp_acked *ta;
1275 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE);
1280 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
1281 PROTO_ITEM_SET_GENERATED(item);
1282 tree=proto_item_add_subtree(item, ett_tcp_analysis);
1284 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
1285 data we actually have */
1286 if(ta->frame_acked){
1287 item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
1288 tvb, 0, 0, ta->frame_acked);
1289 PROTO_ITEM_SET_GENERATED(item);
1291 /* only display RTT if we actually have something we are acking */
1292 if( ta->ts.secs || ta->ts.nsecs ){
1293 item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
1294 tvb, 0, 0, &ta->ts);
1295 PROTO_ITEM_SET_GENERATED(item);
1300 proto_item *flags_item=NULL;
1301 proto_tree *flags_tree=NULL;
1303 flags_item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, -1, FALSE);
1304 PROTO_ITEM_SET_GENERATED(flags_item);
1305 flags_tree=proto_item_add_subtree(flags_item, ett_tcp_analysis);
1306 if( ta->flags&TCP_A_RETRANSMISSION ){
1307 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
1308 PROTO_ITEM_SET_GENERATED(flags_item);
1309 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Retransmission (suspected)");
1310 if(check_col(pinfo->cinfo, COL_INFO)){
1311 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
1313 if( ta->rto_ts.secs || ta->rto_ts.nsecs ){
1314 item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
1315 tvb, 0, 0, &ta->rto_ts);
1316 PROTO_ITEM_SET_GENERATED(item);
1317 item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame, tvb, 0, 0, ta->rto_frame);
1318 PROTO_ITEM_SET_GENERATED(item);
1321 if( ta->flags&TCP_A_FAST_RETRANSMISSION ){
1322 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_fast_retransmission, tvb, 0, 0, "This frame is a (suspected) fast retransmission");
1323 PROTO_ITEM_SET_GENERATED(flags_item);
1324 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Fast retransmission (suspected)");
1325 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
1326 PROTO_ITEM_SET_GENERATED(flags_item);
1327 if(check_col(pinfo->cinfo, COL_INFO)){
1328 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Fast Retransmission] ");
1331 if( ta->flags&TCP_A_OUT_OF_ORDER ){
1332 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_out_of_order, tvb, 0, 0, "This frame is a (suspected) out-of-order segment");
1333 PROTO_ITEM_SET_GENERATED(flags_item);
1334 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Out-Of-Order segment");
1335 if(check_col(pinfo->cinfo, COL_INFO)){
1336 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
1339 if( ta->flags&TCP_A_LOST_PACKET ){
1340 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_lost_packet, tvb, 0, 0, "A segment before this frame was lost");
1341 PROTO_ITEM_SET_GENERATED(flags_item);
1342 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Previous segment lost (common at capture start)");
1343 if(check_col(pinfo->cinfo, COL_INFO)){
1344 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] ");
1347 if( ta->flags&TCP_A_ACK_LOST_PACKET ){
1348 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_ack_lost_packet, tvb, 0, 0, "This frame ACKs a segment we have not seen (lost?)");
1349 PROTO_ITEM_SET_GENERATED(flags_item);
1350 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "ACKed lost segment (common at capture start)");
1351 if(check_col(pinfo->cinfo, COL_INFO)){
1352 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] ");
1355 if( ta->flags&TCP_A_WINDOW_UPDATE ){
1356 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_update, tvb, 0, 0, "This is a tcp window update");
1357 PROTO_ITEM_SET_GENERATED(flags_item);
1358 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window update");
1359 if(check_col(pinfo->cinfo, COL_INFO)){
1360 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
1363 if( ta->flags&TCP_A_WINDOW_FULL ){
1364 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_full, tvb, 0, 0, "The transmission window is now completely full");
1365 PROTO_ITEM_SET_GENERATED(flags_item);
1366 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window is full");
1367 if(check_col(pinfo->cinfo, COL_INFO)){
1368 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
1371 if( ta->flags&TCP_A_KEEP_ALIVE ){
1372 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive, tvb, 0, 0, "This is a TCP keep-alive segment");
1373 PROTO_ITEM_SET_GENERATED(flags_item);
1374 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive");
1375 if(check_col(pinfo->cinfo, COL_INFO)){
1376 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
1379 if( ta->flags&TCP_A_KEEP_ALIVE_ACK ){
1380 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive_ack, tvb, 0, 0, "This is an ACK to a TCP keep-alive segment");
1381 PROTO_ITEM_SET_GENERATED(flags_item);
1382 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive ACK");
1383 if(check_col(pinfo->cinfo, COL_INFO)){
1384 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
1387 if( ta->dupack_num){
1388 if( ta->flags&TCP_A_DUPLICATE_ACK ){
1389 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_duplicate_ack, tvb, 0, 0, "This is a TCP duplicate ack");
1390 PROTO_ITEM_SET_GENERATED(flags_item);
1391 if(check_col(pinfo->cinfo, COL_INFO)){
1392 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Dup ACK %u#%u] ", ta->dupack_frame, ta->dupack_num);
1395 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
1396 tvb, 0, 0, ta->dupack_num);
1397 PROTO_ITEM_SET_GENERATED(flags_item);
1398 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
1399 tvb, 0, 0, ta->dupack_frame);
1400 PROTO_ITEM_SET_GENERATED(flags_item);
1401 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Duplicate ACK (#%u) to ACK in packet #%u",
1402 ta->dupack_num, ta->dupack_frame);
1404 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE ){
1405 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_probe, tvb, 0, 0, "This is a TCP zero-window-probe");
1406 PROTO_ITEM_SET_GENERATED(flags_item);
1407 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe");
1408 if(check_col(pinfo->cinfo, COL_INFO)){
1409 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
1412 if( ta->flags&TCP_A_ZERO_WINDOW ){
1413 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window, tvb, 0, 0, "This is a ZeroWindow segment");
1414 PROTO_ITEM_SET_GENERATED(flags_item);
1415 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window");
1416 if(check_col(pinfo->cinfo, COL_INFO)){
1417 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
1420 if( ta->flags&TCP_A_ZERO_WINDOW_VIOLATION ){
1421 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_violation, tvb, 0, 0, "This is a ZeroWindow violation, attempts to write >1 byte of data to a zero-window");
1422 PROTO_ITEM_SET_GENERATED(flags_item);
1423 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window violation");
1424 if(check_col(pinfo->cinfo, COL_INFO)){
1425 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowViolation] ");
1433 /* Do we still need to do this ...remove_all() even though we dont need
1434 * to do anything special? The glib docs are not clear on this and
1435 * its better safe than sorry
1438 free_all_acked(gpointer key_arg _U_, gpointer value _U_, gpointer user_data _U_)
1444 tcp_acked_hash(gconstpointer k)
1446 guint32 frame = GPOINTER_TO_UINT(k);
1451 tcp_acked_equal(gconstpointer k1, gconstpointer k2)
1453 guint32 frame1 = GPOINTER_TO_UINT(k1);
1454 guint32 frame2 = GPOINTER_TO_UINT(k2);
1456 return frame1==frame2;
1460 tcp_analyze_seq_init(void)
1462 /* first destroy the tables */
1463 if( tcp_analyze_acked_table ){
1464 g_hash_table_foreach_remove(tcp_analyze_acked_table,
1465 free_all_acked, NULL);
1466 g_hash_table_destroy(tcp_analyze_acked_table);
1467 tcp_analyze_acked_table = NULL;
1469 if( tcp_rel_seq_table ){
1470 g_hash_table_foreach_remove(tcp_rel_seq_table,
1471 free_all_acked, NULL);
1472 g_hash_table_destroy(tcp_rel_seq_table);
1473 tcp_rel_seq_table = NULL;
1475 if( tcp_pdu_tracking_table ){
1476 g_hash_table_foreach_remove(tcp_pdu_tracking_table,
1477 free_all_acked, NULL);
1478 g_hash_table_destroy(tcp_pdu_tracking_table);
1479 tcp_pdu_tracking_table = NULL;
1481 if( tcp_pdu_time_table ){
1482 g_hash_table_foreach_remove(tcp_pdu_time_table,
1483 free_all_acked, NULL);
1484 g_hash_table_destroy(tcp_pdu_time_table);
1485 tcp_pdu_time_table = NULL;
1487 if( tcp_pdu_skipping_table ){
1488 g_hash_table_foreach_remove(tcp_pdu_skipping_table,
1489 free_all_acked, NULL);
1490 g_hash_table_destroy(tcp_pdu_skipping_table);
1491 tcp_pdu_skipping_table = NULL;
1494 if(tcp_analyze_seq){
1495 tcp_analyze_acked_table = g_hash_table_new(tcp_acked_hash,
1497 tcp_rel_seq_table = g_hash_table_new(tcp_acked_hash,
1499 tcp_pdu_time_table = g_hash_table_new(tcp_acked_hash,
1501 tcp_pdu_tracking_table = g_hash_table_new(tcp_acked_hash,
1503 tcp_pdu_skipping_table = g_hash_table_new(tcp_acked_hash,
1509 /* **************************************************************************
1510 * End of tcp sequence number analysis
1511 * **************************************************************************/
1516 /* Minimum TCP header length. */
1517 #define TCPH_MIN_LEN 20
1523 #define TCPOPT_NOP 1 /* Padding */
1524 #define TCPOPT_EOL 0 /* End of options */
1525 #define TCPOPT_MSS 2 /* Segment size negotiating */
1526 #define TCPOPT_WINDOW 3 /* Window scaling */
1527 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
1528 #define TCPOPT_SACK 5 /* SACK Block */
1529 #define TCPOPT_ECHO 6
1530 #define TCPOPT_ECHOREPLY 7
1531 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
1532 #define TCPOPT_CC 11
1533 #define TCPOPT_CCNEW 12
1534 #define TCPOPT_CCECHO 13
1535 #define TCPOPT_MD5 19 /* RFC2385 */
1538 * TCP option lengths
1541 #define TCPOLEN_MSS 4
1542 #define TCPOLEN_WINDOW 3
1543 #define TCPOLEN_SACK_PERM 2
1544 #define TCPOLEN_SACK_MIN 2
1545 #define TCPOLEN_ECHO 6
1546 #define TCPOLEN_ECHOREPLY 6
1547 #define TCPOLEN_TIMESTAMP 10
1548 #define TCPOLEN_CC 6
1549 #define TCPOLEN_CCNEW 6
1550 #define TCPOLEN_CCECHO 6
1551 #define TCPOLEN_MD5 18
1555 /* Desegmentation of TCP streams */
1556 /* table to hold defragmented TCP streams */
1557 static GHashTable *tcp_fragment_table = NULL;
1559 tcp_fragment_init(void)
1561 fragment_table_init(&tcp_fragment_table);
1564 /* functions to trace tcp segments */
1565 /* Enable desegmenting of TCP streams */
1566 static gboolean tcp_desegment = TRUE;
1568 static GHashTable *tcp_segment_table = NULL;
1569 static GMemChunk *tcp_segment_key_chunk = NULL;
1570 static int tcp_segment_init_count = 200;
1571 static GMemChunk *tcp_segment_address_chunk = NULL;
1572 static int tcp_segment_address_init_count = 500;
1574 typedef struct _tcp_segment_key {
1575 /* for own bookkeeping inside packet-tcp.c */
1584 guint32 first_frame;
1588 free_all_segments(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
1590 tcp_segment_key *key = key_arg;
1592 if((key->src)&&(key->src->data)){
1593 g_free((gpointer)key->src->data);
1594 key->src->data=NULL;
1597 if((key->dst)&&(key->dst->data)){
1598 g_free((gpointer)key->dst->data);
1599 key->dst->data=NULL;
1606 tcp_segment_hash(gconstpointer k)
1608 const tcp_segment_key *key = (const tcp_segment_key *)k;
1610 return key->seq+key->sport;
1614 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
1616 const tcp_segment_key *key1 = (const tcp_segment_key *)k1;
1617 const tcp_segment_key *key2 = (const tcp_segment_key *)k2;
1619 return ( ( (key1->seq==key2->seq)
1620 &&(ADDRESSES_EQUAL(key1->src, key2->src))
1621 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
1622 &&(key1->sport==key2->sport)
1623 &&(key1->dport==key2->dport)
1628 tcp_desegment_init(void)
1631 * Free this before freeing any memory chunks; those
1632 * chunks contain data we'll look at in "free_all_segments()".
1634 if(tcp_segment_table){
1635 g_hash_table_foreach_remove(tcp_segment_table,
1636 free_all_segments, NULL);
1637 g_hash_table_destroy(tcp_segment_table);
1638 tcp_segment_table = NULL;
1641 if(tcp_segment_key_chunk){
1642 g_mem_chunk_destroy(tcp_segment_key_chunk);
1643 tcp_segment_key_chunk = NULL;
1645 if(tcp_segment_address_chunk){
1646 g_mem_chunk_destroy(tcp_segment_address_chunk);
1647 tcp_segment_address_chunk = NULL;
1650 /* dont allocate any hash table or memory chunks unless the user
1651 really uses this option
1657 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
1660 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
1661 sizeof(tcp_segment_key),
1662 tcp_segment_init_count*sizeof(tcp_segment_key),
1665 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
1667 tcp_segment_address_init_count*sizeof(address),
1672 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1673 guint32 seq, guint32 nxtseq,
1674 guint32 sport, guint32 dport,
1675 proto_tree *tree, proto_tree *tcp_tree)
1677 struct tcpinfo *tcpinfo = pinfo->private_data;
1678 fragment_data *ipfd_head=NULL;
1679 tcp_segment_key old_tsk, *tsk;
1680 gboolean must_desegment = FALSE;
1681 gboolean called_dissector = FALSE;
1686 proto_item *frag_tree_item;
1687 proto_item *tcp_tree_item;
1691 * Initialize these to assume no desegmentation.
1692 * If that's not the case, these will be set appropriately
1693 * by the subdissector.
1695 pinfo->desegment_offset = 0;
1696 pinfo->desegment_len = 0;
1699 * Initialize this to assume that this segment will just be
1700 * added to the middle of a desegmented chunk of data, so
1701 * that we should show it all as data.
1702 * If that's not the case, it will be set appropriately.
1704 deseg_offset = offset;
1706 /* First we must check if this TCP segment should be desegmented.
1707 This is only to check if we should desegment this packet,
1708 so we dont spend time doing COPY_ADDRESS/g_free.
1709 We just "borrow" some address structures from pinfo instead. Cheaper.
1711 old_tsk.src = &pinfo->src;
1712 old_tsk.dst = &pinfo->dst;
1713 old_tsk.sport = sport;
1714 old_tsk.dport = dport;
1716 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1719 /* OK, this segment was found, which means it continues
1720 a higher-level PDU. This means we must desegment it.
1721 Add it to the defragmentation lists.
1723 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->first_frame,
1725 seq - tsk->start_seq,
1727 (LT_SEQ (nxtseq,tsk->start_seq + tsk->tot_len)) );
1730 /* fragment_add() returned NULL, This means that
1731 desegmentation is not completed yet.
1732 (its like defragmentation but we know we will
1733 always add the segments in order).
1734 XXX - no, we don't; there is no guarantee that
1735 TCP segments are in order on the wire.
1737 we must add next segment to our table so we will
1740 tcp_segment_key *new_tsk;
1742 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1743 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1744 new_tsk->seq=nxtseq;
1745 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1748 /* This segment was not found in our table, so it doesn't
1749 contain a continuation of a higher-level PDU.
1750 Call the normal subdissector.
1752 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1753 sport, dport, 0, 0, FALSE);
1754 called_dissector = TRUE;
1756 /* Did the subdissector ask us to desegment some more data
1757 before it could handle the packet?
1758 If so we have to create some structures in our table but
1759 this is something we only do the first time we see this
1762 if(pinfo->desegment_len) {
1763 if (!pinfo->fd->flags.visited)
1764 must_desegment = TRUE;
1767 * Set "deseg_offset" to the offset in "tvb"
1768 * of the first byte of data that the
1769 * subdissector didn't process.
1771 deseg_offset = offset + pinfo->desegment_offset;
1774 /* Either no desegmentation is necessary, or this is
1775 segment contains the beginning but not the end of
1776 a higher-level PDU and thus isn't completely
1782 /* is it completely desegmented? */
1784 fragment_data *ipfd;
1787 * Yes, we think it is.
1788 * We only call subdissector for the last segment.
1789 * Note that the last segment may include more than what
1792 if(GE_SEQ(nxtseq, tsk->start_seq + tsk->tot_len)){
1794 * OK, this is the last segment.
1795 * Let's call the subdissector with the desegmented
1801 /* create a new TVB structure for desegmented data */
1802 next_tvb = tvb_new_real_data(ipfd_head->data,
1803 ipfd_head->datalen, ipfd_head->datalen);
1805 /* add this tvb as a child to the original one */
1806 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1808 /* add desegmented data to the data source list */
1809 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1812 * Supply the sequence number of the first of the
1813 * reassembled bytes.
1815 tcpinfo->seq = tsk->start_seq;
1817 /* indicate that this is reassembled data */
1818 tcpinfo->is_reassembled = TRUE;
1820 /* call subdissector */
1821 process_tcp_payload(next_tvb, 0, pinfo, tree,
1822 tcp_tree, sport, dport, 0, 0, FALSE);
1823 called_dissector = TRUE;
1826 * OK, did the subdissector think it was completely
1827 * desegmented, or does it think we need even more
1830 old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
1831 if(pinfo->desegment_len &&
1832 pinfo->desegment_offset<=old_len){
1833 tcp_segment_key *new_tsk;
1836 * "desegment_len" isn't 0, so it needs more
1837 * data for something - and "desegment_offset"
1838 * is before "old_len", so it needs more data
1839 * to dissect the stuff we thought was
1840 * completely desegmented (as opposed to the
1841 * stuff at the beginning being completely
1842 * desegmented, but the stuff at the end
1843 * being a new higher-level PDU that also
1844 * needs desegmentation).
1846 fragment_set_partial_reassembly(pinfo,tsk->first_frame,tcp_fragment_table);
1847 tsk->tot_len = tvb_reported_length(next_tvb) + pinfo->desegment_len;
1850 * Update tsk structure.
1851 * Can ask ->next->next because at least there's a hdr and one
1852 * entry in fragment_add()
1854 for(ipfd=ipfd_head->next; ipfd->next; ipfd=ipfd->next){
1855 old_tsk.seq = tsk->start_seq + ipfd->offset;
1856 new_tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1857 new_tsk->tot_len = tsk->tot_len;
1860 /* this is the next segment in the sequence we want */
1861 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1862 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1863 new_tsk->seq = nxtseq;
1864 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1867 * Show the stuff in this TCP segment as
1868 * just raw TCP segment data.
1871 tvb_reported_length_remaining(tvb, offset);
1872 proto_tree_add_text(tcp_tree, tvb, offset, -1,
1873 "TCP segment data (%u byte%s)", nbytes,
1874 plurality(nbytes, "", "s"));
1877 * The subdissector thought it was completely
1878 * desegmented (although the stuff at the
1879 * end may, in turn, require desegmentation),
1880 * so we show a tree with all segments.
1882 show_fragment_tree(ipfd_head, &tcp_segment_items,
1883 tree, pinfo, next_tvb, &frag_tree_item);
1885 * The toplevel fragment subtree is now
1886 * behind all desegmented data; move it
1887 * right behind the TCP tree.
1889 tcp_tree_item = proto_tree_get_parent(tcp_tree);
1890 if(frag_tree_item && tcp_tree_item) {
1891 proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1894 /* Did the subdissector ask us to desegment
1895 some more data? This means that the data
1896 at the beginning of this segment completed
1897 a higher-level PDU, but the data at the
1898 end of this segment started a higher-level
1899 PDU but didn't complete it.
1901 If so, we have to create some structures
1902 in our table, but this is something we
1903 only do the first time we see this packet.
1905 if(pinfo->desegment_len) {
1906 if (!pinfo->fd->flags.visited)
1907 must_desegment = TRUE;
1909 /* The stuff we couldn't dissect
1910 must have come from this segment,
1911 so it's all in "tvb".
1913 "pinfo->desegment_offset" is
1914 relative to the beginning of
1915 "next_tvb"; we want an offset
1916 relative to the beginning of "tvb".
1918 First, compute the offset relative
1919 to the *end* of "next_tvb" - i.e.,
1920 the number of bytes before the end
1921 of "next_tvb" at which the
1922 subdissector stopped. That's the
1923 length of "next_tvb" minus the
1924 offset, relative to the beginning
1925 of "next_tvb, at which the
1926 subdissector stopped.
1929 ipfd_head->datalen - pinfo->desegment_offset;
1931 /* "tvb" and "next_tvb" end at the
1932 same byte of data, so the offset
1933 relative to the end of "next_tvb"
1934 of the byte at which we stopped
1935 is also the offset relative to
1936 the end of "tvb" of the byte at
1939 Convert that back into an offset
1940 relative to the beginninng of
1941 "tvb", by taking the length of
1942 "tvb" and subtracting the offset
1943 relative to the end.
1945 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1951 if (must_desegment) {
1952 tcp_segment_key *tsk, *new_tsk;
1955 * The sequence number at which the stuff to be desegmented
1956 * starts is the sequence number of the byte at an offset
1957 * of "deseg_offset" into "tvb".
1959 * The sequence number of the byte at an offset of "offset"
1960 * is "seq", i.e. the starting sequence number of this
1961 * segment, so the sequence number of the byte at
1962 * "deseg_offset" is "seq + (deseg_offset - offset)".
1964 deseg_seq = seq + (deseg_offset - offset);
1967 * XXX - how do we detect out-of-order transmissions?
1968 * We can't just check for "nxtseq" being greater than
1969 * "tsk->start_seq"; for now, we check for the difference
1970 * being less than a megabyte, but this is a really
1971 * gross hack - we really need to handle out-of-order
1972 * transmissions correctly.
1974 if ((nxtseq - deseg_seq) <= 1024*1024) {
1975 /* OK, subdissector wants us to desegment
1976 some data before it can process it. Add
1977 what remains of this packet and set
1978 up next packet/sequence number as well.
1980 We must remember this segment
1982 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1983 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
1984 COPY_ADDRESS(tsk->src, &pinfo->src);
1985 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
1986 COPY_ADDRESS(tsk->dst, &pinfo->dst);
1987 tsk->seq = deseg_seq;
1988 tsk->start_seq = tsk->seq;
1989 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
1990 tsk->first_frame = pinfo->fd->num;
1993 g_hash_table_insert(tcp_segment_table, tsk, tsk);
1995 /* Add portion of segment unprocessed by the subdissector
1996 to defragmentation lists */
1997 fragment_add(tvb, deseg_offset, pinfo, tsk->first_frame,
1999 tsk->seq - tsk->start_seq,
2000 nxtseq - tsk->start_seq,
2001 LT_SEQ (nxtseq, tsk->start_seq + tsk->tot_len));
2003 /* this is the next segment in the sequence we want */
2004 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
2005 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
2006 new_tsk->seq = nxtseq;
2007 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
2011 if (!called_dissector || pinfo->desegment_len != 0) {
2012 if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
2013 !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
2015 * We know what frame this PDU is reassembled in;
2016 * let the user know.
2018 item=proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in,
2019 tvb, 0, 0, ipfd_head->reassembled_in);
2020 PROTO_ITEM_SET_GENERATED(item);
2024 * Either we didn't call the subdissector at all (i.e.,
2025 * this is a segment that contains the middle of a
2026 * higher-level PDU, but contains neither the beginning
2027 * nor the end), or the subdissector couldn't dissect it
2028 * all, as some data was missing (i.e., it set
2029 * "pinfo->desegment_len" to the amount of additional
2032 if (pinfo->desegment_offset == 0) {
2034 * It couldn't, in fact, dissect any of it (the
2035 * first byte it couldn't dissect is at an offset
2036 * of "pinfo->desegment_offset" from the beginning
2037 * of the payload, and that's 0).
2038 * Just mark this as TCP.
2040 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
2041 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2043 if (check_col(pinfo->cinfo, COL_INFO)){
2044 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
2049 * Show what's left in the packet as just raw TCP segment
2051 * XXX - remember what protocol the last subdissector
2052 * was, and report it as a continuation of that, instead?
2054 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
2055 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
2056 "TCP segment data (%u byte%s)", nbytes,
2057 plurality(nbytes, "", "s"));
2059 pinfo->can_desegment=0;
2060 pinfo->desegment_offset = 0;
2061 pinfo->desegment_len = 0;
2065 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
2066 * consists of a fixed-length chunk of data that contains enough information
2067 * to determine the length of the PDU, followed by rest of the PDU.
2069 * The first three arguments are the arguments passed to the dissector
2070 * that calls this routine.
2072 * "proto_desegment" is the dissector's flag controlling whether it should
2073 * desegment PDUs that cross TCP segment boundaries.
2075 * "fixed_len" is the length of the fixed-length part of the PDU.
2077 * "get_pdu_len()" is a routine called to get the length of the PDU from
2078 * the fixed-length part of the PDU; it's passed "tvb" and "offset".
2080 * "dissect_pdu()" is the routine to dissect a PDU.
2083 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2084 gboolean proto_desegment, guint fixed_len,
2085 guint (*get_pdu_len)(tvbuff_t *, int),
2086 dissector_t dissect_pdu)
2088 volatile int offset = 0;
2090 guint length_remaining;
2095 while (tvb_reported_length_remaining(tvb, offset) != 0) {
2097 * We use "tvb_ensure_length_remaining()" to make sure there actually
2098 * *is* data remaining. The protocol we're handling could conceivably
2099 * consists of a sequence of fixed-length PDUs, and therefore the
2100 * "get_pdu_len" routine might not actually fetch anything from
2101 * the tvbuff, and thus might not cause an exception to be thrown if
2102 * we've run past the end of the tvbuff.
2104 * This means we're guaranteed that "length_remaining" is positive.
2106 length_remaining = tvb_ensure_length_remaining(tvb, offset);
2109 * Can we do reassembly?
2111 if (proto_desegment && pinfo->can_desegment) {
2113 * Yes - is the fixed-length part of the PDU split across segment
2116 if (length_remaining < fixed_len) {
2118 * Yes. Tell the TCP dissector where the data for this message
2119 * starts in the data it handed us, and how many more bytes we
2122 pinfo->desegment_offset = offset;
2123 pinfo->desegment_len = fixed_len - length_remaining;
2129 * Get the length of the PDU.
2131 plen = (*get_pdu_len)(tvb, offset);
2132 if (plen < fixed_len) {
2134 * The PDU length from the fixed-length portion probably didn't
2135 * include the fixed-length portion's length, and was probably so
2136 * large that the total length overflowed.
2138 * Report this as an error.
2140 show_reported_bounds_error(tvb, pinfo, tree);
2144 /* give a hint to TCP where the next PDU starts
2145 * so that it can attempt to find it in case it starts
2146 * somewhere in the middle of a segment.
2148 if(!pinfo->fd->flags.visited && tcp_analyze_seq){
2149 guint remaining_bytes;
2150 remaining_bytes=tvb_reported_length_remaining(tvb, offset);
2151 if(plen>remaining_bytes){
2152 pinfo->want_pdu_tracking=2;
2153 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
2158 * Can we do reassembly?
2160 if (proto_desegment && pinfo->can_desegment) {
2162 * Yes - is the PDU split across segment boundaries?
2164 if (length_remaining < plen) {
2166 * Yes. Tell the TCP dissector where the data for this message
2167 * starts in the data it handed us, and how many more bytes we
2170 pinfo->desegment_offset = offset;
2171 pinfo->desegment_len = plen - length_remaining;
2177 * Construct a tvbuff containing the amount of the payload we have
2178 * available. Make its reported length the amount of data in the PDU.
2180 * XXX - if reassembly isn't enabled. the subdissector will throw a
2181 * BoundsError exception, rather than a ReportedBoundsError exception.
2182 * We really want a tvbuff where the length is "length", the reported
2183 * length is "plen", and the "if the snapshot length were infinite"
2184 * length is the minimum of the reported length of the tvbuff handed
2185 * to us and "plen", with a new type of exception thrown if the offset
2186 * is within the reported length but beyond that third length, with
2187 * that exception getting the "Unreassembled Packet" error.
2189 length = length_remaining;
2192 next_tvb = tvb_new_subset(tvb, offset, length, plen);
2197 * Catch the ReportedBoundsError exception; if this particular message
2198 * happens to get a ReportedBoundsError exception, that doesn't mean
2199 * that we should stop dissecting PDUs within this frame or chunk of
2202 * If it gets a BoundsError, we can stop, as there's nothing more to
2203 * see, so we just re-throw it.
2206 (*dissect_pdu)(next_tvb, pinfo, tree);
2208 CATCH(BoundsError) {
2211 CATCH(ReportedBoundsError) {
2212 show_reported_bounds_error(tvb, pinfo, tree);
2217 * Step to the next PDU.
2218 * Make sure we don't overflow.
2220 offset_before = offset;
2222 if (offset <= offset_before)
2228 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
2230 if (check_col(pinfo->cinfo, COL_INFO))
2231 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
2235 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
2236 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2240 mss = tvb_get_ntohs(tvb, offset + 2);
2241 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_mss, tvb, offset,
2243 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
2244 optlen, mss, "%s: %u bytes", optp->name, mss);
2245 tcp_info_append_uint(pinfo, "MSS", mss);
2249 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
2250 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2254 ws = tvb_get_guint8(tvb, offset + 2);
2255 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_wscale, tvb,
2256 offset, optlen, TRUE);
2257 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
2258 offset, optlen, ws, "%s: %u (multiply by %u)",
2259 optp->name, ws, 1 << ws);
2260 tcp_info_append_uint(pinfo, "WS", ws);
2261 if(!pinfo->fd->flags.visited && tcp_analyze_seq && tcp_relative_seq){
2262 pdu_store_window_scale_option(pinfo, ws);
2267 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
2268 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2270 proto_tree *field_tree = NULL;
2271 proto_item *tf=NULL;
2272 guint32 leftedge, rightedge;
2273 struct tcp_analysis *tcpd=NULL;
2277 if(tcp_analyze_seq && tcp_relative_seq){
2278 /* find(or create if needed) the conversation for this tcp session */
2279 tcpd=get_tcp_conversation_data(pinfo);
2281 /* check direction and get ua lists */
2282 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2283 /* if the addresses are equal, match the ports instead */
2285 direction= (pinfo->srcport > pinfo->destport)*2-1;
2288 base_ack=tcpd->base_seq2;
2290 base_ack=tcpd->base_seq1;
2294 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
2295 offset += 2; /* skip past type and length */
2296 optlen -= 2; /* subtract size of type and length */
2297 while (optlen > 0) {
2298 if (field_tree == NULL) {
2299 /* Haven't yet made a subtree out of this option. Do so. */
2300 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2301 proto_tree_add_boolean_hidden(field_tree, hf_tcp_option_sack, tvb,
2302 offset, optlen, TRUE);
2305 proto_tree_add_text(field_tree, tvb, offset, optlen,
2306 "(suboption would go past end of option)");
2309 leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
2310 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
2311 offset, 4, leftedge,
2312 "left edge = %u%s", leftedge,
2313 tcp_relative_seq ? " (relative)" : "");
2317 proto_tree_add_text(field_tree, tvb, offset, optlen,
2318 "(suboption would go past end of option)");
2321 /* XXX - check whether it goes past end of packet */
2322 rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
2324 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
2325 offset+4, 4, rightedge,
2326 "right edge = %u%s", rightedge,
2327 tcp_relative_seq ? " (relative)" : "");
2328 tcp_info_append_uint(pinfo, "SLE", leftedge);
2329 tcp_info_append_uint(pinfo, "SRE", rightedge);
2330 proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
2336 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
2337 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2341 echo = tvb_get_ntohl(tvb, offset + 2);
2342 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_echo, tvb, offset,
2344 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2345 "%s: %u", optp->name, echo);
2346 tcp_info_append_uint(pinfo, "ECHO", echo);
2350 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
2351 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2355 tsv = tvb_get_ntohl(tvb, offset + 2);
2356 tser = tvb_get_ntohl(tvb, offset + 6);
2357 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_time_stamp, tvb,
2358 offset, optlen, TRUE);
2359 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2360 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
2361 tcp_info_append_uint(pinfo, "TSV", tsv);
2362 tcp_info_append_uint(pinfo, "TSER", tser);
2366 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
2367 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2371 cc = tvb_get_ntohl(tvb, offset + 2);
2372 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_cc, tvb, offset,
2374 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2375 "%s: %u", optp->name, cc);
2376 tcp_info_append_uint(pinfo, "CC", cc);
2379 static const ip_tcp_opt tcpopts[] = {
2398 "Maximum segment size",
2402 dissect_tcpopt_maxseg
2410 dissect_tcpopt_wscale
2423 &ett_tcp_option_sack,
2450 dissect_tcpopt_timestamp
2478 "TCP MD5 signature",
2486 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
2488 /* Determine if there is a sub-dissector and call it; return TRUE
2489 if there was a sub-dissector, FALSE otherwise.
2491 This has been separated into a stand alone routine to other protocol
2492 dissectors can call to it, e.g., SOCKS. */
2494 static gboolean try_heuristic_first = FALSE;
2497 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
2498 proto_tree *tree, int src_port, int dst_port)
2501 int low_port, high_port;
2503 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2505 /* determine if this packet is part of a conversation and call dissector */
2506 /* for the conversation if available */
2508 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
2509 src_port, dst_port, next_tvb, pinfo, tree)){
2510 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2514 if (try_heuristic_first) {
2515 /* do lookup with the heuristic subdissector table */
2516 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2517 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2522 /* Do lookups with the subdissector table.
2523 We try the port number with the lower value first, followed by the
2524 port number with the higher value. This means that, for packets
2525 where a dissector is registered for *both* port numbers:
2527 1) we pick the same dissector for traffic going in both directions;
2529 2) we prefer the port number that's more likely to be the right
2530 one (as that prefers well-known ports to reserved ports);
2532 although there is, of course, no guarantee that any such strategy
2533 will always pick the right port number.
2535 XXX - we ignore port numbers of 0, as some dissectors use a port
2536 number of 0 to disable the port. */
2537 if (src_port > dst_port) {
2538 low_port = dst_port;
2539 high_port = src_port;
2541 low_port = src_port;
2542 high_port = dst_port;
2544 if (low_port != 0 &&
2545 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree)){
2546 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2549 if (high_port != 0 &&
2550 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree)){
2551 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2555 if (!try_heuristic_first) {
2556 /* do lookup with the heuristic subdissector table */
2557 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2558 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2563 /* Oh, well, we don't know this; dissect it as data. */
2564 call_dissector(data_handle,next_tvb, pinfo, tree);
2566 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2571 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
2572 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
2573 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment)
2575 pinfo->want_pdu_tracking=0;
2579 /*qqq see if it is an unaligned PDU */
2580 if(tcp_analyze_seq && (!tcp_desegment)){
2582 offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
2587 /* if offset is -1 this means that this segment is known
2588 * to be fully inside a previously detected pdu
2589 * so we dont even need to try to dissect it either.
2592 decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
2595 * We succeeded in handing off to a subdissector.
2597 * Is this a TCP segment or a reassembled chunk of
2601 /* if !visited, check want_pdu_tracking and
2602 store it in table */
2603 if((!pinfo->fd->flags.visited) &&
2604 tcp_analyze_seq && pinfo->want_pdu_tracking){
2606 pdu_store_sequencenumber_of_next_pdu(
2609 nxtseq+pinfo->bytes_until_next_pdu);
2616 /* We got an exception. At this point the dissection is
2617 * completely aborted and execution will be transfered back
2618 * to (probably) the frame dissector.
2619 * Here we have to place whatever we want the dissector
2620 * to do before aborting the tcp dissection.
2623 * Is this a TCP segment or a reassembled chunk of TCP
2628 * It's from a TCP segment.
2630 * if !visited, check want_pdu_tracking and store it
2633 if((!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking){
2635 pdu_store_sequencenumber_of_next_pdu(pinfo,
2637 nxtseq+pinfo->bytes_until_next_pdu);
2647 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
2648 guint32 nxtseq, guint32 sport, guint32 dport,
2649 proto_tree *tree, proto_tree *tcp_tree)
2651 gboolean save_fragmented;
2653 /* Can we desegment this segment? */
2654 if (pinfo->can_desegment) {
2656 desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
2659 /* No - just call the subdissector.
2660 Mark this as fragmented, so if somebody throws an exception,
2661 we don't report it as a malformed frame. */
2662 save_fragmented = pinfo->fragmented;
2663 pinfo->fragmented = TRUE;
2664 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
2666 pinfo->fragmented = save_fragmented;
2671 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2673 guint8 th_off_x2; /* combines th_off and th_x2 */
2676 proto_tree *tcp_tree = NULL, *field_tree = NULL;
2677 proto_item *ti = NULL, *tf;
2679 gchar *flags = "<None>";
2680 const gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
2681 size_t fpos = 0, returned_length;
2689 guint16 computed_cksum;
2690 guint16 real_window;
2691 guint length_remaining;
2692 gboolean desegment_ok;
2693 struct tcpinfo tcpinfo;
2694 static struct tcpheader tcphstruct[4], *tcph;
2695 static int tcph_count=0;
2696 proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
2702 tcph=&tcphstruct[tcph_count];
2703 SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
2704 SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
2706 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2707 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2709 /* Clear out the Info column. */
2710 if (check_col(pinfo->cinfo, COL_INFO))
2711 col_clear(pinfo->cinfo, COL_INFO);
2713 tcph->th_sport = tvb_get_ntohs(tvb, offset);
2714 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
2715 if (check_col(pinfo->cinfo, COL_INFO)) {
2716 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
2717 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2720 if (tcp_summary_in_tree) {
2721 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
2722 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
2723 get_tcp_port(tcph->th_sport), tcph->th_sport,
2724 get_tcp_port(tcph->th_dport), tcph->th_dport);
2727 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
2729 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
2730 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
2731 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
2732 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
2733 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
2734 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
2735 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
2738 /* Set the source and destination port numbers as soon as we get them,
2739 so that they're available to the "Follow TCP Stream" code even if
2740 we throw an exception dissecting the rest of the TCP header. */
2741 pinfo->ptype = PT_TCP;
2742 pinfo->srcport = tcph->th_sport;
2743 pinfo->destport = tcph->th_dport;
2745 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
2746 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
2747 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
2748 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
2749 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
2750 real_window = tcph->th_win;
2751 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
2754 * If we've been handed an IP fragment, we don't know how big the TCP
2755 * segment is, so don't do anything that requires that we know that.
2757 * The same applies if we're part of an error packet. (XXX - if the
2758 * ICMP and ICMPv6 dissectors could set a "this is how big the IP
2759 * header says it is" length in the tvbuff, we could use that; such
2760 * a length might also be useful for handling packets where the IP
2761 * length is bigger than the actual data available in the frame; the
2762 * dissectors should trust that length, and then throw a
2763 * ReportedBoundsError exception when they go past the end of the frame.)
2765 * We also can't determine the segment length if the reported length
2766 * of the TCP packet is less than the TCP header length.
2768 reported_len = tvb_reported_length(tvb);
2770 if (!pinfo->fragmented && !pinfo->in_error_pkt) {
2771 if (reported_len < tcph->th_hlen) {
2772 proto_tree_add_text(tcp_tree, tvb, offset, 0,
2773 "Short segment. Segment/fragment does not contain a full TCP header"
2774 " (might be NMAP or someone else deliberately sending unusual packets)");
2775 tcph->th_have_seglen = FALSE;
2777 /* Compute the length of data in this segment. */
2778 tcph->th_seglen = reported_len - tcph->th_hlen;
2779 tcph->th_have_seglen = TRUE;
2781 if (tree) { /* Add the seglen as an invisible field */
2783 proto_tree_add_uint_hidden(ti, hf_tcp_len, tvb, offset, 4, tcph->th_seglen);
2787 /* handle TCP seq# analysis parse all new segments we see */
2788 if(tcp_analyze_seq){
2789 if(!(pinfo->fd->flags.visited)){
2790 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win);
2792 if(tcp_relative_seq){
2793 tcp_get_relative_seq_ack(pinfo->fd->num, &(tcph->th_seq), &(tcph->th_ack), &(tcph->th_win));
2797 /* Compute the sequence number of next octet after this segment. */
2798 nxtseq = tcph->th_seq + tcph->th_seglen;
2801 tcph->th_have_seglen = FALSE;
2803 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
2804 #define MAX_FLAGS_LEN 64
2805 flags=ep_alloc(MAX_FLAGS_LEN);
2807 for (i = 0; i < 8; i++) {
2809 if (tcph->th_flags & bpos) {
2810 returned_length = g_snprintf(&flags[fpos], MAX_FLAGS_LEN-fpos, "%s%s",
2813 fpos += MIN(returned_length, MAX_FLAGS_LEN-fpos);
2818 if (check_col(pinfo->cinfo, COL_INFO)) {
2819 if(tcph->th_flags&TH_ACK){
2820 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
2821 flags, tcph->th_seq, tcph->th_ack, tcph->th_win);
2823 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u",
2824 flags, tcph->th_seq);
2829 if (tcp_summary_in_tree) {
2830 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
2832 if(tcp_relative_seq){
2833 proto_tree_add_uint_format(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq, "Sequence number: %u (relative sequence number)", tcph->th_seq);
2835 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
2839 if (tcph->th_hlen < TCPH_MIN_LEN) {
2840 /* Give up at this point; we put the source and destination port in
2841 the tree, before fetching the header length, so that they'll
2842 show up if this is in the failing packet in an ICMP error packet,
2843 but it's now time to give up if the header length is bogus. */
2844 if (check_col(pinfo->cinfo, COL_INFO))
2845 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
2846 tcph->th_hlen, TCPH_MIN_LEN);
2848 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2849 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
2856 if (tcp_summary_in_tree) {
2857 if(tcph->th_flags&TH_ACK){
2858 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
2860 if (tcph->th_have_seglen)
2861 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
2863 proto_item_set_len(ti, tcph->th_hlen);
2864 if (tcph->th_have_seglen) {
2865 if (nxtseq != tcph->th_seq) {
2866 if(tcp_relative_seq){
2867 tf=proto_tree_add_uint_format(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "Next sequence number: %u (relative sequence number)", nxtseq);
2869 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
2871 PROTO_ITEM_SET_GENERATED(tf);
2874 if (tcph->th_flags & TH_ACK) {
2875 if(tcp_relative_seq){
2876 proto_tree_add_uint_format(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack, "Acknowledgement number: %u (relative ack number)", tcph->th_ack);
2878 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
2881 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2882 "Header length: %u bytes", tcph->th_hlen);
2883 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
2884 tcph->th_flags, "Flags: 0x%04x (%s)", tcph->th_flags, flags);
2885 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
2886 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
2887 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
2888 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
2889 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
2890 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
2891 tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
2892 tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
2893 tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
2894 if(tcp_relative_seq && (tcph->th_win!=real_window)){
2895 proto_tree_add_uint_format(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win, "Window size: %u (scaled)", tcph->th_win);
2897 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
2901 if(tcph->th_flags & TH_SYN) {
2902 if(tcph->th_flags & TH_ACK)
2903 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): %s -> %s",
2904 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2906 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): %s -> %s",
2907 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2909 if(tcph->th_flags & TH_FIN)
2910 expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN): %s -> %s",
2911 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2912 if(tcph->th_flags & TH_RST)
2913 expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST): %s -> %s",
2914 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2916 /* Supply the sequence number of the first byte and of the first byte
2917 after the segment. */
2918 tcpinfo.seq = tcph->th_seq;
2919 tcpinfo.nxtseq = nxtseq;
2921 /* Assume we'll pass un-reassembled data to subdissectors. */
2922 tcpinfo.is_reassembled = FALSE;
2924 pinfo->private_data = &tcpinfo;
2927 * Assume, initially, that we can't desegment.
2929 pinfo->can_desegment = 0;
2930 th_sum = tvb_get_ntohs(tvb, offset + 16);
2931 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
2932 /* The packet isn't part of an un-reassembled fragmented datagram
2933 and isn't truncated. This means we have all the data, and thus
2934 can checksum it and, unless it's being returned in an error
2935 packet, are willing to allow subdissectors to request reassembly
2938 if (tcp_check_checksum) {
2939 /* We haven't turned checksum checking off; checksum it. */
2941 /* Set up the fields of the pseudo-header. */
2942 cksum_vec[0].ptr = pinfo->src.data;
2943 cksum_vec[0].len = pinfo->src.len;
2944 cksum_vec[1].ptr = pinfo->dst.data;
2945 cksum_vec[1].len = pinfo->dst.len;
2946 cksum_vec[2].ptr = (const guint8 *)&phdr;
2947 switch (pinfo->src.type) {
2950 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
2951 cksum_vec[2].len = 4;
2955 phdr[0] = g_htonl(reported_len);
2956 phdr[1] = g_htonl(IP_PROTO_TCP);
2957 cksum_vec[2].len = 8;
2961 /* TCP runs only atop IPv4 and IPv6.... */
2962 DISSECTOR_ASSERT_NOT_REACHED();
2965 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
2966 cksum_vec[3].len = reported_len;
2967 computed_cksum = in_cksum(&cksum_vec[0], 4);
2968 if (computed_cksum == 0) {
2969 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2970 offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
2972 /* Checksum is valid, so we're willing to desegment it. */
2973 desegment_ok = TRUE;
2977 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2978 offset + 16, 2, th_sum,
2979 "Checksum: 0x%04x [incorrect, should be 0x%04x]", th_sum,
2980 in_cksum_shouldbe(th_sum, computed_cksum));
2981 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
2982 item = proto_tree_add_boolean(tcp_tree, hf_tcp_checksum_bad, tvb,
2983 offset + 16, 2, TRUE);
2984 PROTO_ITEM_SET_GENERATED(item);
2985 /* XXX - don't use hidden fields for checksums */
2986 PROTO_ITEM_SET_HIDDEN(item);
2988 if (check_col(pinfo->cinfo, COL_INFO))
2989 col_append_fstr(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
2991 /* Checksum is invalid, so we're not willing to desegment it. */
2992 desegment_ok = FALSE;
2993 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
2996 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2997 offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
2999 /* We didn't check the checksum, and don't care if it's valid,
3000 so we're willing to desegment it. */
3001 desegment_ok = TRUE;
3004 /* We don't have all the packet data, so we can't checksum it... */
3005 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3006 offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
3008 /* ...and aren't willing to desegment it. */
3009 desegment_ok = FALSE;
3013 /* We're willing to desegment this. Is desegmentation enabled? */
3014 if (tcp_desegment) {
3015 /* Yes - is this segment being returned in an error packet? */
3016 if (!pinfo->in_error_pkt) {
3017 /* No - indicate that we will desegment.
3018 We do NOT want to desegment segments returned in error
3019 packets, as they're not part of a TCP connection. */
3020 pinfo->can_desegment = 2;
3025 if (tcph->th_flags & TH_URG) {
3026 th_urp = tvb_get_ntohs(tvb, offset + 18);
3027 /* Export the urgent pointer, for the benefit of protocols such as
3029 tcpinfo.urgent = TRUE;
3030 tcpinfo.urgent_pointer = th_urp;
3031 if (check_col(pinfo->cinfo, COL_INFO))
3032 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
3033 if (tcp_tree != NULL)
3034 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
3036 tcpinfo.urgent = FALSE;
3038 if (tcph->th_have_seglen) {
3039 if (check_col(pinfo->cinfo, COL_INFO))
3040 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
3043 /* Decode TCP options, if any. */
3044 if (tcph->th_hlen > TCPH_MIN_LEN) {
3045 /* There's more than just the fixed-length header. Decode the
3047 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
3048 tvb_ensure_bytes_exist(tvb, offset + 20, optlen);
3049 if (tcp_tree != NULL) {
3050 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
3051 "Options: (%u bytes)", optlen);
3052 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
3055 dissect_ip_tcp_options(tvb, offset + 20, optlen,
3056 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
3059 /* If there was window scaling in the SYN packet byt none in the SYN+ACK
3060 * then we should just forget about the windowscaling completely.
3062 if(!pinfo->fd->flags.visited){
3063 if(tcp_analyze_seq && tcp_relative_seq){
3064 if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
3065 verify_tcp_window_scaling(pinfo);
3070 /* Skip over header + options */
3071 offset += tcph->th_hlen;
3073 /* Check the packet length to see if there's more data
3074 (it could be an ACK-only packet) */
3075 length_remaining = tvb_length_remaining(tvb, offset);
3077 if (tcph->th_have_seglen) {
3078 if( data_out_file ) {
3079 reassemble_tcp( tcph->th_seq, /* sequence number */
3080 tcph->th_seglen, /* data length */
3081 tvb_get_ptr(tvb, offset, length_remaining), /* data */
3082 length_remaining, /* captured data length */
3083 ( tcph->th_flags & TH_SYN ), /* is syn set? */
3091 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
3092 if(tcp_analyze_seq){
3093 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree);
3095 tap_queue_packet(tcp_tap, pinfo, tcph);
3098 * XXX - what, if any, of this should we do if this is included in an
3099 * error packet? It might be nice to see the details of the packet
3100 * that caused the ICMP error, but it might not be nice to have the
3101 * dissector update state based on it.
3102 * Also, we probably don't want to run TCP taps on those packets.
3104 if (length_remaining != 0) {
3105 if (tcph->th_flags & TH_RST) {
3109 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
3111 * A TCP SHOULD allow a received RST segment to include data.
3114 * It has been suggested that a RST segment could contain
3115 * ASCII text that encoded and explained the cause of the
3116 * RST. No standard has yet been established for such
3119 * so for segments with RST we just display the data as text.
3121 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
3123 tvb_format_text(tvb, offset, length_remaining));
3125 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
3126 tcph->th_sport, tcph->th_dport, tree, tcp_tree);
3132 proto_register_tcp(void)
3134 static hf_register_info hf[] = {
3137 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
3141 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
3145 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
3149 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
3153 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
3157 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
3161 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
3165 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
3168 { &hf_tcp_flags_cwr,
3169 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
3172 { &hf_tcp_flags_ecn,
3173 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
3176 { &hf_tcp_flags_urg,
3177 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
3180 { &hf_tcp_flags_ack,
3181 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
3184 { &hf_tcp_flags_push,
3185 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
3188 { &hf_tcp_flags_reset,
3189 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
3192 { &hf_tcp_flags_syn,
3193 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
3196 { &hf_tcp_flags_fin,
3197 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
3200 /* 32 bits so we can present some values adjusted to window scaling */
3201 { &hf_tcp_window_size,
3202 { "Window size", "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
3206 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
3209 { &hf_tcp_checksum_bad,
3210 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3213 { &hf_tcp_analysis_flags,
3214 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
3215 "This frame has some of the TCP analysis flags set", HFILL }},
3217 { &hf_tcp_analysis_retransmission,
3218 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
3219 "This frame is a suspected TCP retransmission", HFILL }},
3221 { &hf_tcp_analysis_fast_retransmission,
3222 { "Fast Retransmission", "tcp.analysis.fast_retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
3223 "This frame is a suspected TCP fast retransmission", HFILL }},
3225 { &hf_tcp_analysis_out_of_order,
3226 { "Out Of Order", "tcp.analysis.out_of_order", FT_NONE, BASE_NONE, NULL, 0x0,
3227 "This frame is a suspected Out-Of-Order segment", HFILL }},
3229 { &hf_tcp_analysis_lost_packet,
3230 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
3231 "A segment before this one was lost from the capture", HFILL }},
3233 { &hf_tcp_analysis_ack_lost_packet,
3234 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
3235 "This frame ACKs a lost segment", HFILL }},
3237 { &hf_tcp_analysis_window_update,
3238 { "Window update", "tcp.analysis.window_update", FT_NONE, BASE_NONE, NULL, 0x0,
3239 "This frame is a tcp window update", HFILL }},
3241 { &hf_tcp_analysis_window_full,
3242 { "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
3243 "This segment has caused the allowed window to become 100% full", HFILL }},
3245 { &hf_tcp_analysis_keep_alive,
3246 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
3247 "This is a keep-alive segment", HFILL }},
3249 { &hf_tcp_analysis_keep_alive_ack,
3250 { "Keep Alive ACK", "tcp.analysis.keep_alive_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3251 "This is an ACK to a keep-alive segment", HFILL }},
3253 { &hf_tcp_analysis_duplicate_ack,
3254 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3255 "This is a duplicate ACK", HFILL }},
3257 { &hf_tcp_analysis_duplicate_ack_num,
3258 { "Duplicate ACK #", "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
3259 "This is duplicate ACK number #", HFILL }},
3261 { &hf_tcp_analysis_duplicate_ack_frame,
3262 { "Duplicate to the ACK in frame", "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3263 "This is a duplicate to the ACK in frame #", HFILL }},
3265 { &hf_tcp_continuation_to,
3266 { "This is a continuation to the PDU in frame", "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3267 "This is a continuation to the PDU in frame #", HFILL }},
3269 { &hf_tcp_analysis_zero_window_violation,
3270 { "Zero Window Violation", "tcp.analysis.zero_window_violation", FT_NONE, BASE_NONE, NULL, 0x0,
3271 "This is a zero-window violation, an attempt to write >1 byte to a zero-window", HFILL }},
3273 { &hf_tcp_analysis_zero_window_probe,
3274 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
3275 "This is a zero-window-probe", HFILL }},
3277 { &hf_tcp_analysis_zero_window,
3278 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
3279 "This is a zero-window", HFILL }},
3282 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
3285 { &hf_tcp_analysis_acks_frame,
3286 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3287 "Which previous segment is this an ACK for", HFILL}},
3289 { &hf_tcp_analysis_ack_rtt,
3290 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3291 "How long time it took to ACK the segment (RTT)", HFILL}},
3293 { &hf_tcp_analysis_rto,
3294 { "The RTO for this segment was", "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3295 "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
3297 { &hf_tcp_analysis_rto_frame,
3298 { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3299 "This is the frame we measure the RTO from", HFILL }},
3301 { &hf_tcp_urgent_pointer,
3302 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
3305 { &hf_tcp_segment_overlap,
3306 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3307 "Segment overlaps with other segments", HFILL }},
3309 { &hf_tcp_segment_overlap_conflict,
3310 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3311 "Overlapping segments contained conflicting data", HFILL }},
3313 { &hf_tcp_segment_multiple_tails,
3314 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3315 "Several tails were found when reassembling the pdu", HFILL }},
3317 { &hf_tcp_segment_too_long_fragment,
3318 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3319 "Segment contained data past end of the pdu", HFILL }},
3321 { &hf_tcp_segment_error,
3322 { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3323 "Reassembling error due to illegal segments", HFILL }},
3326 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3327 "TCP Segment", HFILL }},
3330 { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
3331 "TCP Segments", HFILL }},
3333 { &hf_tcp_reassembled_in,
3334 { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3335 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
3337 { &hf_tcp_option_mss,
3338 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
3339 BASE_NONE, NULL, 0x0, "TCP MSS Option", HFILL }},
3341 { &hf_tcp_option_mss_val,
3342 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
3343 BASE_DEC, NULL, 0x0, "TCP MSS Option Value", HFILL}},
3345 { &hf_tcp_option_wscale,
3346 { "TCP Window Scale Option", "tcp.options.wscale",
3348 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
3350 { &hf_tcp_option_wscale_val,
3351 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
3352 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
3355 { &hf_tcp_option_sack_perm,
3356 { "TCP Sack Perm Option", "tcp.options.sack_perm",
3358 BASE_NONE, NULL, 0x0, "TCP Sack Perm Option", HFILL}},
3360 { &hf_tcp_option_sack,
3361 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
3362 BASE_NONE, NULL, 0x0, "TCP Sack Option", HFILL}},
3364 { &hf_tcp_option_sack_sle,
3365 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
3366 BASE_DEC, NULL, 0x0, "TCP Sack Left Edge", HFILL}},
3368 { &hf_tcp_option_sack_sre,
3369 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
3370 BASE_DEC, NULL, 0x0, "TCP Sack Right Edge", HFILL}},
3372 { &hf_tcp_option_echo,
3373 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
3374 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
3376 { &hf_tcp_option_echo_reply,
3377 { "TCP Echo Reply Option", "tcp.options.echo_reply",
3379 BASE_NONE, NULL, 0x0, "TCP Echo Reply Option", HFILL}},
3381 { &hf_tcp_option_time_stamp,
3382 { "TCP Time Stamp Option", "tcp.options.time_stamp",
3384 BASE_NONE, NULL, 0x0, "TCP Time Stamp Option", HFILL}},
3386 { &hf_tcp_option_cc,
3387 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
3388 NULL, 0x0, "TCP CC Option", HFILL}},
3390 { &hf_tcp_option_ccnew,
3391 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
3392 BASE_NONE, NULL, 0x0, "TCP CC New Option", HFILL}},
3394 { &hf_tcp_option_ccecho,
3395 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
3396 BASE_NONE, NULL, 0x0, "TCP CC Echo Option", HFILL}},
3398 { &hf_tcp_option_md5,
3399 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
3400 NULL, 0x0, "TCP MD5 Option", HFILL}},
3403 { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3404 "How long time has passed until the last frame of this PDU", HFILL}},
3405 { &hf_tcp_pdu_last_frame,
3406 { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3407 "This is the last frame of the PDU starting in this segment", HFILL }},
3410 static gint *ett[] = {
3414 &ett_tcp_option_sack,
3415 &ett_tcp_analysis_faults,
3420 module_t *tcp_module;
3422 proto_tcp = proto_register_protocol("Transmission Control Protocol",
3424 proto_register_field_array(proto_tcp, hf, array_length(hf));
3425 proto_register_subtree_array(ett, array_length(ett));
3427 /* subdissector code */
3428 subdissector_table = register_dissector_table("tcp.port",
3429 "TCP port", FT_UINT16, BASE_DEC);
3430 register_heur_dissector_list("tcp", &heur_subdissector_list);
3432 /* Register configuration preferences */
3433 tcp_module = prefs_register_protocol(proto_tcp, NULL);
3434 prefs_register_bool_preference(tcp_module, "summary_in_tree",
3435 "Show TCP summary in protocol tree",
3436 "Whether the TCP summary line should be shown in the protocol tree",
3437 &tcp_summary_in_tree);
3438 prefs_register_bool_preference(tcp_module, "check_checksum",
3439 "Validate the TCP checksum if possible",
3440 "Whether to validate the TCP checksum",
3441 &tcp_check_checksum);
3442 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
3443 "Allow subdissector to reassemble TCP streams",
3444 "Whether subdissector can request TCP streams to be reassembled",
3446 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
3447 "Analyze TCP sequence numbers",
3448 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
3450 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
3451 "Relative sequence numbers and window scaling",
3452 "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
3453 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
3454 "This option will also try to track and adjust the window field according to any TCP window scaling options seen.",
3456 prefs_register_bool_preference(tcp_module, "try_heuristic_first",
3457 "Try heuristic sub-dissectors first",
3458 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
3459 &try_heuristic_first);
3461 register_init_routine(tcp_analyze_seq_init);
3462 register_init_routine(tcp_desegment_init);
3463 register_init_routine(tcp_fragment_init);
3467 proto_reg_handoff_tcp(void)
3469 dissector_handle_t tcp_handle;
3471 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
3472 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
3473 data_handle = find_dissector("data");
3474 tcp_tap = register_tap("tcp");