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 <epan/emem.h>
41 #include "packet-tcp.h"
42 #include "packet-ip.h"
43 #include "packet-frame.h"
44 #include <epan/conversation.h>
45 #include <epan/strutil.h>
46 #include <epan/reassemble.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_probe_ack = -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 */
173 /* **************************************************************************
175 * RTT and reltive sequence numbers.
176 * **************************************************************************/
177 static gboolean tcp_analyze_seq = TRUE;
178 static gboolean tcp_relative_seq = TRUE;
180 /* SLAB allocator for tcp_unacked structures
182 SLAB_ITEM_TYPE_DEFINE(tcp_unacked_t)
183 static SLAB_FREE_LIST_DEFINE(tcp_unacked_t)
184 #define TCP_UNACKED_NEW(fi) \
185 SLAB_ALLOC(fi, tcp_unacked_t)
186 #define TCP_UNACKED_FREE(fi) \
187 SLAB_FREE(fi, tcp_unacked_t)
190 /* Idea for gt: either x > y, or y is much bigger (assume wrap) */
191 #define GT_SEQ(x, y) ((gint32)((y) - (x)) < 0)
192 #define LT_SEQ(x, y) ((gint32)((x) - (y)) < 0)
193 #define GE_SEQ(x, y) ((gint32)((y) - (x)) <= 0)
194 #define LE_SEQ(x, y) ((gint32)((x) - (y)) <= 0)
195 #define EQ_SEQ(x, y) ((x) == (y))
197 #define TCP_A_RETRANSMISSION 0x0001
198 #define TCP_A_LOST_PACKET 0x0002
199 #define TCP_A_ACK_LOST_PACKET 0x0004
200 #define TCP_A_KEEP_ALIVE 0x0008
201 #define TCP_A_DUPLICATE_ACK 0x0010
202 #define TCP_A_ZERO_WINDOW 0x0020
203 #define TCP_A_ZERO_WINDOW_PROBE 0x0040
204 #define TCP_A_ZERO_WINDOW_PROBE_ACK 0x0080
205 #define TCP_A_KEEP_ALIVE_ACK 0x0100
206 #define TCP_A_OUT_OF_ORDER 0x0200
207 #define TCP_A_FAST_RETRANSMISSION 0x0400
208 #define TCP_A_WINDOW_UPDATE 0x0800
209 #define TCP_A_WINDOW_FULL 0x1000
212 static GHashTable *tcp_pdu_tracking_table = NULL;
213 static GHashTable *tcp_pdu_skipping_table = NULL;
215 static se_tree_t *tcp_pdu_time_table = NULL;
218 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
219 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
220 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
221 struct tcp_analysis *tcpd);
224 struct tcp_analysis *
225 get_tcp_conversation_data(packet_info *pinfo)
228 conversation_t *conv=NULL;
229 struct tcp_analysis *tcpd=NULL;
231 /* Have we seen this conversation before? */
232 if( (conv=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
233 /* No this is a new conversation. */
234 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
237 /* check if we have any data for this conversation */
238 tcpd=conversation_get_proto_data(conv, proto_tcp);
240 /* No no such data yet. Allocate and init it */
241 tcpd=se_alloc(sizeof(struct tcp_analysis));
242 tcpd->flow1.segments=NULL;
243 tcpd->flow1.base_seq=0;
244 tcpd->flow1.lastack=0;
245 tcpd->flow1.lastacktime.secs=0;
246 tcpd->flow1.lastacktime.nsecs=0;
247 tcpd->flow1.lastnondupack=0;
248 tcpd->flow1.nextseq=0;
249 tcpd->flow1.nextseqtime.secs=0;
250 tcpd->flow1.nextseqtime.nsecs=0;
251 tcpd->flow1.nextseqframe=0;
252 tcpd->flow1.window=0;
253 tcpd->flow1.win_scale=-1;
254 tcpd->flow1.pdu_seq=NULL;
255 tcpd->flow2.segments=NULL;
256 tcpd->flow2.base_seq=0;
257 tcpd->flow2.lastack=0;
258 tcpd->flow2.lastacktime.secs=0;
259 tcpd->flow2.lastacktime.nsecs=0;
260 tcpd->flow2.lastnondupack=0;
261 tcpd->flow2.nextseq=0;
262 tcpd->flow2.nextseqtime.secs=0;
263 tcpd->flow2.nextseqtime.nsecs=0;
264 tcpd->flow2.nextseqframe=0;
265 tcpd->flow2.window=0;
266 tcpd->flow2.win_scale=-1;
267 tcpd->flow2.pdu_seq=NULL;
268 tcpd->acked_table=se_tree_create_non_persistent(SE_TREE_TYPE_RED_BLACK, "tcp_analyze_acked_table");
271 conversation_add_proto_data(conv, proto_tcp, tcpd);
275 /* check direction and get ua lists */
276 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
277 /* if the addresses are equal, match the ports instead */
279 direction= (pinfo->srcport > pinfo->destport)*2-1;
282 tcpd->fwd=&(tcpd->flow1);
283 tcpd->rev=&(tcpd->flow2);
285 tcpd->fwd=&(tcpd->flow2);
286 tcpd->rev=&(tcpd->flow1);
293 /* This function is called from the tcp analysis code to provide
294 clues on how the seq and ack numbers are changed.
295 To prevent the next_pdu lists from growing uncontrollable in size we
296 use this function to do the following :
297 IF we see an ACK then we assume that the left edge of the window has changed
298 at least to this point and assuming it is rare with reordering and
299 trailing duplicate/retransmitted segments, we just assume that after
300 we have seen the ACK we will not see any more segments prior to the
302 If we will not see any segments prior to the ACK value then we can just
303 delete all next_pdu entries that describe pdu's starting prior to the
305 If this heuristics is prooved to be too simplistic we can just enhance it
308 /* XXX this function should be ehnanced to handle sequence number wrapping */
309 /* XXX to handle retransmissions and reordered packets maybe we should only
310 discard entries that are more than (guesstimate) 50kb older than the
311 specified sequence number ?
314 prune_next_pdu_list(struct tcp_next_pdu **tnp, guint32 seq)
316 struct tcp_next_pdu *tmptnp;
322 for(tmptnp=*tnp;tmptnp;tmptnp=tmptnp->next){
323 if(tmptnp->nxtpdu<=seq){
324 struct tcp_next_pdu *oldtnp;
335 for(tmptnp=*tnp;tmptnp;tmptnp=tmptnp->next){
336 if(tmptnp->next==oldtnp){
337 tmptnp->next=oldtnp->next;
351 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_next_pdu *tnp)
355 if (check_col(pinfo->cinfo, COL_INFO)){
356 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", tnp->first_frame);
358 item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
359 tvb, 0, 0, tnp->first_frame);
360 PROTO_ITEM_SET_GENERATED(item);
363 /* if we know that a PDU starts inside this segment, return the adjusted
364 offset to where that PDU starts or just return offset back
365 and let TCP try to find out what it can about this segment
368 scan_for_next_pdu(tvbuff_t *tvb, proto_tree *tcp_tree, packet_info *pinfo, int offset, guint32 seq, guint32 nxtseq, struct tcp_analysis *tcpd)
370 struct tcp_next_pdu *tnp=NULL;
372 if(!pinfo->fd->flags.visited){
373 /* find(or create if needed) the conversation for this tcp session */
374 tnp=tcpd->fwd->pdu_seq;
376 /* scan and see if we find any pdus starting inside this tvb */
377 for(;tnp;tnp=tnp->next){
378 /* XXX here we should also try to handle sequence number
381 /* If this segment is completely within a previous PDU
382 * then we just skip this packet
384 if(seq>tnp->seq && nxtseq<=tnp->nxtpdu){
385 tnp->last_frame=pinfo->fd->num;
386 tnp->last_frame_time=pinfo->fd->abs_ts;
387 g_hash_table_insert(tcp_pdu_skipping_table,
388 GINT_TO_POINTER(pinfo->fd->num), (void *)tnp);
389 print_pdu_tracking_data(pinfo, tvb, tcp_tree, tnp);
393 if(seq<tnp->nxtpdu && nxtseq>tnp->nxtpdu){
394 g_hash_table_insert(tcp_pdu_tracking_table,
395 GINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(tnp->nxtpdu));
396 offset+=tnp->nxtpdu-seq;
403 tnp=(struct tcp_next_pdu *)se_tree_lookup32(tcp_pdu_time_table, pinfo->fd->num);
408 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, tnp->last_frame);
409 PROTO_ITEM_SET_GENERATED(item);
411 nstime_delta(&ns, &tnp->last_frame_time, &pinfo->fd->abs_ts);
412 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
414 PROTO_ITEM_SET_GENERATED(item);
417 /* check if this is a segment in the middle of a pdu */
418 tnp=(struct tcp_next_pdu *)g_hash_table_lookup(tcp_pdu_skipping_table, GINT_TO_POINTER(pinfo->fd->num));
420 print_pdu_tracking_data(pinfo, tvb, tcp_tree, tnp);
424 pduseq=GPOINTER_TO_UINT(g_hash_table_lookup(tcp_pdu_tracking_table, GINT_TO_POINTER(pinfo->fd->num)));
433 /* if we saw a PDU that extended beyond the end of the segment,
434 use this function to remember where the next pdu starts
437 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, struct tcp_analysis *tcpd)
439 struct tcp_next_pdu *tnp=NULL;
441 tnp=se_alloc(sizeof(struct tcp_next_pdu));
444 tnp->first_frame=pinfo->fd->num;
445 tnp->last_frame=pinfo->fd->num;
446 tnp->last_frame_time=pinfo->fd->abs_ts;
448 tnp->next=tcpd->fwd->pdu_seq;
449 tcpd->fwd->pdu_seq=tnp;
451 Add check for ACKs and purge list of sequence numbers
454 se_tree_insert32(tcp_pdu_time_table, pinfo->fd->num, (void *)tnp);
457 /* This is called for SYN+ACK packets and the purpose is to verify that we
458 * have seen window scaling in both directions.
459 * If we cant find window scaling being set in both directions
460 * that means it was present in the SYN but not in the SYN+ACK
461 * (or the SYN was missing) and then we disable the window scaling
462 * for this tcp session.
465 verify_tcp_window_scaling(struct tcp_analysis *tcpd)
467 if( tcpd && ((tcpd->flow1.win_scale==-1) || (tcpd->flow2.win_scale==-1)) ){
468 tcpd->flow1.win_scale=-1;
469 tcpd->flow2.win_scale=-1;
473 /* if we saw a window scaling option, store it for future reference
476 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
478 tcpd->fwd->win_scale=ws;
482 tcp_get_relative_seq_ack(guint32 *seq, guint32 *ack, guint32 *win, struct tcp_analysis *tcpd)
484 if(tcp_relative_seq){
485 (*seq) -= tcpd->fwd->base_seq;
486 (*ack) -= tcpd->rev->base_seq;
487 if(tcpd->fwd->win_scale!=-1){
488 (*win)<<=tcpd->fwd->win_scale;
494 /* when this function returns, it will (if createflag) populate the ta pointer.
497 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag, struct tcp_analysis *tcpd)
499 tcpd->ta=se_tree_lookup32(tcpd->acked_table, frame);
500 if((!tcpd->ta) && createflag){
501 tcpd->ta=se_alloc(sizeof(struct tcp_acked));
502 tcpd->ta->frame_acked=0;
504 tcpd->ta->ts.nsecs=0;
506 tcpd->ta->dupack_num=0;
507 tcpd->ta->dupack_frame=0;
508 se_tree_insert32(tcpd->acked_table, frame, (void *)tcpd->ta);
513 /* fwd contains a list of all segments processed but not yet ACKed in the
514 * same direction as the current segment.
515 * rev contains a list of all segments received but not yet ACKed in the
516 * opposite direction to the current segment.
518 * New segments are always added to the head of the fwd/rev lists.
522 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint32 window, struct tcp_analysis *tcpd)
524 tcp_unacked_t *ual=NULL;
528 printf("analyze_sequence numbers frame:%d direction:%s\n",pinfo->fd->num,direction>=0?"FWD":"REW");
529 printf("FWD list lastflags:0x%04x base_seq:0x%08x:\n",tcpd->fwd->lastsegmentflags,tcpd->fwd->base_seq);for(ual=tcpd->fwd->segments;ual;ual=ual->next)printf("Frame:%d Seq:%d Nextseq:%d\n",ual->frame,ual->seq,ual->nextseq);
530 printf("REV list lastflags:0x%04x base_seq:0x%08x:\n",tcpd->rev->lastsegmentflags,tcpd->rev->base_seq);for(ual=tcpd->rev->segments;ual;ual=ual->next)printf("Frame:%d Seq:%d Nextseq:%d\n",ual->frame,ual->seq,ual->nextseq);
535 /* if this is the first segment for this list we need to store the
538 if(tcpd->fwd->base_seq==0){
539 tcpd->fwd->base_seq=seq;
541 /* if we have spotted a new base_Seq in the reverse direction
544 if(tcpd->rev->base_seq==0){
545 tcpd->rev->base_seq=ack;
551 * it is a zero window probe if
552 * the sequnece number is the next expected one
553 * the window in the other direction is 0
554 * the segment is exactly 1 byte
558 && seq==tcpd->fwd->nextseq
559 && tcpd->rev->window==0 ){
561 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
563 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
569 * a zero window packet has window == 0 but none of the SYN/FIN/RST set
573 && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ){
575 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
577 tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
582 * If this segment is beyond the last seen nextseq we must
583 * have missed some previous segment
585 * We only check for this if we have actually seen segments prior to this
587 * RST packets are not checked for this.
589 if( tcpd->fwd->nextseq
590 && GT_SEQ(seq, tcpd->fwd->nextseq)
591 && (flags&(TH_RST))==0 ){
593 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
595 tcpd->ta->flags|=TCP_A_LOST_PACKET;
600 * a keepalive contains 0 or 1 bytes of data and starts one byte prior
601 * to what should be the next sequence number.
602 * SYN/FIN/RST segments are never keepalives
605 if( (seglen==0||seglen==1)
606 && seq==(tcpd->fwd->nextseq-1)
607 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
609 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
611 tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
615 * A window update is a 0 byte segment with the same SEQ/ACK numbers as
616 * the previous seen segment and with a new window value
620 && window!=tcpd->fwd->window
621 && seq==tcpd->fwd->nextseq
622 && ack==tcpd->fwd->lastack
623 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
625 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
627 tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
632 * If we know the window scaling
633 * and if this segment contains data ang goes all the way to the
634 * edge of the advertized window
635 * then we mark it as WINDOW FULL
636 * SYN/RST/FIN packets are never WINDOW FULL
640 && tcpd->fwd->win_scale!=-1
641 && tcpd->rev->win_scale!=-1
642 && (seq+seglen)==(tcpd->rev->lastack+(tcpd->rev->window<<tcpd->rev->win_scale))
643 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
645 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
647 tcpd->ta->flags|=TCP_A_WINDOW_FULL;
652 * It is a keepalive ack if it repeats the previous ACK and if
653 * the last segment in the reverse direction was a keepalive
658 && window==tcpd->fwd->window
659 && seq==tcpd->fwd->nextseq
660 && ack==tcpd->fwd->lastack
661 && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
662 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
664 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
666 tcpd->ta->flags|=TCP_A_KEEP_ALIVE_ACK;
671 /* ZERO WINDOW PROBE ACK
672 * It is a zerowindowprobe ack if it repeats the previous ACK and if
673 * the last segment in the reverse direction was a zerowindowprobe
674 * It also repeats the previous zero window indication
679 && window==tcpd->fwd->window
680 && seq==tcpd->fwd->nextseq
681 && ack==tcpd->fwd->lastack
682 && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
683 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
685 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
687 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
693 * It is a duplicate ack if window/seq/ack is the same as the previous
694 * segment and if the segment length is 0
698 && window==tcpd->fwd->window
699 && seq==tcpd->fwd->nextseq
700 && ack==tcpd->fwd->lastack
701 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
702 tcpd->fwd->dupacknum++;
704 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
706 tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
707 tcpd->ta->dupack_num=tcpd->fwd->dupacknum;
708 tcpd->ta->dupack_frame=tcpd->fwd->lastnondupack;
713 /* If this was NOT a dupack we must reset the dupack countres */
714 if( (!tcpd->ta) || !(tcpd->ta->flags&TCP_A_DUPLICATE_ACK) ){
715 tcpd->fwd->lastnondupack=pinfo->fd->num;
716 tcpd->fwd->dupacknum=0;
721 * If this segment acks beyond the nextseqnum in the other direction
722 * then that means we have missed packets going in the
725 * We only check this if we have actually seen some seq numbers
726 * in the other direction.
728 if( tcpd->rev->nextseq
729 && GT_SEQ(ack, tcpd->rev->nextseq )){
732 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
734 tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
735 /* update nextseq in the other direction so we dont get
736 * this indication again.
738 tcpd->rev->nextseq=ack;
742 /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
743 * If the segments contains data and if it does not advance
744 * sequence number it must be either of these three.
745 * Only test for this if we know what the seq number should be
746 * (tcpd->fwd->nextseq)
748 * Note that a simple KeepAlive is not a retransmission
751 && tcpd->fwd->nextseq
752 && (LT_SEQ(seq, tcpd->fwd->nextseq)) ){
755 if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ){
756 goto finished_checking_retransmission_type;
759 /* If there were >=1 duplicate ACKs in the reverse direction
760 * (there might be duplicate acks missing from the trace)
761 * and if this sequence number matches those ACKs
762 * and if the packet occurs within 20ms of the last
764 * then this is a fast retransmission
766 t=(pinfo->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
767 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;
768 if( tcpd->rev->dupacknum>=1
769 && tcpd->rev->lastack==seq
772 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
774 tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
775 goto finished_checking_retransmission_type;
778 /* If the segment came <3ms since the segment with the highest
779 * seen sequence number, then it is an OUT-OF-ORDER segment.
780 * (3ms is an arbitrary number)
782 t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
783 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
786 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
788 tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
789 goto finished_checking_retransmission_type;
792 /* Then it has to be a generic retransmission */
794 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
796 tcpd->ta->flags|=TCP_A_RETRANSMISSION;
797 nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
798 tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
800 finished_checking_retransmission_type:
803 /* add this new sequence number to the fwd list */
804 TCP_UNACKED_NEW(ual);
805 ual->next=tcpd->fwd->segments;
806 tcpd->fwd->segments=ual;
807 ual->frame=pinfo->fd->num;
809 ual->ts=pinfo->fd->abs_ts;
811 /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
812 ual->nextseq=seq+seglen;
813 if( flags&(TH_SYN|TH_FIN) ){
817 /* Store the highest number seen so far for nextseq so we can detect
818 * when we receive segments that arrive with a "hole"
819 * If we dont have anything since before, just store what we got.
820 * ZeroWindowProbes are special and dont really advance the nextseq
822 if(GT_SEQ(ual->nextseq, tcpd->fwd->nextseq) || !tcpd->fwd->nextseq) {
823 if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ){
824 tcpd->fwd->nextseq=ual->nextseq;
825 tcpd->fwd->nextseqframe=pinfo->fd->num;
826 tcpd->fwd->nextseqtime.secs=pinfo->fd->abs_ts.secs;
827 tcpd->fwd->nextseqtime.nsecs=pinfo->fd->abs_ts.nsecs;
832 /* remember what the ack/window is so we can track window updates and retransmissions */
833 tcpd->fwd->window=window;
834 tcpd->fwd->lastack=ack;
835 tcpd->fwd->lastacktime.secs=pinfo->fd->abs_ts.secs;
836 tcpd->fwd->lastacktime.nsecs=pinfo->fd->abs_ts.nsecs;
839 /* if there were any flags set for this segment we need to remember them
840 * we only remember the flags for the very last segment though.
843 tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
845 tcpd->fwd->lastsegmentflags=0;
849 prune_next_pdu_list(&(tcpd->rev->pdu_seq), ack-tcpd->rev->base_seq);
851 /* remove all segments this ACKs and we dont need to keep around any more
854 /* first we remove all such segments at the head of the list */
855 while((ual=tcpd->rev->segments)){
856 tcp_unacked_t *tmpual;
857 if(GT_SEQ(ual->nextseq,ack)){
861 /*qqq do the ACKs segment x delta y */
864 tmpual=tcpd->rev->segments->next;
865 TCP_UNACKED_FREE(ual);
866 tcpd->rev->segments=tmpual;
868 /* now we remove all such segments that are NOT at the head of the list */
869 ual=tcpd->rev->segments;
870 while(ual && ual->next){
871 tcp_unacked_t *tmpual;
872 if(GT_SEQ(ual->next->nextseq,ack)){
877 /*qqq do the ACKs segment x delta y */
880 tmpual=ual->next->next;
881 TCP_UNACKED_FREE(ual->next);
887 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
888 tcpd->ta->frame_acked=tcpd->rev->segments->frame;
889 nstime_delta(&tcpd->ta->ts, &pinfo->fd->abs_ts, &tcpd->rev->segments->ts);
894 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd)
896 struct tcp_acked *ta;
901 tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE, tcpd);
908 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
909 PROTO_ITEM_SET_GENERATED(item);
910 tree=proto_item_add_subtree(item, ett_tcp_analysis);
912 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
913 data we actually have */
915 item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
916 tvb, 0, 0, ta->frame_acked);
917 PROTO_ITEM_SET_GENERATED(item);
919 /* only display RTT if we actually have something we are acking */
920 if( ta->ts.secs || ta->ts.nsecs ){
921 item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
923 PROTO_ITEM_SET_GENERATED(item);
928 proto_item *flags_item=NULL;
929 proto_tree *flags_tree=NULL;
931 flags_item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, -1, FALSE);
932 PROTO_ITEM_SET_GENERATED(flags_item);
933 flags_tree=proto_item_add_subtree(flags_item, ett_tcp_analysis);
934 if( ta->flags&TCP_A_RETRANSMISSION ){
935 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
936 PROTO_ITEM_SET_GENERATED(flags_item);
937 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Retransmission (suspected)");
938 if(check_col(pinfo->cinfo, COL_INFO)){
939 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
941 if( ta->rto_ts.secs || ta->rto_ts.nsecs ){
942 item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
943 tvb, 0, 0, &ta->rto_ts);
944 PROTO_ITEM_SET_GENERATED(item);
945 item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame, tvb, 0, 0, ta->rto_frame);
946 PROTO_ITEM_SET_GENERATED(item);
949 if( ta->flags&TCP_A_FAST_RETRANSMISSION ){
950 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_fast_retransmission, tvb, 0, 0, "This frame is a (suspected) fast retransmission");
951 PROTO_ITEM_SET_GENERATED(flags_item);
952 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Fast retransmission (suspected)");
953 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
954 PROTO_ITEM_SET_GENERATED(flags_item);
955 if(check_col(pinfo->cinfo, COL_INFO)){
956 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Fast Retransmission] ");
959 if( ta->flags&TCP_A_OUT_OF_ORDER ){
960 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");
961 PROTO_ITEM_SET_GENERATED(flags_item);
962 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Out-Of-Order segment");
963 if(check_col(pinfo->cinfo, COL_INFO)){
964 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
967 if( ta->flags&TCP_A_LOST_PACKET ){
968 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_lost_packet, tvb, 0, 0, "A segment before this frame was lost");
969 PROTO_ITEM_SET_GENERATED(flags_item);
970 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Previous segment lost (common at capture start)");
971 if(check_col(pinfo->cinfo, COL_INFO)){
972 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] ");
975 if( ta->flags&TCP_A_ACK_LOST_PACKET ){
976 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?)");
977 PROTO_ITEM_SET_GENERATED(flags_item);
978 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "ACKed lost segment (common at capture start)");
979 if(check_col(pinfo->cinfo, COL_INFO)){
980 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] ");
983 if( ta->flags&TCP_A_WINDOW_UPDATE ){
984 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_update, tvb, 0, 0, "This is a tcp window update");
985 PROTO_ITEM_SET_GENERATED(flags_item);
986 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window update");
987 if(check_col(pinfo->cinfo, COL_INFO)){
988 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
991 if( ta->flags&TCP_A_WINDOW_FULL ){
992 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_full, tvb, 0, 0, "The transmission window is now completely full");
993 PROTO_ITEM_SET_GENERATED(flags_item);
994 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window is full");
995 if(check_col(pinfo->cinfo, COL_INFO)){
996 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
999 if( ta->flags&TCP_A_KEEP_ALIVE ){
1000 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive, tvb, 0, 0, "This is a TCP keep-alive segment");
1001 PROTO_ITEM_SET_GENERATED(flags_item);
1002 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive");
1003 if(check_col(pinfo->cinfo, COL_INFO)){
1004 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
1007 if( ta->flags&TCP_A_KEEP_ALIVE_ACK ){
1008 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");
1009 PROTO_ITEM_SET_GENERATED(flags_item);
1010 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive ACK");
1011 if(check_col(pinfo->cinfo, COL_INFO)){
1012 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
1015 if( ta->dupack_num){
1016 if( ta->flags&TCP_A_DUPLICATE_ACK ){
1017 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_duplicate_ack, tvb, 0, 0, "This is a TCP duplicate ack");
1018 PROTO_ITEM_SET_GENERATED(flags_item);
1019 if(check_col(pinfo->cinfo, COL_INFO)){
1020 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Dup ACK %u#%u] ", ta->dupack_frame, ta->dupack_num);
1023 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
1024 tvb, 0, 0, ta->dupack_num);
1025 PROTO_ITEM_SET_GENERATED(flags_item);
1026 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
1027 tvb, 0, 0, ta->dupack_frame);
1028 PROTO_ITEM_SET_GENERATED(flags_item);
1029 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Duplicate ACK (#%u) to ACK in packet #%u",
1030 ta->dupack_num, ta->dupack_frame);
1032 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE ){
1033 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");
1034 PROTO_ITEM_SET_GENERATED(flags_item);
1035 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe");
1036 if(check_col(pinfo->cinfo, COL_INFO)){
1037 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
1040 if( ta->flags&TCP_A_ZERO_WINDOW ){
1041 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window, tvb, 0, 0, "This is a ZeroWindow segment");
1042 PROTO_ITEM_SET_GENERATED(flags_item);
1043 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window");
1044 if(check_col(pinfo->cinfo, COL_INFO)){
1045 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
1048 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE_ACK ){
1049 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_probe_ack, tvb, 0, 0, "This is an ACK to a TCP zero-window-probe");
1050 PROTO_ITEM_SET_GENERATED(flags_item);
1051 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe ACK");
1052 if(check_col(pinfo->cinfo, COL_INFO)){
1053 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbeAck] ");
1061 /* Do we still need to do this ...remove_all() even though we dont need
1062 * to do anything special? The glib docs are not clear on this and
1063 * its better safe than sorry
1066 free_all_acked(gpointer key_arg _U_, gpointer value _U_, gpointer user_data _U_)
1072 tcp_acked_hash(gconstpointer k)
1074 guint32 frame = GPOINTER_TO_UINT(k);
1079 tcp_acked_equal(gconstpointer k1, gconstpointer k2)
1081 guint32 frame1 = GPOINTER_TO_UINT(k1);
1082 guint32 frame2 = GPOINTER_TO_UINT(k2);
1084 return frame1==frame2;
1088 tcp_analyze_seq_init(void)
1090 /* first destroy the tables */
1091 if( tcp_pdu_tracking_table ){
1092 g_hash_table_foreach_remove(tcp_pdu_tracking_table,
1093 free_all_acked, NULL);
1094 g_hash_table_destroy(tcp_pdu_tracking_table);
1095 tcp_pdu_tracking_table = NULL;
1097 if( tcp_pdu_skipping_table ){
1098 g_hash_table_foreach_remove(tcp_pdu_skipping_table,
1099 free_all_acked, NULL);
1100 g_hash_table_destroy(tcp_pdu_skipping_table);
1101 tcp_pdu_skipping_table = NULL;
1104 if(tcp_analyze_seq){
1105 tcp_pdu_tracking_table = g_hash_table_new(tcp_acked_hash,
1107 tcp_pdu_skipping_table = g_hash_table_new(tcp_acked_hash,
1113 /* **************************************************************************
1114 * End of tcp sequence number analysis
1115 * **************************************************************************/
1120 /* Minimum TCP header length. */
1121 #define TCPH_MIN_LEN 20
1127 #define TCPOPT_NOP 1 /* Padding */
1128 #define TCPOPT_EOL 0 /* End of options */
1129 #define TCPOPT_MSS 2 /* Segment size negotiating */
1130 #define TCPOPT_WINDOW 3 /* Window scaling */
1131 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
1132 #define TCPOPT_SACK 5 /* SACK Block */
1133 #define TCPOPT_ECHO 6
1134 #define TCPOPT_ECHOREPLY 7
1135 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
1136 #define TCPOPT_CC 11
1137 #define TCPOPT_CCNEW 12
1138 #define TCPOPT_CCECHO 13
1139 #define TCPOPT_MD5 19 /* RFC2385 */
1142 * TCP option lengths
1145 #define TCPOLEN_MSS 4
1146 #define TCPOLEN_WINDOW 3
1147 #define TCPOLEN_SACK_PERM 2
1148 #define TCPOLEN_SACK_MIN 2
1149 #define TCPOLEN_ECHO 6
1150 #define TCPOLEN_ECHOREPLY 6
1151 #define TCPOLEN_TIMESTAMP 10
1152 #define TCPOLEN_CC 6
1153 #define TCPOLEN_CCNEW 6
1154 #define TCPOLEN_CCECHO 6
1155 #define TCPOLEN_MD5 18
1159 /* Desegmentation of TCP streams */
1160 /* table to hold defragmented TCP streams */
1161 static GHashTable *tcp_fragment_table = NULL;
1163 tcp_fragment_init(void)
1165 fragment_table_init(&tcp_fragment_table);
1168 /* functions to trace tcp segments */
1169 /* Enable desegmenting of TCP streams */
1170 static gboolean tcp_desegment = TRUE;
1172 static GHashTable *tcp_segment_table = NULL;
1173 static GMemChunk *tcp_segment_key_chunk = NULL;
1174 static int tcp_segment_init_count = 200;
1175 static GMemChunk *tcp_segment_address_chunk = NULL;
1176 static int tcp_segment_address_init_count = 500;
1178 typedef struct _tcp_segment_key {
1179 /* for own bookkeeping inside packet-tcp.c */
1188 guint32 first_frame;
1192 free_all_segments(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
1194 tcp_segment_key *key = key_arg;
1196 if((key->src)&&(key->src->data)){
1197 g_free((gpointer)key->src->data);
1198 key->src->data=NULL;
1201 if((key->dst)&&(key->dst->data)){
1202 g_free((gpointer)key->dst->data);
1203 key->dst->data=NULL;
1210 tcp_segment_hash(gconstpointer k)
1212 const tcp_segment_key *key = (const tcp_segment_key *)k;
1214 return key->seq+key->sport;
1218 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
1220 const tcp_segment_key *key1 = (const tcp_segment_key *)k1;
1221 const tcp_segment_key *key2 = (const tcp_segment_key *)k2;
1223 return ( ( (key1->seq==key2->seq)
1224 &&(ADDRESSES_EQUAL(key1->src, key2->src))
1225 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
1226 &&(key1->sport==key2->sport)
1227 &&(key1->dport==key2->dport)
1232 tcp_desegment_init(void)
1235 * Free this before freeing any memory chunks; those
1236 * chunks contain data we'll look at in "free_all_segments()".
1238 if(tcp_segment_table){
1239 g_hash_table_foreach_remove(tcp_segment_table,
1240 free_all_segments, NULL);
1241 g_hash_table_destroy(tcp_segment_table);
1242 tcp_segment_table = NULL;
1245 if(tcp_segment_key_chunk){
1246 g_mem_chunk_destroy(tcp_segment_key_chunk);
1247 tcp_segment_key_chunk = NULL;
1249 if(tcp_segment_address_chunk){
1250 g_mem_chunk_destroy(tcp_segment_address_chunk);
1251 tcp_segment_address_chunk = NULL;
1254 /* dont allocate any hash table or memory chunks unless the user
1255 really uses this option
1261 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
1264 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
1265 sizeof(tcp_segment_key),
1266 tcp_segment_init_count*sizeof(tcp_segment_key),
1269 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
1271 tcp_segment_address_init_count*sizeof(address),
1276 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1277 guint32 seq, guint32 nxtseq,
1278 guint32 sport, guint32 dport,
1279 proto_tree *tree, proto_tree *tcp_tree,
1280 struct tcp_analysis *tcpd)
1282 struct tcpinfo *tcpinfo = pinfo->private_data;
1283 fragment_data *ipfd_head=NULL;
1284 tcp_segment_key old_tsk, *tsk;
1285 gboolean must_desegment = FALSE;
1286 gboolean called_dissector = FALSE;
1291 proto_item *frag_tree_item;
1292 proto_item *tcp_tree_item;
1296 * Initialize these to assume no desegmentation.
1297 * If that's not the case, these will be set appropriately
1298 * by the subdissector.
1300 pinfo->desegment_offset = 0;
1301 pinfo->desegment_len = 0;
1304 * Initialize this to assume that this segment will just be
1305 * added to the middle of a desegmented chunk of data, so
1306 * that we should show it all as data.
1307 * If that's not the case, it will be set appropriately.
1309 deseg_offset = offset;
1311 /* First we must check if this TCP segment should be desegmented.
1312 This is only to check if we should desegment this packet,
1313 so we dont spend time doing COPY_ADDRESS/g_free.
1314 We just "borrow" some address structures from pinfo instead. Cheaper.
1316 old_tsk.src = &pinfo->src;
1317 old_tsk.dst = &pinfo->dst;
1318 old_tsk.sport = sport;
1319 old_tsk.dport = dport;
1321 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1324 /* OK, this segment was found, which means it continues
1325 a higher-level PDU. This means we must desegment it.
1326 Add it to the defragmentation lists.
1328 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->first_frame,
1330 seq - tsk->start_seq,
1332 (LT_SEQ (nxtseq,tsk->start_seq + tsk->tot_len)) );
1335 /* fragment_add() returned NULL, This means that
1336 desegmentation is not completed yet.
1337 (its like defragmentation but we know we will
1338 always add the segments in order).
1339 XXX - no, we don't; there is no guarantee that
1340 TCP segments are in order on the wire.
1342 we must add next segment to our table so we will
1345 tcp_segment_key *new_tsk;
1347 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1348 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1349 new_tsk->seq=nxtseq;
1350 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1353 /* This segment was not found in our table, so it doesn't
1354 contain a continuation of a higher-level PDU.
1355 Call the normal subdissector.
1357 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1358 sport, dport, 0, 0, FALSE, tcpd);
1359 called_dissector = TRUE;
1361 /* Did the subdissector ask us to desegment some more data
1362 before it could handle the packet?
1363 If so we have to create some structures in our table but
1364 this is something we only do the first time we see this
1367 if(pinfo->desegment_len) {
1368 if (!pinfo->fd->flags.visited)
1369 must_desegment = TRUE;
1372 * Set "deseg_offset" to the offset in "tvb"
1373 * of the first byte of data that the
1374 * subdissector didn't process.
1376 deseg_offset = offset + pinfo->desegment_offset;
1379 /* Either no desegmentation is necessary, or this is
1380 segment contains the beginning but not the end of
1381 a higher-level PDU and thus isn't completely
1387 /* is it completely desegmented? */
1389 fragment_data *ipfd;
1392 * Yes, we think it is.
1393 * We only call subdissector for the last segment.
1394 * Note that the last segment may include more than what
1397 if(GE_SEQ(nxtseq, tsk->start_seq + tsk->tot_len)){
1399 * OK, this is the last segment.
1400 * Let's call the subdissector with the desegmented
1406 /* create a new TVB structure for desegmented data */
1407 next_tvb = tvb_new_real_data(ipfd_head->data,
1408 ipfd_head->datalen, ipfd_head->datalen);
1410 /* add this tvb as a child to the original one */
1411 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1413 /* add desegmented data to the data source list */
1414 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1417 * Supply the sequence number of the first of the
1418 * reassembled bytes.
1420 tcpinfo->seq = tsk->start_seq;
1422 /* indicate that this is reassembled data */
1423 tcpinfo->is_reassembled = TRUE;
1425 /* call subdissector */
1426 process_tcp_payload(next_tvb, 0, pinfo, tree,
1427 tcp_tree, sport, dport, 0, 0, FALSE, tcpd);
1428 called_dissector = TRUE;
1431 * OK, did the subdissector think it was completely
1432 * desegmented, or does it think we need even more
1435 old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
1436 if(pinfo->desegment_len &&
1437 pinfo->desegment_offset<=old_len){
1438 tcp_segment_key *new_tsk;
1441 * "desegment_len" isn't 0, so it needs more
1442 * data for something - and "desegment_offset"
1443 * is before "old_len", so it needs more data
1444 * to dissect the stuff we thought was
1445 * completely desegmented (as opposed to the
1446 * stuff at the beginning being completely
1447 * desegmented, but the stuff at the end
1448 * being a new higher-level PDU that also
1449 * needs desegmentation).
1451 fragment_set_partial_reassembly(pinfo,tsk->first_frame,tcp_fragment_table);
1452 tsk->tot_len = tvb_reported_length(next_tvb) + pinfo->desegment_len;
1455 * Update tsk structure.
1456 * Can ask ->next->next because at least there's a hdr and one
1457 * entry in fragment_add()
1459 for(ipfd=ipfd_head->next; ipfd->next; ipfd=ipfd->next){
1460 old_tsk.seq = tsk->start_seq + ipfd->offset;
1461 new_tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1463 new_tsk->tot_len = tsk->tot_len;
1466 /* this is the next segment in the sequence we want */
1467 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1468 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1469 new_tsk->seq = nxtseq;
1470 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1473 * Show the stuff in this TCP segment as
1474 * just raw TCP segment data.
1477 tvb_reported_length_remaining(tvb, offset);
1478 proto_tree_add_text(tcp_tree, tvb, offset, -1,
1479 "TCP segment data (%u byte%s)", nbytes,
1480 plurality(nbytes, "", "s"));
1483 * The subdissector thought it was completely
1484 * desegmented (although the stuff at the
1485 * end may, in turn, require desegmentation),
1486 * so we show a tree with all segments.
1488 show_fragment_tree(ipfd_head, &tcp_segment_items,
1489 tree, pinfo, next_tvb, &frag_tree_item);
1491 * The toplevel fragment subtree is now
1492 * behind all desegmented data; move it
1493 * right behind the TCP tree.
1495 tcp_tree_item = proto_tree_get_parent(tcp_tree);
1496 if(frag_tree_item && tcp_tree_item) {
1497 proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1500 /* Did the subdissector ask us to desegment
1501 some more data? This means that the data
1502 at the beginning of this segment completed
1503 a higher-level PDU, but the data at the
1504 end of this segment started a higher-level
1505 PDU but didn't complete it.
1507 If so, we have to create some structures
1508 in our table, but this is something we
1509 only do the first time we see this packet.
1511 if(pinfo->desegment_len) {
1512 if (!pinfo->fd->flags.visited)
1513 must_desegment = TRUE;
1515 /* The stuff we couldn't dissect
1516 must have come from this segment,
1517 so it's all in "tvb".
1519 "pinfo->desegment_offset" is
1520 relative to the beginning of
1521 "next_tvb"; we want an offset
1522 relative to the beginning of "tvb".
1524 First, compute the offset relative
1525 to the *end* of "next_tvb" - i.e.,
1526 the number of bytes before the end
1527 of "next_tvb" at which the
1528 subdissector stopped. That's the
1529 length of "next_tvb" minus the
1530 offset, relative to the beginning
1531 of "next_tvb, at which the
1532 subdissector stopped.
1535 ipfd_head->datalen - pinfo->desegment_offset;
1537 /* "tvb" and "next_tvb" end at the
1538 same byte of data, so the offset
1539 relative to the end of "next_tvb"
1540 of the byte at which we stopped
1541 is also the offset relative to
1542 the end of "tvb" of the byte at
1545 Convert that back into an offset
1546 relative to the beginninng of
1547 "tvb", by taking the length of
1548 "tvb" and subtracting the offset
1549 relative to the end.
1551 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1557 if (must_desegment) {
1558 tcp_segment_key *tsk, *new_tsk;
1561 * The sequence number at which the stuff to be desegmented
1562 * starts is the sequence number of the byte at an offset
1563 * of "deseg_offset" into "tvb".
1565 * The sequence number of the byte at an offset of "offset"
1566 * is "seq", i.e. the starting sequence number of this
1567 * segment, so the sequence number of the byte at
1568 * "deseg_offset" is "seq + (deseg_offset - offset)".
1570 deseg_seq = seq + (deseg_offset - offset);
1573 * XXX - how do we detect out-of-order transmissions?
1574 * We can't just check for "nxtseq" being greater than
1575 * "tsk->start_seq"; for now, we check for the difference
1576 * being less than a megabyte, but this is a really
1577 * gross hack - we really need to handle out-of-order
1578 * transmissions correctly.
1580 if ((nxtseq - deseg_seq) <= 1024*1024) {
1581 /* OK, subdissector wants us to desegment
1582 some data before it can process it. Add
1583 what remains of this packet and set
1584 up next packet/sequence number as well.
1586 We must remember this segment
1588 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1589 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
1590 COPY_ADDRESS(tsk->src, &pinfo->src);
1591 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
1592 COPY_ADDRESS(tsk->dst, &pinfo->dst);
1593 tsk->seq = deseg_seq;
1594 tsk->start_seq = tsk->seq;
1595 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
1596 tsk->first_frame = pinfo->fd->num;
1599 g_hash_table_insert(tcp_segment_table, tsk, tsk);
1601 /* Add portion of segment unprocessed by the subdissector
1602 to defragmentation lists */
1603 fragment_add(tvb, deseg_offset, pinfo, tsk->first_frame,
1605 tsk->seq - tsk->start_seq,
1606 nxtseq - tsk->start_seq,
1607 LT_SEQ (nxtseq, tsk->start_seq + tsk->tot_len));
1609 /* this is the next segment in the sequence we want */
1610 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1611 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1612 new_tsk->seq = nxtseq;
1613 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1617 if (!called_dissector || pinfo->desegment_len != 0) {
1618 if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
1619 !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
1621 * We know what frame this PDU is reassembled in;
1622 * let the user know.
1624 item=proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in,
1625 tvb, 0, 0, ipfd_head->reassembled_in);
1626 PROTO_ITEM_SET_GENERATED(item);
1630 * Either we didn't call the subdissector at all (i.e.,
1631 * this is a segment that contains the middle of a
1632 * higher-level PDU, but contains neither the beginning
1633 * nor the end), or the subdissector couldn't dissect it
1634 * all, as some data was missing (i.e., it set
1635 * "pinfo->desegment_len" to the amount of additional
1638 if (pinfo->desegment_offset == 0) {
1640 * It couldn't, in fact, dissect any of it (the
1641 * first byte it couldn't dissect is at an offset
1642 * of "pinfo->desegment_offset" from the beginning
1643 * of the payload, and that's 0).
1644 * Just mark this as TCP.
1646 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1647 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1649 if (check_col(pinfo->cinfo, COL_INFO)){
1650 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
1655 * Show what's left in the packet as just raw TCP segment
1657 * XXX - remember what protocol the last subdissector
1658 * was, and report it as a continuation of that, instead?
1660 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
1661 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
1662 "TCP segment data (%u byte%s)", nbytes,
1663 plurality(nbytes, "", "s"));
1665 pinfo->can_desegment=0;
1666 pinfo->desegment_offset = 0;
1667 pinfo->desegment_len = 0;
1671 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
1672 * consists of a fixed-length chunk of data that contains enough information
1673 * to determine the length of the PDU, followed by rest of the PDU.
1675 * The first three arguments are the arguments passed to the dissector
1676 * that calls this routine.
1678 * "proto_desegment" is the dissector's flag controlling whether it should
1679 * desegment PDUs that cross TCP segment boundaries.
1681 * "fixed_len" is the length of the fixed-length part of the PDU.
1683 * "get_pdu_len()" is a routine called to get the length of the PDU from
1684 * the fixed-length part of the PDU; it's passed "tvb" and "offset".
1686 * "dissect_pdu()" is the routine to dissect a PDU.
1689 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1690 gboolean proto_desegment, guint fixed_len,
1691 guint (*get_pdu_len)(tvbuff_t *, int),
1692 dissector_t dissect_pdu)
1694 volatile int offset = 0;
1696 guint length_remaining;
1701 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1703 * We use "tvb_ensure_length_remaining()" to make sure there actually
1704 * *is* data remaining. The protocol we're handling could conceivably
1705 * consists of a sequence of fixed-length PDUs, and therefore the
1706 * "get_pdu_len" routine might not actually fetch anything from
1707 * the tvbuff, and thus might not cause an exception to be thrown if
1708 * we've run past the end of the tvbuff.
1710 * This means we're guaranteed that "length_remaining" is positive.
1712 length_remaining = tvb_ensure_length_remaining(tvb, offset);
1715 * Can we do reassembly?
1717 if (proto_desegment && pinfo->can_desegment) {
1719 * Yes - is the fixed-length part of the PDU split across segment
1722 if (length_remaining < fixed_len) {
1724 * Yes. Tell the TCP dissector where the data for this message
1725 * starts in the data it handed us, and how many more bytes we
1728 pinfo->desegment_offset = offset;
1729 pinfo->desegment_len = fixed_len - length_remaining;
1735 * Get the length of the PDU.
1737 plen = (*get_pdu_len)(tvb, offset);
1738 if (plen < fixed_len) {
1740 * The PDU length from the fixed-length portion probably didn't
1741 * include the fixed-length portion's length, and was probably so
1742 * large that the total length overflowed.
1744 * Report this as an error.
1746 show_reported_bounds_error(tvb, pinfo, tree);
1750 /* give a hint to TCP where the next PDU starts
1751 * so that it can attempt to find it in case it starts
1752 * somewhere in the middle of a segment.
1754 if(!pinfo->fd->flags.visited && tcp_analyze_seq){
1755 guint remaining_bytes;
1756 remaining_bytes=tvb_reported_length_remaining(tvb, offset);
1757 if(plen>remaining_bytes){
1758 pinfo->want_pdu_tracking=2;
1759 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
1764 * Can we do reassembly?
1766 if (proto_desegment && pinfo->can_desegment) {
1768 * Yes - is the PDU split across segment boundaries?
1770 if (length_remaining < plen) {
1772 * Yes. Tell the TCP dissector where the data for this message
1773 * starts in the data it handed us, and how many more bytes we
1776 pinfo->desegment_offset = offset;
1777 pinfo->desegment_len = plen - length_remaining;
1783 * Construct a tvbuff containing the amount of the payload we have
1784 * available. Make its reported length the amount of data in the PDU.
1786 * XXX - if reassembly isn't enabled. the subdissector will throw a
1787 * BoundsError exception, rather than a ReportedBoundsError exception.
1788 * We really want a tvbuff where the length is "length", the reported
1789 * length is "plen", and the "if the snapshot length were infinite"
1790 * length is the minimum of the reported length of the tvbuff handed
1791 * to us and "plen", with a new type of exception thrown if the offset
1792 * is within the reported length but beyond that third length, with
1793 * that exception getting the "Unreassembled Packet" error.
1795 length = length_remaining;
1798 next_tvb = tvb_new_subset(tvb, offset, length, plen);
1803 * Catch the ReportedBoundsError exception; if this particular message
1804 * happens to get a ReportedBoundsError exception, that doesn't mean
1805 * that we should stop dissecting PDUs within this frame or chunk of
1808 * If it gets a BoundsError, we can stop, as there's nothing more to
1809 * see, so we just re-throw it.
1812 (*dissect_pdu)(next_tvb, pinfo, tree);
1814 CATCH(BoundsError) {
1817 CATCH(ReportedBoundsError) {
1818 show_reported_bounds_error(tvb, pinfo, tree);
1823 * Step to the next PDU.
1824 * Make sure we don't overflow.
1826 offset_before = offset;
1828 if (offset <= offset_before)
1834 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
1836 if (check_col(pinfo->cinfo, COL_INFO))
1837 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
1841 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
1842 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1846 mss = tvb_get_ntohs(tvb, offset + 2);
1847 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_mss, tvb, offset,
1849 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
1850 optlen, mss, "%s: %u bytes", optp->name, mss);
1851 tcp_info_append_uint(pinfo, "MSS", mss);
1855 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
1856 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1859 struct tcp_analysis *tcpd=NULL;
1861 tcpd=get_tcp_conversation_data(pinfo);
1863 ws = tvb_get_guint8(tvb, offset + 2);
1864 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_wscale, tvb,
1865 offset, optlen, TRUE);
1866 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
1867 offset, optlen, ws, "%s: %u (multiply by %u)",
1868 optp->name, ws, 1 << ws);
1869 tcp_info_append_uint(pinfo, "WS", ws);
1870 if(!pinfo->fd->flags.visited && tcp_analyze_seq && tcp_relative_seq){
1871 pdu_store_window_scale_option(ws, tcpd);
1876 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
1877 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1879 proto_tree *field_tree = NULL;
1880 proto_item *tf=NULL;
1881 guint32 leftedge, rightedge;
1882 struct tcp_analysis *tcpd=NULL;
1885 if(tcp_analyze_seq && tcp_relative_seq){
1886 /* find(or create if needed) the conversation for this tcp session */
1887 tcpd=get_tcp_conversation_data(pinfo);
1889 base_ack=tcpd->rev->base_seq;
1892 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
1893 offset += 2; /* skip past type and length */
1894 optlen -= 2; /* subtract size of type and length */
1895 while (optlen > 0) {
1896 if (field_tree == NULL) {
1897 /* Haven't yet made a subtree out of this option. Do so. */
1898 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1899 proto_tree_add_boolean_hidden(field_tree, hf_tcp_option_sack, tvb,
1900 offset, optlen, TRUE);
1903 proto_tree_add_text(field_tree, tvb, offset, optlen,
1904 "(suboption would go past end of option)");
1907 leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
1908 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
1909 offset, 4, leftedge,
1910 "left edge = %u%s", leftedge,
1911 tcp_relative_seq ? " (relative)" : "");
1915 proto_tree_add_text(field_tree, tvb, offset, optlen,
1916 "(suboption would go past end of option)");
1919 /* XXX - check whether it goes past end of packet */
1920 rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
1922 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
1923 offset+4, 4, rightedge,
1924 "right edge = %u%s", rightedge,
1925 tcp_relative_seq ? " (relative)" : "");
1926 tcp_info_append_uint(pinfo, "SLE", leftedge);
1927 tcp_info_append_uint(pinfo, "SRE", rightedge);
1928 proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
1934 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
1935 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1939 echo = tvb_get_ntohl(tvb, offset + 2);
1940 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_echo, tvb, offset,
1942 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1943 "%s: %u", optp->name, echo);
1944 tcp_info_append_uint(pinfo, "ECHO", echo);
1948 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
1949 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1953 tsv = tvb_get_ntohl(tvb, offset + 2);
1954 tser = tvb_get_ntohl(tvb, offset + 6);
1955 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_time_stamp, tvb,
1956 offset, optlen, TRUE);
1957 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1958 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
1959 tcp_info_append_uint(pinfo, "TSV", tsv);
1960 tcp_info_append_uint(pinfo, "TSER", tser);
1964 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
1965 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1969 cc = tvb_get_ntohl(tvb, offset + 2);
1970 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_cc, tvb, offset,
1972 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1973 "%s: %u", optp->name, cc);
1974 tcp_info_append_uint(pinfo, "CC", cc);
1977 static const ip_tcp_opt tcpopts[] = {
1996 "Maximum segment size",
2000 dissect_tcpopt_maxseg
2008 dissect_tcpopt_wscale
2021 &ett_tcp_option_sack,
2048 dissect_tcpopt_timestamp
2076 "TCP MD5 signature",
2084 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
2086 /* Determine if there is a sub-dissector and call it; return TRUE
2087 if there was a sub-dissector, FALSE otherwise.
2089 This has been separated into a stand alone routine to other protocol
2090 dissectors can call to it, e.g., SOCKS. */
2092 static gboolean try_heuristic_first = FALSE;
2095 /* this function can be called with tcpd==NULL as from the msproxy dissector */
2097 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
2098 proto_tree *tree, int src_port, int dst_port,
2099 struct tcp_analysis *tcpd)
2102 int low_port, high_port;
2104 /* dont call subdissectors for keepalive or zerowindowprobes
2105 * eventhough tehy do contain payload "data"
2106 * keeaplives just contain garbage and zwp contain too little data (1 byte)
2109 if(tcpd && tcpd->ta){
2110 if(tcpd->ta->flags&(TCP_A_ZERO_WINDOW_PROBE|TCP_A_KEEP_ALIVE)){
2115 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2117 /* determine if this packet is part of a conversation and call dissector */
2118 /* for the conversation if available */
2120 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
2121 src_port, dst_port, next_tvb, pinfo, tree)){
2122 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2126 if (try_heuristic_first) {
2127 /* do lookup with the heuristic subdissector table */
2128 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2129 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2134 /* Do lookups with the subdissector table.
2135 We try the port number with the lower value first, followed by the
2136 port number with the higher value. This means that, for packets
2137 where a dissector is registered for *both* port numbers:
2139 1) we pick the same dissector for traffic going in both directions;
2141 2) we prefer the port number that's more likely to be the right
2142 one (as that prefers well-known ports to reserved ports);
2144 although there is, of course, no guarantee that any such strategy
2145 will always pick the right port number.
2147 XXX - we ignore port numbers of 0, as some dissectors use a port
2148 number of 0 to disable the port. */
2149 if (src_port > dst_port) {
2150 low_port = dst_port;
2151 high_port = src_port;
2153 low_port = src_port;
2154 high_port = dst_port;
2156 if (low_port != 0 &&
2157 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree)){
2158 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2161 if (high_port != 0 &&
2162 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree)){
2163 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2167 if (!try_heuristic_first) {
2168 /* do lookup with the heuristic subdissector table */
2169 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2170 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2175 /* Oh, well, we don't know this; dissect it as data. */
2176 call_dissector(data_handle,next_tvb, pinfo, tree);
2178 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2183 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
2184 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
2185 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
2186 struct tcp_analysis *tcpd)
2188 pinfo->want_pdu_tracking=0;
2192 /*qqq see if it is an unaligned PDU */
2193 if(tcp_analyze_seq && (!tcp_desegment)){
2195 offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
2200 /* if offset is -1 this means that this segment is known
2201 * to be fully inside a previously detected pdu
2202 * so we dont even need to try to dissect it either.
2205 decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
2208 * We succeeded in handing off to a subdissector.
2210 * Is this a TCP segment or a reassembled chunk of
2214 /* if !visited, check want_pdu_tracking and
2215 store it in table */
2216 if((!pinfo->fd->flags.visited) &&
2217 tcp_analyze_seq && pinfo->want_pdu_tracking){
2219 pdu_store_sequencenumber_of_next_pdu(
2222 nxtseq+pinfo->bytes_until_next_pdu,
2230 /* We got an exception. At this point the dissection is
2231 * completely aborted and execution will be transfered back
2232 * to (probably) the frame dissector.
2233 * Here we have to place whatever we want the dissector
2234 * to do before aborting the tcp dissection.
2237 * Is this a TCP segment or a reassembled chunk of TCP
2242 * It's from a TCP segment.
2244 * if !visited, check want_pdu_tracking and store it
2247 if((!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking){
2249 pdu_store_sequencenumber_of_next_pdu(pinfo,
2251 nxtseq+pinfo->bytes_until_next_pdu,
2262 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
2263 guint32 nxtseq, guint32 sport, guint32 dport,
2264 proto_tree *tree, proto_tree *tcp_tree,
2265 struct tcp_analysis *tcpd)
2267 gboolean save_fragmented;
2269 /* Can we desegment this segment? */
2270 if (pinfo->can_desegment) {
2272 desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
2275 /* No - just call the subdissector.
2276 Mark this as fragmented, so if somebody throws an exception,
2277 we don't report it as a malformed frame. */
2278 save_fragmented = pinfo->fragmented;
2279 pinfo->fragmented = TRUE;
2280 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
2281 seq, nxtseq, TRUE, tcpd);
2282 pinfo->fragmented = save_fragmented;
2287 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2289 guint8 th_off_x2; /* combines th_off and th_x2 */
2292 proto_tree *tcp_tree = NULL, *field_tree = NULL;
2293 proto_item *ti = NULL, *tf;
2295 gchar *flags = "<None>";
2296 const gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
2297 size_t fpos = 0, returned_length;
2305 guint16 computed_cksum;
2306 guint16 real_window;
2307 guint length_remaining;
2308 gboolean desegment_ok;
2309 struct tcpinfo tcpinfo;
2310 static struct tcpheader tcphstruct[4], *tcph;
2311 static int tcph_count=0;
2312 proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
2313 struct tcp_analysis *tcpd=NULL;
2319 tcph=&tcphstruct[tcph_count];
2320 SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
2321 SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
2323 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2324 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2326 /* Clear out the Info column. */
2327 if (check_col(pinfo->cinfo, COL_INFO))
2328 col_clear(pinfo->cinfo, COL_INFO);
2330 tcph->th_sport = tvb_get_ntohs(tvb, offset);
2331 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
2332 if (check_col(pinfo->cinfo, COL_INFO)) {
2333 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
2334 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2337 if (tcp_summary_in_tree) {
2338 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
2339 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
2340 get_tcp_port(tcph->th_sport), tcph->th_sport,
2341 get_tcp_port(tcph->th_dport), tcph->th_dport);
2344 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
2346 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
2347 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
2348 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
2349 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
2350 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
2351 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
2352 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
2355 /* Set the source and destination port numbers as soon as we get them,
2356 so that they're available to the "Follow TCP Stream" code even if
2357 we throw an exception dissecting the rest of the TCP header. */
2358 pinfo->ptype = PT_TCP;
2359 pinfo->srcport = tcph->th_sport;
2360 pinfo->destport = tcph->th_dport;
2362 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
2363 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
2364 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
2365 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
2366 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
2367 real_window = tcph->th_win;
2368 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
2370 /* find(or create if needed) the conversation for this tcp session */
2371 tcpd=get_tcp_conversation_data(pinfo);
2374 * If we've been handed an IP fragment, we don't know how big the TCP
2375 * segment is, so don't do anything that requires that we know that.
2377 * The same applies if we're part of an error packet. (XXX - if the
2378 * ICMP and ICMPv6 dissectors could set a "this is how big the IP
2379 * header says it is" length in the tvbuff, we could use that; such
2380 * a length might also be useful for handling packets where the IP
2381 * length is bigger than the actual data available in the frame; the
2382 * dissectors should trust that length, and then throw a
2383 * ReportedBoundsError exception when they go past the end of the frame.)
2385 * We also can't determine the segment length if the reported length
2386 * of the TCP packet is less than the TCP header length.
2388 reported_len = tvb_reported_length(tvb);
2390 if (!pinfo->fragmented && !pinfo->in_error_pkt) {
2391 if (reported_len < tcph->th_hlen) {
2392 proto_tree_add_text(tcp_tree, tvb, offset, 0,
2393 "Short segment. Segment/fragment does not contain a full TCP header"
2394 " (might be NMAP or someone else deliberately sending unusual packets)");
2395 tcph->th_have_seglen = FALSE;
2397 /* Compute the length of data in this segment. */
2398 tcph->th_seglen = reported_len - tcph->th_hlen;
2399 tcph->th_have_seglen = TRUE;
2401 if (tree) { /* Add the seglen as an invisible field */
2403 proto_tree_add_uint_hidden(ti, hf_tcp_len, tvb, offset, 4, tcph->th_seglen);
2408 /* handle TCP seq# analysis parse all new segments we see */
2409 if(tcp_analyze_seq){
2410 if(!(pinfo->fd->flags.visited)){
2411 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
2413 if(tcp_relative_seq){
2414 tcp_get_relative_seq_ack(&(tcph->th_seq), &(tcph->th_ack), &(tcph->th_win), tcpd);
2418 /* Compute the sequence number of next octet after this segment. */
2419 nxtseq = tcph->th_seq + tcph->th_seglen;
2422 tcph->th_have_seglen = FALSE;
2424 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
2425 #define MAX_FLAGS_LEN 64
2426 flags=ep_alloc(MAX_FLAGS_LEN);
2428 for (i = 0; i < 8; i++) {
2430 if (tcph->th_flags & bpos) {
2431 returned_length = g_snprintf(&flags[fpos], MAX_FLAGS_LEN-fpos, "%s%s",
2434 fpos += MIN(returned_length, MAX_FLAGS_LEN-fpos);
2439 if (check_col(pinfo->cinfo, COL_INFO)) {
2440 if(tcph->th_flags&TH_ACK){
2441 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
2442 flags, tcph->th_seq, tcph->th_ack, tcph->th_win);
2444 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u",
2445 flags, tcph->th_seq);
2450 if (tcp_summary_in_tree) {
2451 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
2453 if(tcp_relative_seq){
2454 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);
2456 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
2460 if (tcph->th_hlen < TCPH_MIN_LEN) {
2461 /* Give up at this point; we put the source and destination port in
2462 the tree, before fetching the header length, so that they'll
2463 show up if this is in the failing packet in an ICMP error packet,
2464 but it's now time to give up if the header length is bogus. */
2465 if (check_col(pinfo->cinfo, COL_INFO))
2466 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
2467 tcph->th_hlen, TCPH_MIN_LEN);
2469 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2470 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
2477 if (tcp_summary_in_tree) {
2478 if(tcph->th_flags&TH_ACK){
2479 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
2481 if (tcph->th_have_seglen)
2482 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
2484 proto_item_set_len(ti, tcph->th_hlen);
2485 if (tcph->th_have_seglen) {
2486 if (nxtseq != tcph->th_seq) {
2487 if(tcp_relative_seq){
2488 tf=proto_tree_add_uint_format(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "Next sequence number: %u (relative sequence number)", nxtseq);
2490 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
2492 PROTO_ITEM_SET_GENERATED(tf);
2495 if (tcph->th_flags & TH_ACK) {
2496 if(tcp_relative_seq){
2497 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);
2499 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
2502 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2503 "Header length: %u bytes", tcph->th_hlen);
2504 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
2505 tcph->th_flags, "Flags: 0x%04x (%s)", tcph->th_flags, flags);
2506 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
2507 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
2508 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
2509 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
2510 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
2511 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
2512 tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
2513 tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
2514 tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
2515 if(tcp_relative_seq && (tcph->th_win!=real_window)){
2516 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);
2518 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
2522 if(tcph->th_flags & TH_SYN) {
2523 if(tcph->th_flags & TH_ACK)
2524 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): %s -> %s",
2525 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2527 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): %s -> %s",
2528 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2530 if(tcph->th_flags & TH_FIN)
2531 expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN): %s -> %s",
2532 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2533 if(tcph->th_flags & TH_RST)
2534 expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST): %s -> %s",
2535 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2537 /* Supply the sequence number of the first byte and of the first byte
2538 after the segment. */
2539 tcpinfo.seq = tcph->th_seq;
2540 tcpinfo.nxtseq = nxtseq;
2542 /* Assume we'll pass un-reassembled data to subdissectors. */
2543 tcpinfo.is_reassembled = FALSE;
2545 pinfo->private_data = &tcpinfo;
2548 * Assume, initially, that we can't desegment.
2550 pinfo->can_desegment = 0;
2551 th_sum = tvb_get_ntohs(tvb, offset + 16);
2552 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
2553 /* The packet isn't part of an un-reassembled fragmented datagram
2554 and isn't truncated. This means we have all the data, and thus
2555 can checksum it and, unless it's being returned in an error
2556 packet, are willing to allow subdissectors to request reassembly
2559 if (tcp_check_checksum) {
2560 /* We haven't turned checksum checking off; checksum it. */
2562 /* Set up the fields of the pseudo-header. */
2563 cksum_vec[0].ptr = pinfo->src.data;
2564 cksum_vec[0].len = pinfo->src.len;
2565 cksum_vec[1].ptr = pinfo->dst.data;
2566 cksum_vec[1].len = pinfo->dst.len;
2567 cksum_vec[2].ptr = (const guint8 *)&phdr;
2568 switch (pinfo->src.type) {
2571 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
2572 cksum_vec[2].len = 4;
2576 phdr[0] = g_htonl(reported_len);
2577 phdr[1] = g_htonl(IP_PROTO_TCP);
2578 cksum_vec[2].len = 8;
2582 /* TCP runs only atop IPv4 and IPv6.... */
2583 DISSECTOR_ASSERT_NOT_REACHED();
2586 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
2587 cksum_vec[3].len = reported_len;
2588 computed_cksum = in_cksum(&cksum_vec[0], 4);
2589 if (computed_cksum == 0) {
2590 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2591 offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
2593 /* Checksum is valid, so we're willing to desegment it. */
2594 desegment_ok = TRUE;
2595 } else if (th_sum == 0) {
2596 /* checksum is probably fine but checksum offload is used */
2597 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2598 offset + 16, 2, th_sum, "Checksum: 0x%04x [Checksum Offloaded]", th_sum);
2600 /* Checksum is (probably) valid, so we're willing to desegment it. */
2601 desegment_ok = TRUE;
2605 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2606 offset + 16, 2, th_sum,
2607 "Checksum: 0x%04x [incorrect, should be 0x%04x]", th_sum,
2608 in_cksum_shouldbe(th_sum, computed_cksum));
2609 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
2610 item = proto_tree_add_boolean(tcp_tree, hf_tcp_checksum_bad, tvb,
2611 offset + 16, 2, TRUE);
2612 PROTO_ITEM_SET_GENERATED(item);
2613 /* XXX - don't use hidden fields for checksums */
2614 PROTO_ITEM_SET_HIDDEN(item);
2616 if (check_col(pinfo->cinfo, COL_INFO))
2617 col_append_fstr(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
2619 /* Checksum is invalid, so we're not willing to desegment it. */
2620 desegment_ok = FALSE;
2621 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
2624 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2625 offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
2627 /* We didn't check the checksum, and don't care if it's valid,
2628 so we're willing to desegment it. */
2629 desegment_ok = TRUE;
2632 /* We don't have all the packet data, so we can't checksum it... */
2633 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2634 offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
2636 /* ...and aren't willing to desegment it. */
2637 desegment_ok = FALSE;
2641 /* We're willing to desegment this. Is desegmentation enabled? */
2642 if (tcp_desegment) {
2643 /* Yes - is this segment being returned in an error packet? */
2644 if (!pinfo->in_error_pkt) {
2645 /* No - indicate that we will desegment.
2646 We do NOT want to desegment segments returned in error
2647 packets, as they're not part of a TCP connection. */
2648 pinfo->can_desegment = 2;
2653 if (tcph->th_flags & TH_URG) {
2654 th_urp = tvb_get_ntohs(tvb, offset + 18);
2655 /* Export the urgent pointer, for the benefit of protocols such as
2657 tcpinfo.urgent = TRUE;
2658 tcpinfo.urgent_pointer = th_urp;
2659 if (check_col(pinfo->cinfo, COL_INFO))
2660 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
2661 if (tcp_tree != NULL)
2662 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
2664 tcpinfo.urgent = FALSE;
2666 if (tcph->th_have_seglen) {
2667 if (check_col(pinfo->cinfo, COL_INFO))
2668 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
2671 /* Decode TCP options, if any. */
2672 if (tcph->th_hlen > TCPH_MIN_LEN) {
2673 /* There's more than just the fixed-length header. Decode the
2675 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
2676 tvb_ensure_bytes_exist(tvb, offset + 20, optlen);
2677 if (tcp_tree != NULL) {
2678 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
2679 "Options: (%u bytes)", optlen);
2680 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
2683 dissect_ip_tcp_options(tvb, offset + 20, optlen,
2684 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
2687 /* If there was window scaling in the SYN packet but none in the SYN+ACK
2688 * then we should just forget about the windowscaling completely.
2690 if(!pinfo->fd->flags.visited){
2691 if(tcp_analyze_seq && tcp_relative_seq){
2692 if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
2693 verify_tcp_window_scaling(tcpd);
2698 /* Skip over header + options */
2699 offset += tcph->th_hlen;
2701 /* Check the packet length to see if there's more data
2702 (it could be an ACK-only packet) */
2703 length_remaining = tvb_length_remaining(tvb, offset);
2705 if (tcph->th_have_seglen) {
2706 if( data_out_file ) {
2707 reassemble_tcp( tcph->th_seq, /* sequence number */
2708 tcph->th_seglen, /* data length */
2709 tvb_get_ptr(tvb, offset, length_remaining), /* data */
2710 length_remaining, /* captured data length */
2711 ( tcph->th_flags & TH_SYN ), /* is syn set? */
2719 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
2720 if(tcp_analyze_seq){
2721 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd);
2723 tap_queue_packet(tcp_tap, pinfo, tcph);
2726 * XXX - what, if any, of this should we do if this is included in an
2727 * error packet? It might be nice to see the details of the packet
2728 * that caused the ICMP error, but it might not be nice to have the
2729 * dissector update state based on it.
2730 * Also, we probably don't want to run TCP taps on those packets.
2732 if (length_remaining != 0) {
2733 if (tcph->th_flags & TH_RST) {
2737 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
2739 * A TCP SHOULD allow a received RST segment to include data.
2742 * It has been suggested that a RST segment could contain
2743 * ASCII text that encoded and explained the cause of the
2744 * RST. No standard has yet been established for such
2747 * so for segments with RST we just display the data as text.
2749 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
2751 tvb_format_text(tvb, offset, length_remaining));
2753 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
2754 tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd);
2760 proto_register_tcp(void)
2762 static hf_register_info hf[] = {
2765 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
2769 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
2773 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
2777 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
2781 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
2785 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
2789 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2793 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2796 { &hf_tcp_flags_cwr,
2797 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
2800 { &hf_tcp_flags_ecn,
2801 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
2804 { &hf_tcp_flags_urg,
2805 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
2808 { &hf_tcp_flags_ack,
2809 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
2812 { &hf_tcp_flags_push,
2813 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
2816 { &hf_tcp_flags_reset,
2817 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
2820 { &hf_tcp_flags_syn,
2821 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
2824 { &hf_tcp_flags_fin,
2825 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
2828 /* 32 bits so we can present some values adjusted to window scaling */
2829 { &hf_tcp_window_size,
2830 { "Window size", "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
2834 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
2837 { &hf_tcp_checksum_bad,
2838 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2841 { &hf_tcp_analysis_flags,
2842 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
2843 "This frame has some of the TCP analysis flags set", HFILL }},
2845 { &hf_tcp_analysis_retransmission,
2846 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2847 "This frame is a suspected TCP retransmission", HFILL }},
2849 { &hf_tcp_analysis_fast_retransmission,
2850 { "Fast Retransmission", "tcp.analysis.fast_retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2851 "This frame is a suspected TCP fast retransmission", HFILL }},
2853 { &hf_tcp_analysis_out_of_order,
2854 { "Out Of Order", "tcp.analysis.out_of_order", FT_NONE, BASE_NONE, NULL, 0x0,
2855 "This frame is a suspected Out-Of-Order segment", HFILL }},
2857 { &hf_tcp_analysis_lost_packet,
2858 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2859 "A segment before this one was lost from the capture", HFILL }},
2861 { &hf_tcp_analysis_ack_lost_packet,
2862 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2863 "This frame ACKs a lost segment", HFILL }},
2865 { &hf_tcp_analysis_window_update,
2866 { "Window update", "tcp.analysis.window_update", FT_NONE, BASE_NONE, NULL, 0x0,
2867 "This frame is a tcp window update", HFILL }},
2869 { &hf_tcp_analysis_window_full,
2870 { "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
2871 "This segment has caused the allowed window to become 100% full", HFILL }},
2873 { &hf_tcp_analysis_keep_alive,
2874 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
2875 "This is a keep-alive segment", HFILL }},
2877 { &hf_tcp_analysis_keep_alive_ack,
2878 { "Keep Alive ACK", "tcp.analysis.keep_alive_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2879 "This is an ACK to a keep-alive segment", HFILL }},
2881 { &hf_tcp_analysis_duplicate_ack,
2882 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2883 "This is a duplicate ACK", HFILL }},
2885 { &hf_tcp_analysis_duplicate_ack_num,
2886 { "Duplicate ACK #", "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
2887 "This is duplicate ACK number #", HFILL }},
2889 { &hf_tcp_analysis_duplicate_ack_frame,
2890 { "Duplicate to the ACK in frame", "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2891 "This is a duplicate to the ACK in frame #", HFILL }},
2893 { &hf_tcp_continuation_to,
2894 { "This is a continuation to the PDU in frame", "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2895 "This is a continuation to the PDU in frame #", HFILL }},
2897 { &hf_tcp_analysis_zero_window_probe,
2898 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
2899 "This is a zero-window-probe", HFILL }},
2901 { &hf_tcp_analysis_zero_window_probe_ack,
2902 { "Zero Window Probe Ack", "tcp.analysis.zero_window_probe_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2903 "This is an ACK to a zero-window-probe", HFILL }},
2905 { &hf_tcp_analysis_zero_window,
2906 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
2907 "This is a zero-window", HFILL }},
2910 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
2913 { &hf_tcp_analysis_acks_frame,
2914 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2915 "Which previous segment is this an ACK for", HFILL}},
2917 { &hf_tcp_analysis_ack_rtt,
2918 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2919 "How long time it took to ACK the segment (RTT)", HFILL}},
2921 { &hf_tcp_analysis_rto,
2922 { "The RTO for this segment was", "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2923 "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
2925 { &hf_tcp_analysis_rto_frame,
2926 { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2927 "This is the frame we measure the RTO from", HFILL }},
2929 { &hf_tcp_urgent_pointer,
2930 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
2933 { &hf_tcp_segment_overlap,
2934 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2935 "Segment overlaps with other segments", HFILL }},
2937 { &hf_tcp_segment_overlap_conflict,
2938 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2939 "Overlapping segments contained conflicting data", HFILL }},
2941 { &hf_tcp_segment_multiple_tails,
2942 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2943 "Several tails were found when reassembling the pdu", HFILL }},
2945 { &hf_tcp_segment_too_long_fragment,
2946 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2947 "Segment contained data past end of the pdu", HFILL }},
2949 { &hf_tcp_segment_error,
2950 { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2951 "Reassembling error due to illegal segments", HFILL }},
2954 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2955 "TCP Segment", HFILL }},
2958 { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
2959 "TCP Segments", HFILL }},
2961 { &hf_tcp_reassembled_in,
2962 { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2963 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
2965 { &hf_tcp_option_mss,
2966 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
2967 BASE_NONE, NULL, 0x0, "TCP MSS Option", HFILL }},
2969 { &hf_tcp_option_mss_val,
2970 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
2971 BASE_DEC, NULL, 0x0, "TCP MSS Option Value", HFILL}},
2973 { &hf_tcp_option_wscale,
2974 { "TCP Window Scale Option", "tcp.options.wscale",
2976 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
2978 { &hf_tcp_option_wscale_val,
2979 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
2980 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
2983 { &hf_tcp_option_sack_perm,
2984 { "TCP Sack Perm Option", "tcp.options.sack_perm",
2986 BASE_NONE, NULL, 0x0, "TCP Sack Perm Option", HFILL}},
2988 { &hf_tcp_option_sack,
2989 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
2990 BASE_NONE, NULL, 0x0, "TCP Sack Option", HFILL}},
2992 { &hf_tcp_option_sack_sle,
2993 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
2994 BASE_DEC, NULL, 0x0, "TCP Sack Left Edge", HFILL}},
2996 { &hf_tcp_option_sack_sre,
2997 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
2998 BASE_DEC, NULL, 0x0, "TCP Sack Right Edge", HFILL}},
3000 { &hf_tcp_option_echo,
3001 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
3002 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
3004 { &hf_tcp_option_echo_reply,
3005 { "TCP Echo Reply Option", "tcp.options.echo_reply",
3007 BASE_NONE, NULL, 0x0, "TCP Echo Reply Option", HFILL}},
3009 { &hf_tcp_option_time_stamp,
3010 { "TCP Time Stamp Option", "tcp.options.time_stamp",
3012 BASE_NONE, NULL, 0x0, "TCP Time Stamp Option", HFILL}},
3014 { &hf_tcp_option_cc,
3015 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
3016 NULL, 0x0, "TCP CC Option", HFILL}},
3018 { &hf_tcp_option_ccnew,
3019 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
3020 BASE_NONE, NULL, 0x0, "TCP CC New Option", HFILL}},
3022 { &hf_tcp_option_ccecho,
3023 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
3024 BASE_NONE, NULL, 0x0, "TCP CC Echo Option", HFILL}},
3026 { &hf_tcp_option_md5,
3027 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
3028 NULL, 0x0, "TCP MD5 Option", HFILL}},
3031 { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3032 "How long time has passed until the last frame of this PDU", HFILL}},
3033 { &hf_tcp_pdu_last_frame,
3034 { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3035 "This is the last frame of the PDU starting in this segment", HFILL }},
3038 static gint *ett[] = {
3042 &ett_tcp_option_sack,
3043 &ett_tcp_analysis_faults,
3048 module_t *tcp_module;
3050 proto_tcp = proto_register_protocol("Transmission Control Protocol",
3052 proto_register_field_array(proto_tcp, hf, array_length(hf));
3053 proto_register_subtree_array(ett, array_length(ett));
3055 /* subdissector code */
3056 subdissector_table = register_dissector_table("tcp.port",
3057 "TCP port", FT_UINT16, BASE_DEC);
3058 register_heur_dissector_list("tcp", &heur_subdissector_list);
3060 /* Register configuration preferences */
3061 tcp_module = prefs_register_protocol(proto_tcp, NULL);
3062 prefs_register_bool_preference(tcp_module, "summary_in_tree",
3063 "Show TCP summary in protocol tree",
3064 "Whether the TCP summary line should be shown in the protocol tree",
3065 &tcp_summary_in_tree);
3066 prefs_register_bool_preference(tcp_module, "check_checksum",
3067 "Validate the TCP checksum if possible",
3068 "Whether to validate the TCP checksum",
3069 &tcp_check_checksum);
3070 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
3071 "Allow subdissector to reassemble TCP streams",
3072 "Whether subdissector can request TCP streams to be reassembled",
3074 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
3075 "Analyze TCP sequence numbers",
3076 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
3078 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
3079 "Relative sequence numbers and window scaling",
3080 "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
3081 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
3082 "This option will also try to track and adjust the window field according to any TCP window scaling options seen.",
3084 prefs_register_bool_preference(tcp_module, "try_heuristic_first",
3085 "Try heuristic sub-dissectors first",
3086 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
3087 &try_heuristic_first);
3089 tcp_pdu_time_table=se_tree_create(SE_TREE_TYPE_RED_BLACK, "tcp_pdu_time_table");
3090 register_init_routine(tcp_analyze_seq_init);
3091 register_init_routine(tcp_desegment_init);
3092 register_init_routine(tcp_fragment_init);
3096 proto_reg_handoff_tcp(void)
3098 dissector_handle_t tcp_handle;
3100 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
3101 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
3102 data_handle = find_dissector("data");
3103 tcp_tap = register_tap("tcp");