2 * Routines for TCP packet disassembly
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/in_cksum.h>
34 #include <epan/packet.h>
35 #include <epan/addr_resolv.h>
36 #include <epan/ipproto.h>
37 #include <epan/ip_opts.h>
38 #include <epan/follow.h>
39 #include <epan/prefs.h>
40 #include "packet-tcp.h"
41 #include "packet-ip.h"
42 #include "packet-frame.h"
43 #include <epan/conversation.h>
44 #include <epan/strutil.h>
45 #include <epan/reassemble.h>
47 #include <epan/emem.h>
48 #include <epan/slab.h>
49 #include <epan/expert.h>
51 static int tcp_tap = -1;
53 /* Place TCP summary in proto tree */
54 static gboolean tcp_summary_in_tree = TRUE;
57 * Flag to control whether to check the TCP checksum.
59 * In at least some Solaris network traces, there are packets with bad
60 * TCP checksums, but the traffic appears to indicate that the packets
61 * *were* received; the packets were probably sent by the host on which
62 * the capture was being done, on a network interface to which
63 * checksumming was offloaded, so that DLPI supplied an un-checksummed
64 * packet to the capture program but a checksummed packet got put onto
67 static gboolean tcp_check_checksum = TRUE;
69 extern FILE* data_out_file;
71 static int proto_tcp = -1;
72 static int hf_tcp_srcport = -1;
73 static int hf_tcp_dstport = -1;
74 static int hf_tcp_port = -1;
75 static int hf_tcp_seq = -1;
76 static int hf_tcp_nxtseq = -1;
77 static int hf_tcp_ack = -1;
78 static int hf_tcp_hdr_len = -1;
79 static int hf_tcp_flags = -1;
80 static int hf_tcp_flags_cwr = -1;
81 static int hf_tcp_flags_ecn = -1;
82 static int hf_tcp_flags_urg = -1;
83 static int hf_tcp_flags_ack = -1;
84 static int hf_tcp_flags_push = -1;
85 static int hf_tcp_flags_reset = -1;
86 static int hf_tcp_flags_syn = -1;
87 static int hf_tcp_flags_fin = -1;
88 static int hf_tcp_window_size = -1;
89 static int hf_tcp_checksum = -1;
90 static int hf_tcp_checksum_bad = -1;
91 static int hf_tcp_len = -1;
92 static int hf_tcp_urgent_pointer = -1;
93 static int hf_tcp_analysis_flags = -1;
94 static int hf_tcp_analysis_acks_frame = -1;
95 static int hf_tcp_analysis_ack_rtt = -1;
96 static int hf_tcp_analysis_rto = -1;
97 static int hf_tcp_analysis_rto_frame = -1;
98 static int hf_tcp_analysis_retransmission = -1;
99 static int hf_tcp_analysis_fast_retransmission = -1;
100 static int hf_tcp_analysis_out_of_order = -1;
101 static int hf_tcp_analysis_lost_packet = -1;
102 static int hf_tcp_analysis_ack_lost_packet = -1;
103 static int hf_tcp_analysis_window_update = -1;
104 static int hf_tcp_analysis_window_full = -1;
105 static int hf_tcp_analysis_keep_alive = -1;
106 static int hf_tcp_analysis_keep_alive_ack = -1;
107 static int hf_tcp_analysis_duplicate_ack = -1;
108 static int hf_tcp_analysis_duplicate_ack_num = -1;
109 static int hf_tcp_analysis_duplicate_ack_frame = -1;
110 static int hf_tcp_analysis_zero_window = -1;
111 static int hf_tcp_analysis_zero_window_probe = -1;
112 static int hf_tcp_analysis_zero_window_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
210 static GHashTable *tcp_analyze_acked_table = NULL;
212 static GHashTable *tcp_pdu_tracking_table = NULL;
213 static GHashTable *tcp_pdu_skipping_table = NULL;
214 static se_tree_t *tcp_pdu_time_table = NULL;
217 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
218 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
219 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
220 struct tcp_analysis *tcpd);
223 struct tcp_analysis *
224 get_tcp_conversation_data(packet_info *pinfo)
227 conversation_t *conv=NULL;
228 struct tcp_analysis *tcpd=NULL;
230 /* Have we seen this conversation before? */
231 if( (conv=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
232 /* No this is a new conversation. */
233 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
236 /* check if we have any data for this conversation */
237 tcpd=conversation_get_proto_data(conv, proto_tcp);
239 /* No no such data yet. Allocate and init it */
240 tcpd=se_alloc(sizeof(struct tcp_analysis));
241 tcpd->flow1.segments=NULL;
242 tcpd->flow1.base_seq=0;
243 tcpd->flow1.lastack=0;
244 tcpd->flow1.lastacktime.secs=0;
245 tcpd->flow1.lastacktime.nsecs=0;
246 tcpd->flow1.lastnondupack=0;
247 tcpd->flow1.nextseq=0;
248 tcpd->flow1.nextseqtime.secs=0;
249 tcpd->flow1.nextseqtime.nsecs=0;
250 tcpd->flow1.nextseqframe=0;
251 tcpd->flow1.window=0;
252 tcpd->flow1.win_scale=-1;
253 tcpd->flow1.pdu_seq=NULL;
254 tcpd->flow2.segments=NULL;
255 tcpd->flow2.base_seq=0;
256 tcpd->flow2.lastack=0;
257 tcpd->flow2.lastacktime.secs=0;
258 tcpd->flow2.lastacktime.nsecs=0;
259 tcpd->flow2.lastnondupack=0;
260 tcpd->flow2.nextseq=0;
261 tcpd->flow2.nextseqtime.secs=0;
262 tcpd->flow2.nextseqtime.nsecs=0;
263 tcpd->flow2.nextseqframe=0;
264 tcpd->flow2.window=0;
265 tcpd->flow2.win_scale=-1;
266 tcpd->flow2.pdu_seq=NULL;
268 conversation_add_proto_data(conv, proto_tcp, tcpd);
272 /* check direction and get ua lists */
273 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
274 /* if the addresses are equal, match the ports instead */
276 direction= (pinfo->srcport > pinfo->destport)*2-1;
279 tcpd->fwd=&(tcpd->flow1);
280 tcpd->rev=&(tcpd->flow2);
282 tcpd->fwd=&(tcpd->flow2);
283 tcpd->rev=&(tcpd->flow1);
290 /* This function is called from the tcp analysis code to provide
291 clues on how the seq and ack numbers are changed.
292 To prevent the next_pdu lists from growing uncontrollable in size we
293 use this function to do the following :
294 IF we see an ACK then we assume that the left edge of the window has changed
295 at least to this point and assuming it is rare with reordering and
296 trailing duplicate/retransmitted segments, we just assume that after
297 we have seen the ACK we will not see any more segments prior to the
299 If we will not see any segments prior to the ACK value then we can just
300 delete all next_pdu entries that describe pdu's starting prior to the
302 If this heuristics is prooved to be too simplistic we can just enhance it
305 /* XXX this function should be ehnanced to handle sequence number wrapping */
306 /* XXX to handle retransmissions and reordered packets maybe we should only
307 discard entries that are more than (guesstimate) 50kb older than the
308 specified sequence number ?
311 prune_next_pdu_list(struct tcp_next_pdu **tnp, guint32 seq)
313 struct tcp_next_pdu *tmptnp;
319 for(tmptnp=*tnp;tmptnp;tmptnp=tmptnp->next){
320 if(tmptnp->nxtpdu<=seq){
321 struct tcp_next_pdu *oldtnp;
332 for(tmptnp=*tnp;tmptnp;tmptnp=tmptnp->next){
333 if(tmptnp->next==oldtnp){
334 tmptnp->next=oldtnp->next;
348 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_next_pdu *tnp)
352 if (check_col(pinfo->cinfo, COL_INFO)){
353 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", tnp->first_frame);
355 item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
356 tvb, 0, 0, tnp->first_frame);
357 PROTO_ITEM_SET_GENERATED(item);
360 /* if we know that a PDU starts inside this segment, return the adjusted
361 offset to where that PDU starts or just return offset back
362 and let TCP try to find out what it can about this segment
365 scan_for_next_pdu(tvbuff_t *tvb, proto_tree *tcp_tree, packet_info *pinfo, int offset, guint32 seq, guint32 nxtseq, struct tcp_analysis *tcpd)
367 struct tcp_next_pdu *tnp=NULL;
369 if(!pinfo->fd->flags.visited){
370 /* find(or create if needed) the conversation for this tcp session */
371 tnp=tcpd->fwd->pdu_seq;
373 /* scan and see if we find any pdus starting inside this tvb */
374 for(;tnp;tnp=tnp->next){
375 /* XXX here we should also try to handle sequence number
378 /* If this segment is completely within a previous PDU
379 * then we just skip this packet
381 if(seq>tnp->seq && nxtseq<=tnp->nxtpdu){
382 tnp->last_frame=pinfo->fd->num;
383 tnp->last_frame_time=pinfo->fd->abs_ts;
384 g_hash_table_insert(tcp_pdu_skipping_table,
385 GINT_TO_POINTER(pinfo->fd->num), (void *)tnp);
386 print_pdu_tracking_data(pinfo, tvb, tcp_tree, tnp);
390 if(seq<tnp->nxtpdu && nxtseq>tnp->nxtpdu){
391 g_hash_table_insert(tcp_pdu_tracking_table,
392 GINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(tnp->nxtpdu));
393 offset+=tnp->nxtpdu-seq;
400 tnp=(struct tcp_next_pdu *)se_tree_lookup32(tcp_pdu_time_table, pinfo->fd->num);
405 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, tnp->last_frame);
406 PROTO_ITEM_SET_GENERATED(item);
408 nstime_delta(&ns, &tnp->last_frame_time, &pinfo->fd->abs_ts);
409 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
411 PROTO_ITEM_SET_GENERATED(item);
414 /* check if this is a segment in the middle of a pdu */
415 tnp=(struct tcp_next_pdu *)g_hash_table_lookup(tcp_pdu_skipping_table, GINT_TO_POINTER(pinfo->fd->num));
417 print_pdu_tracking_data(pinfo, tvb, tcp_tree, tnp);
421 pduseq=GPOINTER_TO_UINT(g_hash_table_lookup(tcp_pdu_tracking_table, GINT_TO_POINTER(pinfo->fd->num)));
430 /* if we saw a PDU that extended beyond the end of the segment,
431 use this function to remember where the next pdu starts
434 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, struct tcp_analysis *tcpd)
436 struct tcp_next_pdu *tnp=NULL;
438 tnp=se_alloc(sizeof(struct tcp_next_pdu));
441 tnp->first_frame=pinfo->fd->num;
442 tnp->last_frame=pinfo->fd->num;
443 tnp->last_frame_time=pinfo->fd->abs_ts;
445 tnp->next=tcpd->fwd->pdu_seq;
446 tcpd->fwd->pdu_seq=tnp;
448 Add check for ACKs and purge list of sequence numbers
451 se_tree_insert32(tcp_pdu_time_table, pinfo->fd->num, (void *)tnp);
454 /* This is called for SYN+ACK packets and the purpose is to verify that we
455 * have seen window scaling in both directions.
456 * If we cant find window scaling being set in both directions
457 * that means it was present in the SYN but not in the SYN+ACK
458 * (or the SYN was missing) and then we disable the window scaling
459 * for this tcp session.
462 verify_tcp_window_scaling(struct tcp_analysis *tcpd)
464 if( tcpd && ((tcpd->flow1.win_scale==-1) || (tcpd->flow2.win_scale==-1)) ){
465 tcpd->flow1.win_scale=-1;
466 tcpd->flow2.win_scale=-1;
470 /* if we saw a window scaling option, store it for future reference
473 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
475 tcpd->fwd->win_scale=ws;
479 tcp_get_relative_seq_ack(guint32 *seq, guint32 *ack, guint32 *win, struct tcp_analysis *tcpd)
481 if(tcp_relative_seq){
482 (*seq) -= tcpd->fwd->base_seq;
483 (*ack) -= tcpd->rev->base_seq;
484 if(tcpd->fwd->win_scale!=-1){
485 (*win)<<=tcpd->fwd->win_scale;
491 /* when this function returns, it will (if createflag) populate the ta pointer.
494 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag, struct tcp_analysis *tcpd)
496 tcpd->ta=g_hash_table_lookup(tcp_analyze_acked_table, GUINT_TO_POINTER(frame));
497 if((!tcpd->ta) && createflag){
498 tcpd->ta=se_alloc(sizeof(struct tcp_acked));
499 tcpd->ta->frame_acked=0;
501 tcpd->ta->ts.nsecs=0;
503 tcpd->ta->dupack_num=0;
504 tcpd->ta->dupack_frame=0;
505 g_hash_table_insert(tcp_analyze_acked_table, GUINT_TO_POINTER(frame), tcpd->ta);
510 /* fwd contains a list of all segments processed but not yet ACKed in the
511 * same direction as the current segment.
512 * rev contains a list of all segments received but not yet ACKed in the
513 * opposite direction to the current segment.
515 * New segments are always added to the head of the fwd/rev lists.
519 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint32 window, struct tcp_analysis *tcpd)
521 tcp_unacked_t *ual=NULL;
525 printf("analyze_sequence numbers frame:%d direction:%s\n",pinfo->fd->num,direction>=0?"FWD":"REW");
526 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);
527 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);
532 /* if this is the first segment for this list we need to store the
535 if(tcpd->fwd->base_seq==0){
536 tcpd->fwd->base_seq=seq;
538 /* if we have spotted a new base_Seq in the reverse direction
541 if(tcpd->rev->base_seq==0){
542 tcpd->rev->base_seq=ack;
548 * it is a zero window probe if
549 * the sequnece number is the next expected one
550 * the window in the other direction is 0
551 * the segment is exactly 1 byte
555 && seq==tcpd->fwd->nextseq
556 && tcpd->rev->window==0 ){
558 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
560 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
566 * a zero window packet has window == 0 but none of the SYN/FIN/RST set
570 && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ){
572 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
574 tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
579 * If this segment is beyond the last seen nextseq we must
580 * have missed some previous segment
582 * We only check for this if we have actually seen segments prior to this
584 * RST packets are not checked for this.
586 if( tcpd->fwd->nextseq
587 && GT_SEQ(seq, tcpd->fwd->nextseq)
588 && (flags&(TH_RST))==0 ){
590 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
592 tcpd->ta->flags|=TCP_A_LOST_PACKET;
597 * a keepalive contains 0 or 1 bytes of data and starts one byte prior
598 * to what should be the next sequence number.
599 * SYN/FIN/RST segments are never keepalives
602 if( (seglen==0||seglen==1)
603 && seq==(tcpd->fwd->nextseq-1)
604 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
606 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
608 tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
612 * A window update is a 0 byte segment with the same SEQ/ACK numbers as
613 * the previous seen segment and with a new window value
617 && window!=tcpd->fwd->window
618 && seq==tcpd->fwd->nextseq
619 && ack==tcpd->fwd->lastack
620 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
622 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
624 tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
629 * If we know the window scaling
630 * and if this segment contains data ang goes all the way to the
631 * edge of the advertized window
632 * then we mark it as WINDOW FULL
633 * SYN/RST/FIN packets are never WINDOW FULL
637 && tcpd->fwd->win_scale!=-1
638 && tcpd->rev->win_scale!=-1
639 && (seq+seglen)==(tcpd->rev->lastack+(tcpd->rev->window<<tcpd->rev->win_scale))
640 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
642 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
644 tcpd->ta->flags|=TCP_A_WINDOW_FULL;
649 * It is a keepalive ack if it repeats the previous ACK and if
650 * the last segment in the reverse direction was a keepalive
655 && window==tcpd->fwd->window
656 && seq==tcpd->fwd->nextseq
657 && ack==tcpd->fwd->lastack
658 && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
659 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
661 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
663 tcpd->ta->flags|=TCP_A_KEEP_ALIVE_ACK;
668 /* ZERO WINDOW PROBE ACK
669 * It is a zerowindowprobe ack if it repeats the previous ACK and if
670 * the last segment in the reverse direction was a zerowindowprobe
671 * It also repeats the previous zero window indication
676 && window==tcpd->fwd->window
677 && seq==tcpd->fwd->nextseq
678 && ack==tcpd->fwd->lastack
679 && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
680 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
682 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
684 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
690 * It is a duplicate ack if window/seq/ack is the same as the previous
691 * segment and if the segment length is 0
695 && window==tcpd->fwd->window
696 && seq==tcpd->fwd->nextseq
697 && ack==tcpd->fwd->lastack
698 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
699 tcpd->fwd->dupacknum++;
701 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
703 tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
704 tcpd->ta->dupack_num=tcpd->fwd->dupacknum;
705 tcpd->ta->dupack_frame=tcpd->fwd->lastnondupack;
710 /* If this was NOT a dupack we must reset the dupack countres */
711 if( (!tcpd->ta) || !(tcpd->ta->flags&TCP_A_DUPLICATE_ACK) ){
712 tcpd->fwd->lastnondupack=pinfo->fd->num;
713 tcpd->fwd->dupacknum=0;
718 * If this segment acks beyond the nextseqnum in the other direction
719 * then that means we have missed packets going in the
722 * We only check this if we have actually seen some seq numbers
723 * in the other direction.
725 if( tcpd->rev->nextseq
726 && GT_SEQ(ack, tcpd->rev->nextseq )){
729 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
731 tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
732 /* update nextseq in the other direction so we dont get
733 * this indication again.
735 tcpd->rev->nextseq=ack;
739 /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
740 * If the segments contains data and if it does not advance
741 * sequence number it must be either of these three.
742 * Only test for this if we know what the seq number should be
743 * (tcpd->fwd->nextseq)
745 * Note that a simple KeepAlive is not a retransmission
748 && tcpd->fwd->nextseq
749 && (LT_SEQ(seq, tcpd->fwd->nextseq)) ){
752 if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ){
753 goto finished_checking_retransmission_type;
756 /* If there were >=1 duplicate ACKs in the reverse direction
757 * (there might be duplicate acks missing from the trace)
758 * and if this sequence number matches those ACKs
759 * and if the packet occurs within 20ms of the last
761 * then this is a fast retransmission
763 t=(pinfo->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
764 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;
765 if( tcpd->rev->dupacknum>=1
766 && tcpd->rev->lastack==seq
769 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
771 tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
772 goto finished_checking_retransmission_type;
775 /* If the segment came <3ms since the segment with the highest
776 * seen sequence number, then it is an OUT-OF-ORDER segment.
777 * (3ms is an arbitrary number)
779 t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
780 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
783 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
785 tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
786 goto finished_checking_retransmission_type;
789 /* Then it has to be a generic retransmission */
791 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
793 tcpd->ta->flags|=TCP_A_RETRANSMISSION;
794 nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
795 tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
797 finished_checking_retransmission_type:
800 /* add this new sequence number to the fwd list */
801 TCP_UNACKED_NEW(ual);
802 ual->next=tcpd->fwd->segments;
803 tcpd->fwd->segments=ual;
804 ual->frame=pinfo->fd->num;
806 ual->ts=pinfo->fd->abs_ts;
808 /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
809 ual->nextseq=seq+seglen;
810 if( flags&(TH_SYN|TH_FIN) ){
814 /* Store the highest number seen so far for nextseq so we can detect
815 * when we receive segments that arrive with a "hole"
816 * If we dont have anything since before, just store what we got.
817 * ZeroWindowProbes are special and dont really advance the nextseq
819 if(GT_SEQ(ual->nextseq, tcpd->fwd->nextseq) || !tcpd->fwd->nextseq) {
820 if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ){
821 tcpd->fwd->nextseq=ual->nextseq;
822 tcpd->fwd->nextseqframe=pinfo->fd->num;
823 tcpd->fwd->nextseqtime.secs=pinfo->fd->abs_ts.secs;
824 tcpd->fwd->nextseqtime.nsecs=pinfo->fd->abs_ts.nsecs;
829 /* remember what the ack/window is so we can track window updates and retransmissions */
830 tcpd->fwd->window=window;
831 tcpd->fwd->lastack=ack;
832 tcpd->fwd->lastacktime.secs=pinfo->fd->abs_ts.secs;
833 tcpd->fwd->lastacktime.nsecs=pinfo->fd->abs_ts.nsecs;
836 /* if there were any flags set for this segment we need to remember them
837 * we only remember the flags for the very last segment though.
840 tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
842 tcpd->fwd->lastsegmentflags=0;
846 prune_next_pdu_list(&(tcpd->rev->pdu_seq), ack-tcpd->rev->base_seq);
848 /* remove all segments this ACKs and we dont need to keep around any more
851 /* first we remove all such segments at the head of the list */
852 while((ual=tcpd->rev->segments)){
853 tcp_unacked_t *tmpual;
854 if(GT_SEQ(ual->nextseq,ack)){
858 /*qqq do the ACKs segment x delta y */
861 tmpual=tcpd->rev->segments->next;
862 TCP_UNACKED_FREE(ual);
863 tcpd->rev->segments=tmpual;
865 /* now we remove all such segments that are NOT at the head of the list */
866 ual=tcpd->rev->segments;
867 while(ual && ual->next){
868 tcp_unacked_t *tmpual;
869 if(GT_SEQ(ual->next->nextseq,ack)){
874 /*qqq do the ACKs segment x delta y */
877 tmpual=ual->next->next;
878 TCP_UNACKED_FREE(ual->next);
884 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
885 tcpd->ta->frame_acked=tcpd->rev->segments->frame;
886 nstime_delta(&tcpd->ta->ts, &pinfo->fd->abs_ts, &tcpd->rev->segments->ts);
891 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd)
893 struct tcp_acked *ta;
898 tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE, tcpd);
905 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
906 PROTO_ITEM_SET_GENERATED(item);
907 tree=proto_item_add_subtree(item, ett_tcp_analysis);
909 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
910 data we actually have */
912 item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
913 tvb, 0, 0, ta->frame_acked);
914 PROTO_ITEM_SET_GENERATED(item);
916 /* only display RTT if we actually have something we are acking */
917 if( ta->ts.secs || ta->ts.nsecs ){
918 item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
920 PROTO_ITEM_SET_GENERATED(item);
925 proto_item *flags_item=NULL;
926 proto_tree *flags_tree=NULL;
928 flags_item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, -1, FALSE);
929 PROTO_ITEM_SET_GENERATED(flags_item);
930 flags_tree=proto_item_add_subtree(flags_item, ett_tcp_analysis);
931 if( ta->flags&TCP_A_RETRANSMISSION ){
932 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
933 PROTO_ITEM_SET_GENERATED(flags_item);
934 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Retransmission (suspected)");
935 if(check_col(pinfo->cinfo, COL_INFO)){
936 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
938 if( ta->rto_ts.secs || ta->rto_ts.nsecs ){
939 item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
940 tvb, 0, 0, &ta->rto_ts);
941 PROTO_ITEM_SET_GENERATED(item);
942 item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame, tvb, 0, 0, ta->rto_frame);
943 PROTO_ITEM_SET_GENERATED(item);
946 if( ta->flags&TCP_A_FAST_RETRANSMISSION ){
947 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_fast_retransmission, tvb, 0, 0, "This frame is a (suspected) fast retransmission");
948 PROTO_ITEM_SET_GENERATED(flags_item);
949 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Fast retransmission (suspected)");
950 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
951 PROTO_ITEM_SET_GENERATED(flags_item);
952 if(check_col(pinfo->cinfo, COL_INFO)){
953 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Fast Retransmission] ");
956 if( ta->flags&TCP_A_OUT_OF_ORDER ){
957 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");
958 PROTO_ITEM_SET_GENERATED(flags_item);
959 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Out-Of-Order segment");
960 if(check_col(pinfo->cinfo, COL_INFO)){
961 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
964 if( ta->flags&TCP_A_LOST_PACKET ){
965 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_lost_packet, tvb, 0, 0, "A segment before this frame was lost");
966 PROTO_ITEM_SET_GENERATED(flags_item);
967 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Previous segment lost (common at capture start)");
968 if(check_col(pinfo->cinfo, COL_INFO)){
969 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] ");
972 if( ta->flags&TCP_A_ACK_LOST_PACKET ){
973 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?)");
974 PROTO_ITEM_SET_GENERATED(flags_item);
975 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "ACKed lost segment (common at capture start)");
976 if(check_col(pinfo->cinfo, COL_INFO)){
977 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] ");
980 if( ta->flags&TCP_A_WINDOW_UPDATE ){
981 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_update, tvb, 0, 0, "This is a tcp window update");
982 PROTO_ITEM_SET_GENERATED(flags_item);
983 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window update");
984 if(check_col(pinfo->cinfo, COL_INFO)){
985 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
988 if( ta->flags&TCP_A_WINDOW_FULL ){
989 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_full, tvb, 0, 0, "The transmission window is now completely full");
990 PROTO_ITEM_SET_GENERATED(flags_item);
991 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window is full");
992 if(check_col(pinfo->cinfo, COL_INFO)){
993 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
996 if( ta->flags&TCP_A_KEEP_ALIVE ){
997 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive, tvb, 0, 0, "This is a TCP keep-alive segment");
998 PROTO_ITEM_SET_GENERATED(flags_item);
999 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive");
1000 if(check_col(pinfo->cinfo, COL_INFO)){
1001 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
1004 if( ta->flags&TCP_A_KEEP_ALIVE_ACK ){
1005 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");
1006 PROTO_ITEM_SET_GENERATED(flags_item);
1007 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive ACK");
1008 if(check_col(pinfo->cinfo, COL_INFO)){
1009 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
1012 if( ta->dupack_num){
1013 if( ta->flags&TCP_A_DUPLICATE_ACK ){
1014 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_duplicate_ack, tvb, 0, 0, "This is a TCP duplicate ack");
1015 PROTO_ITEM_SET_GENERATED(flags_item);
1016 if(check_col(pinfo->cinfo, COL_INFO)){
1017 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Dup ACK %u#%u] ", ta->dupack_frame, ta->dupack_num);
1020 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
1021 tvb, 0, 0, ta->dupack_num);
1022 PROTO_ITEM_SET_GENERATED(flags_item);
1023 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
1024 tvb, 0, 0, ta->dupack_frame);
1025 PROTO_ITEM_SET_GENERATED(flags_item);
1026 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Duplicate ACK (#%u) to ACK in packet #%u",
1027 ta->dupack_num, ta->dupack_frame);
1029 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE ){
1030 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");
1031 PROTO_ITEM_SET_GENERATED(flags_item);
1032 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe");
1033 if(check_col(pinfo->cinfo, COL_INFO)){
1034 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
1037 if( ta->flags&TCP_A_ZERO_WINDOW ){
1038 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window, tvb, 0, 0, "This is a ZeroWindow segment");
1039 PROTO_ITEM_SET_GENERATED(flags_item);
1040 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window");
1041 if(check_col(pinfo->cinfo, COL_INFO)){
1042 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
1045 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE_ACK ){
1046 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");
1047 PROTO_ITEM_SET_GENERATED(flags_item);
1048 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe ACK");
1049 if(check_col(pinfo->cinfo, COL_INFO)){
1050 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbeAck] ");
1058 /* Do we still need to do this ...remove_all() even though we dont need
1059 * to do anything special? The glib docs are not clear on this and
1060 * its better safe than sorry
1063 free_all_acked(gpointer key_arg _U_, gpointer value _U_, gpointer user_data _U_)
1069 tcp_acked_hash(gconstpointer k)
1071 guint32 frame = GPOINTER_TO_UINT(k);
1076 tcp_acked_equal(gconstpointer k1, gconstpointer k2)
1078 guint32 frame1 = GPOINTER_TO_UINT(k1);
1079 guint32 frame2 = GPOINTER_TO_UINT(k2);
1081 return frame1==frame2;
1085 tcp_analyze_seq_init(void)
1087 /* first destroy the tables */
1088 if( tcp_analyze_acked_table ){
1089 g_hash_table_foreach_remove(tcp_analyze_acked_table,
1090 free_all_acked, NULL);
1091 g_hash_table_destroy(tcp_analyze_acked_table);
1092 tcp_analyze_acked_table = NULL;
1094 if( tcp_pdu_tracking_table ){
1095 g_hash_table_foreach_remove(tcp_pdu_tracking_table,
1096 free_all_acked, NULL);
1097 g_hash_table_destroy(tcp_pdu_tracking_table);
1098 tcp_pdu_tracking_table = NULL;
1100 if( tcp_pdu_skipping_table ){
1101 g_hash_table_foreach_remove(tcp_pdu_skipping_table,
1102 free_all_acked, NULL);
1103 g_hash_table_destroy(tcp_pdu_skipping_table);
1104 tcp_pdu_skipping_table = NULL;
1107 if(tcp_analyze_seq){
1108 tcp_analyze_acked_table = g_hash_table_new(tcp_acked_hash,
1110 tcp_pdu_tracking_table = g_hash_table_new(tcp_acked_hash,
1112 tcp_pdu_skipping_table = g_hash_table_new(tcp_acked_hash,
1118 /* **************************************************************************
1119 * End of tcp sequence number analysis
1120 * **************************************************************************/
1125 /* Minimum TCP header length. */
1126 #define TCPH_MIN_LEN 20
1132 #define TCPOPT_NOP 1 /* Padding */
1133 #define TCPOPT_EOL 0 /* End of options */
1134 #define TCPOPT_MSS 2 /* Segment size negotiating */
1135 #define TCPOPT_WINDOW 3 /* Window scaling */
1136 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
1137 #define TCPOPT_SACK 5 /* SACK Block */
1138 #define TCPOPT_ECHO 6
1139 #define TCPOPT_ECHOREPLY 7
1140 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
1141 #define TCPOPT_CC 11
1142 #define TCPOPT_CCNEW 12
1143 #define TCPOPT_CCECHO 13
1144 #define TCPOPT_MD5 19 /* RFC2385 */
1147 * TCP option lengths
1150 #define TCPOLEN_MSS 4
1151 #define TCPOLEN_WINDOW 3
1152 #define TCPOLEN_SACK_PERM 2
1153 #define TCPOLEN_SACK_MIN 2
1154 #define TCPOLEN_ECHO 6
1155 #define TCPOLEN_ECHOREPLY 6
1156 #define TCPOLEN_TIMESTAMP 10
1157 #define TCPOLEN_CC 6
1158 #define TCPOLEN_CCNEW 6
1159 #define TCPOLEN_CCECHO 6
1160 #define TCPOLEN_MD5 18
1164 /* Desegmentation of TCP streams */
1165 /* table to hold defragmented TCP streams */
1166 static GHashTable *tcp_fragment_table = NULL;
1168 tcp_fragment_init(void)
1170 fragment_table_init(&tcp_fragment_table);
1173 /* functions to trace tcp segments */
1174 /* Enable desegmenting of TCP streams */
1175 static gboolean tcp_desegment = TRUE;
1177 static GHashTable *tcp_segment_table = NULL;
1178 static GMemChunk *tcp_segment_key_chunk = NULL;
1179 static int tcp_segment_init_count = 200;
1180 static GMemChunk *tcp_segment_address_chunk = NULL;
1181 static int tcp_segment_address_init_count = 500;
1183 typedef struct _tcp_segment_key {
1184 /* for own bookkeeping inside packet-tcp.c */
1193 guint32 first_frame;
1197 free_all_segments(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
1199 tcp_segment_key *key = key_arg;
1201 if((key->src)&&(key->src->data)){
1202 g_free((gpointer)key->src->data);
1203 key->src->data=NULL;
1206 if((key->dst)&&(key->dst->data)){
1207 g_free((gpointer)key->dst->data);
1208 key->dst->data=NULL;
1215 tcp_segment_hash(gconstpointer k)
1217 const tcp_segment_key *key = (const tcp_segment_key *)k;
1219 return key->seq+key->sport;
1223 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
1225 const tcp_segment_key *key1 = (const tcp_segment_key *)k1;
1226 const tcp_segment_key *key2 = (const tcp_segment_key *)k2;
1228 return ( ( (key1->seq==key2->seq)
1229 &&(ADDRESSES_EQUAL(key1->src, key2->src))
1230 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
1231 &&(key1->sport==key2->sport)
1232 &&(key1->dport==key2->dport)
1237 tcp_desegment_init(void)
1240 * Free this before freeing any memory chunks; those
1241 * chunks contain data we'll look at in "free_all_segments()".
1243 if(tcp_segment_table){
1244 g_hash_table_foreach_remove(tcp_segment_table,
1245 free_all_segments, NULL);
1246 g_hash_table_destroy(tcp_segment_table);
1247 tcp_segment_table = NULL;
1250 if(tcp_segment_key_chunk){
1251 g_mem_chunk_destroy(tcp_segment_key_chunk);
1252 tcp_segment_key_chunk = NULL;
1254 if(tcp_segment_address_chunk){
1255 g_mem_chunk_destroy(tcp_segment_address_chunk);
1256 tcp_segment_address_chunk = NULL;
1259 /* dont allocate any hash table or memory chunks unless the user
1260 really uses this option
1266 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
1269 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
1270 sizeof(tcp_segment_key),
1271 tcp_segment_init_count*sizeof(tcp_segment_key),
1274 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
1276 tcp_segment_address_init_count*sizeof(address),
1281 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1282 guint32 seq, guint32 nxtseq,
1283 guint32 sport, guint32 dport,
1284 proto_tree *tree, proto_tree *tcp_tree,
1285 struct tcp_analysis *tcpd)
1287 struct tcpinfo *tcpinfo = pinfo->private_data;
1288 fragment_data *ipfd_head=NULL;
1289 tcp_segment_key old_tsk, *tsk;
1290 gboolean must_desegment = FALSE;
1291 gboolean called_dissector = FALSE;
1296 proto_item *frag_tree_item;
1297 proto_item *tcp_tree_item;
1301 * Initialize these to assume no desegmentation.
1302 * If that's not the case, these will be set appropriately
1303 * by the subdissector.
1305 pinfo->desegment_offset = 0;
1306 pinfo->desegment_len = 0;
1309 * Initialize this to assume that this segment will just be
1310 * added to the middle of a desegmented chunk of data, so
1311 * that we should show it all as data.
1312 * If that's not the case, it will be set appropriately.
1314 deseg_offset = offset;
1316 /* First we must check if this TCP segment should be desegmented.
1317 This is only to check if we should desegment this packet,
1318 so we dont spend time doing COPY_ADDRESS/g_free.
1319 We just "borrow" some address structures from pinfo instead. Cheaper.
1321 old_tsk.src = &pinfo->src;
1322 old_tsk.dst = &pinfo->dst;
1323 old_tsk.sport = sport;
1324 old_tsk.dport = dport;
1326 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1329 /* OK, this segment was found, which means it continues
1330 a higher-level PDU. This means we must desegment it.
1331 Add it to the defragmentation lists.
1333 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->first_frame,
1335 seq - tsk->start_seq,
1337 (LT_SEQ (nxtseq,tsk->start_seq + tsk->tot_len)) );
1340 /* fragment_add() returned NULL, This means that
1341 desegmentation is not completed yet.
1342 (its like defragmentation but we know we will
1343 always add the segments in order).
1344 XXX - no, we don't; there is no guarantee that
1345 TCP segments are in order on the wire.
1347 we must add next segment to our table so we will
1350 tcp_segment_key *new_tsk;
1352 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1353 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1354 new_tsk->seq=nxtseq;
1355 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1358 /* This segment was not found in our table, so it doesn't
1359 contain a continuation of a higher-level PDU.
1360 Call the normal subdissector.
1362 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1363 sport, dport, 0, 0, FALSE, tcpd);
1364 called_dissector = TRUE;
1366 /* Did the subdissector ask us to desegment some more data
1367 before it could handle the packet?
1368 If so we have to create some structures in our table but
1369 this is something we only do the first time we see this
1372 if(pinfo->desegment_len) {
1373 if (!pinfo->fd->flags.visited)
1374 must_desegment = TRUE;
1377 * Set "deseg_offset" to the offset in "tvb"
1378 * of the first byte of data that the
1379 * subdissector didn't process.
1381 deseg_offset = offset + pinfo->desegment_offset;
1384 /* Either no desegmentation is necessary, or this is
1385 segment contains the beginning but not the end of
1386 a higher-level PDU and thus isn't completely
1392 /* is it completely desegmented? */
1394 fragment_data *ipfd;
1397 * Yes, we think it is.
1398 * We only call subdissector for the last segment.
1399 * Note that the last segment may include more than what
1402 if(GE_SEQ(nxtseq, tsk->start_seq + tsk->tot_len)){
1404 * OK, this is the last segment.
1405 * Let's call the subdissector with the desegmented
1411 /* create a new TVB structure for desegmented data */
1412 next_tvb = tvb_new_real_data(ipfd_head->data,
1413 ipfd_head->datalen, ipfd_head->datalen);
1415 /* add this tvb as a child to the original one */
1416 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1418 /* add desegmented data to the data source list */
1419 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1422 * Supply the sequence number of the first of the
1423 * reassembled bytes.
1425 tcpinfo->seq = tsk->start_seq;
1427 /* indicate that this is reassembled data */
1428 tcpinfo->is_reassembled = TRUE;
1430 /* call subdissector */
1431 process_tcp_payload(next_tvb, 0, pinfo, tree,
1432 tcp_tree, sport, dport, 0, 0, FALSE, tcpd);
1433 called_dissector = TRUE;
1436 * OK, did the subdissector think it was completely
1437 * desegmented, or does it think we need even more
1440 old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
1441 if(pinfo->desegment_len &&
1442 pinfo->desegment_offset<=old_len){
1443 tcp_segment_key *new_tsk;
1446 * "desegment_len" isn't 0, so it needs more
1447 * data for something - and "desegment_offset"
1448 * is before "old_len", so it needs more data
1449 * to dissect the stuff we thought was
1450 * completely desegmented (as opposed to the
1451 * stuff at the beginning being completely
1452 * desegmented, but the stuff at the end
1453 * being a new higher-level PDU that also
1454 * needs desegmentation).
1456 fragment_set_partial_reassembly(pinfo,tsk->first_frame,tcp_fragment_table);
1457 tsk->tot_len = tvb_reported_length(next_tvb) + pinfo->desegment_len;
1460 * Update tsk structure.
1461 * Can ask ->next->next because at least there's a hdr and one
1462 * entry in fragment_add()
1464 for(ipfd=ipfd_head->next; ipfd->next; ipfd=ipfd->next){
1465 old_tsk.seq = tsk->start_seq + ipfd->offset;
1466 new_tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1467 new_tsk->tot_len = tsk->tot_len;
1470 /* this is the next segment in the sequence we want */
1471 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1472 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1473 new_tsk->seq = nxtseq;
1474 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1477 * Show the stuff in this TCP segment as
1478 * just raw TCP segment data.
1481 tvb_reported_length_remaining(tvb, offset);
1482 proto_tree_add_text(tcp_tree, tvb, offset, -1,
1483 "TCP segment data (%u byte%s)", nbytes,
1484 plurality(nbytes, "", "s"));
1487 * The subdissector thought it was completely
1488 * desegmented (although the stuff at the
1489 * end may, in turn, require desegmentation),
1490 * so we show a tree with all segments.
1492 show_fragment_tree(ipfd_head, &tcp_segment_items,
1493 tree, pinfo, next_tvb, &frag_tree_item);
1495 * The toplevel fragment subtree is now
1496 * behind all desegmented data; move it
1497 * right behind the TCP tree.
1499 tcp_tree_item = proto_tree_get_parent(tcp_tree);
1500 if(frag_tree_item && tcp_tree_item) {
1501 proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1504 /* Did the subdissector ask us to desegment
1505 some more data? This means that the data
1506 at the beginning of this segment completed
1507 a higher-level PDU, but the data at the
1508 end of this segment started a higher-level
1509 PDU but didn't complete it.
1511 If so, we have to create some structures
1512 in our table, but this is something we
1513 only do the first time we see this packet.
1515 if(pinfo->desegment_len) {
1516 if (!pinfo->fd->flags.visited)
1517 must_desegment = TRUE;
1519 /* The stuff we couldn't dissect
1520 must have come from this segment,
1521 so it's all in "tvb".
1523 "pinfo->desegment_offset" is
1524 relative to the beginning of
1525 "next_tvb"; we want an offset
1526 relative to the beginning of "tvb".
1528 First, compute the offset relative
1529 to the *end* of "next_tvb" - i.e.,
1530 the number of bytes before the end
1531 of "next_tvb" at which the
1532 subdissector stopped. That's the
1533 length of "next_tvb" minus the
1534 offset, relative to the beginning
1535 of "next_tvb, at which the
1536 subdissector stopped.
1539 ipfd_head->datalen - pinfo->desegment_offset;
1541 /* "tvb" and "next_tvb" end at the
1542 same byte of data, so the offset
1543 relative to the end of "next_tvb"
1544 of the byte at which we stopped
1545 is also the offset relative to
1546 the end of "tvb" of the byte at
1549 Convert that back into an offset
1550 relative to the beginninng of
1551 "tvb", by taking the length of
1552 "tvb" and subtracting the offset
1553 relative to the end.
1555 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1561 if (must_desegment) {
1562 tcp_segment_key *tsk, *new_tsk;
1565 * The sequence number at which the stuff to be desegmented
1566 * starts is the sequence number of the byte at an offset
1567 * of "deseg_offset" into "tvb".
1569 * The sequence number of the byte at an offset of "offset"
1570 * is "seq", i.e. the starting sequence number of this
1571 * segment, so the sequence number of the byte at
1572 * "deseg_offset" is "seq + (deseg_offset - offset)".
1574 deseg_seq = seq + (deseg_offset - offset);
1577 * XXX - how do we detect out-of-order transmissions?
1578 * We can't just check for "nxtseq" being greater than
1579 * "tsk->start_seq"; for now, we check for the difference
1580 * being less than a megabyte, but this is a really
1581 * gross hack - we really need to handle out-of-order
1582 * transmissions correctly.
1584 if ((nxtseq - deseg_seq) <= 1024*1024) {
1585 /* OK, subdissector wants us to desegment
1586 some data before it can process it. Add
1587 what remains of this packet and set
1588 up next packet/sequence number as well.
1590 We must remember this segment
1592 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1593 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
1594 COPY_ADDRESS(tsk->src, &pinfo->src);
1595 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
1596 COPY_ADDRESS(tsk->dst, &pinfo->dst);
1597 tsk->seq = deseg_seq;
1598 tsk->start_seq = tsk->seq;
1599 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
1600 tsk->first_frame = pinfo->fd->num;
1603 g_hash_table_insert(tcp_segment_table, tsk, tsk);
1605 /* Add portion of segment unprocessed by the subdissector
1606 to defragmentation lists */
1607 fragment_add(tvb, deseg_offset, pinfo, tsk->first_frame,
1609 tsk->seq - tsk->start_seq,
1610 nxtseq - tsk->start_seq,
1611 LT_SEQ (nxtseq, tsk->start_seq + tsk->tot_len));
1613 /* this is the next segment in the sequence we want */
1614 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1615 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1616 new_tsk->seq = nxtseq;
1617 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1621 if (!called_dissector || pinfo->desegment_len != 0) {
1622 if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
1623 !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
1625 * We know what frame this PDU is reassembled in;
1626 * let the user know.
1628 item=proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in,
1629 tvb, 0, 0, ipfd_head->reassembled_in);
1630 PROTO_ITEM_SET_GENERATED(item);
1634 * Either we didn't call the subdissector at all (i.e.,
1635 * this is a segment that contains the middle of a
1636 * higher-level PDU, but contains neither the beginning
1637 * nor the end), or the subdissector couldn't dissect it
1638 * all, as some data was missing (i.e., it set
1639 * "pinfo->desegment_len" to the amount of additional
1642 if (pinfo->desegment_offset == 0) {
1644 * It couldn't, in fact, dissect any of it (the
1645 * first byte it couldn't dissect is at an offset
1646 * of "pinfo->desegment_offset" from the beginning
1647 * of the payload, and that's 0).
1648 * Just mark this as TCP.
1650 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1651 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1653 if (check_col(pinfo->cinfo, COL_INFO)){
1654 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
1659 * Show what's left in the packet as just raw TCP segment
1661 * XXX - remember what protocol the last subdissector
1662 * was, and report it as a continuation of that, instead?
1664 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
1665 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
1666 "TCP segment data (%u byte%s)", nbytes,
1667 plurality(nbytes, "", "s"));
1669 pinfo->can_desegment=0;
1670 pinfo->desegment_offset = 0;
1671 pinfo->desegment_len = 0;
1675 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
1676 * consists of a fixed-length chunk of data that contains enough information
1677 * to determine the length of the PDU, followed by rest of the PDU.
1679 * The first three arguments are the arguments passed to the dissector
1680 * that calls this routine.
1682 * "proto_desegment" is the dissector's flag controlling whether it should
1683 * desegment PDUs that cross TCP segment boundaries.
1685 * "fixed_len" is the length of the fixed-length part of the PDU.
1687 * "get_pdu_len()" is a routine called to get the length of the PDU from
1688 * the fixed-length part of the PDU; it's passed "tvb" and "offset".
1690 * "dissect_pdu()" is the routine to dissect a PDU.
1693 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1694 gboolean proto_desegment, guint fixed_len,
1695 guint (*get_pdu_len)(tvbuff_t *, int),
1696 dissector_t dissect_pdu)
1698 volatile int offset = 0;
1700 guint length_remaining;
1705 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1707 * We use "tvb_ensure_length_remaining()" to make sure there actually
1708 * *is* data remaining. The protocol we're handling could conceivably
1709 * consists of a sequence of fixed-length PDUs, and therefore the
1710 * "get_pdu_len" routine might not actually fetch anything from
1711 * the tvbuff, and thus might not cause an exception to be thrown if
1712 * we've run past the end of the tvbuff.
1714 * This means we're guaranteed that "length_remaining" is positive.
1716 length_remaining = tvb_ensure_length_remaining(tvb, offset);
1719 * Can we do reassembly?
1721 if (proto_desegment && pinfo->can_desegment) {
1723 * Yes - is the fixed-length part of the PDU split across segment
1726 if (length_remaining < fixed_len) {
1728 * Yes. Tell the TCP dissector where the data for this message
1729 * starts in the data it handed us, and how many more bytes we
1732 pinfo->desegment_offset = offset;
1733 pinfo->desegment_len = fixed_len - length_remaining;
1739 * Get the length of the PDU.
1741 plen = (*get_pdu_len)(tvb, offset);
1742 if (plen < fixed_len) {
1744 * The PDU length from the fixed-length portion probably didn't
1745 * include the fixed-length portion's length, and was probably so
1746 * large that the total length overflowed.
1748 * Report this as an error.
1750 show_reported_bounds_error(tvb, pinfo, tree);
1754 /* give a hint to TCP where the next PDU starts
1755 * so that it can attempt to find it in case it starts
1756 * somewhere in the middle of a segment.
1758 if(!pinfo->fd->flags.visited && tcp_analyze_seq){
1759 guint remaining_bytes;
1760 remaining_bytes=tvb_reported_length_remaining(tvb, offset);
1761 if(plen>remaining_bytes){
1762 pinfo->want_pdu_tracking=2;
1763 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
1768 * Can we do reassembly?
1770 if (proto_desegment && pinfo->can_desegment) {
1772 * Yes - is the PDU split across segment boundaries?
1774 if (length_remaining < plen) {
1776 * Yes. Tell the TCP dissector where the data for this message
1777 * starts in the data it handed us, and how many more bytes we
1780 pinfo->desegment_offset = offset;
1781 pinfo->desegment_len = plen - length_remaining;
1787 * Construct a tvbuff containing the amount of the payload we have
1788 * available. Make its reported length the amount of data in the PDU.
1790 * XXX - if reassembly isn't enabled. the subdissector will throw a
1791 * BoundsError exception, rather than a ReportedBoundsError exception.
1792 * We really want a tvbuff where the length is "length", the reported
1793 * length is "plen", and the "if the snapshot length were infinite"
1794 * length is the minimum of the reported length of the tvbuff handed
1795 * to us and "plen", with a new type of exception thrown if the offset
1796 * is within the reported length but beyond that third length, with
1797 * that exception getting the "Unreassembled Packet" error.
1799 length = length_remaining;
1802 next_tvb = tvb_new_subset(tvb, offset, length, plen);
1807 * Catch the ReportedBoundsError exception; if this particular message
1808 * happens to get a ReportedBoundsError exception, that doesn't mean
1809 * that we should stop dissecting PDUs within this frame or chunk of
1812 * If it gets a BoundsError, we can stop, as there's nothing more to
1813 * see, so we just re-throw it.
1816 (*dissect_pdu)(next_tvb, pinfo, tree);
1818 CATCH(BoundsError) {
1821 CATCH(ReportedBoundsError) {
1822 show_reported_bounds_error(tvb, pinfo, tree);
1827 * Step to the next PDU.
1828 * Make sure we don't overflow.
1830 offset_before = offset;
1832 if (offset <= offset_before)
1838 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
1840 if (check_col(pinfo->cinfo, COL_INFO))
1841 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
1845 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
1846 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1850 mss = tvb_get_ntohs(tvb, offset + 2);
1851 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_mss, tvb, offset,
1853 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
1854 optlen, mss, "%s: %u bytes", optp->name, mss);
1855 tcp_info_append_uint(pinfo, "MSS", mss);
1859 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
1860 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1863 struct tcp_analysis *tcpd=NULL;
1865 tcpd=get_tcp_conversation_data(pinfo);
1867 ws = tvb_get_guint8(tvb, offset + 2);
1868 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_wscale, tvb,
1869 offset, optlen, TRUE);
1870 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
1871 offset, optlen, ws, "%s: %u (multiply by %u)",
1872 optp->name, ws, 1 << ws);
1873 tcp_info_append_uint(pinfo, "WS", ws);
1874 if(!pinfo->fd->flags.visited && tcp_analyze_seq && tcp_relative_seq){
1875 pdu_store_window_scale_option(ws, tcpd);
1880 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
1881 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1883 proto_tree *field_tree = NULL;
1884 proto_item *tf=NULL;
1885 guint32 leftedge, rightedge;
1886 struct tcp_analysis *tcpd=NULL;
1889 if(tcp_analyze_seq && tcp_relative_seq){
1890 /* find(or create if needed) the conversation for this tcp session */
1891 tcpd=get_tcp_conversation_data(pinfo);
1893 base_ack=tcpd->rev->base_seq;
1896 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
1897 offset += 2; /* skip past type and length */
1898 optlen -= 2; /* subtract size of type and length */
1899 while (optlen > 0) {
1900 if (field_tree == NULL) {
1901 /* Haven't yet made a subtree out of this option. Do so. */
1902 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1903 proto_tree_add_boolean_hidden(field_tree, hf_tcp_option_sack, tvb,
1904 offset, optlen, TRUE);
1907 proto_tree_add_text(field_tree, tvb, offset, optlen,
1908 "(suboption would go past end of option)");
1911 leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
1912 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
1913 offset, 4, leftedge,
1914 "left edge = %u%s", leftedge,
1915 tcp_relative_seq ? " (relative)" : "");
1919 proto_tree_add_text(field_tree, tvb, offset, optlen,
1920 "(suboption would go past end of option)");
1923 /* XXX - check whether it goes past end of packet */
1924 rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
1926 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
1927 offset+4, 4, rightedge,
1928 "right edge = %u%s", rightedge,
1929 tcp_relative_seq ? " (relative)" : "");
1930 tcp_info_append_uint(pinfo, "SLE", leftedge);
1931 tcp_info_append_uint(pinfo, "SRE", rightedge);
1932 proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
1938 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
1939 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1943 echo = tvb_get_ntohl(tvb, offset + 2);
1944 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_echo, tvb, offset,
1946 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1947 "%s: %u", optp->name, echo);
1948 tcp_info_append_uint(pinfo, "ECHO", echo);
1952 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
1953 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1957 tsv = tvb_get_ntohl(tvb, offset + 2);
1958 tser = tvb_get_ntohl(tvb, offset + 6);
1959 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_time_stamp, tvb,
1960 offset, optlen, TRUE);
1961 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1962 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
1963 tcp_info_append_uint(pinfo, "TSV", tsv);
1964 tcp_info_append_uint(pinfo, "TSER", tser);
1968 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
1969 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1973 cc = tvb_get_ntohl(tvb, offset + 2);
1974 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_cc, tvb, offset,
1976 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1977 "%s: %u", optp->name, cc);
1978 tcp_info_append_uint(pinfo, "CC", cc);
1981 static const ip_tcp_opt tcpopts[] = {
2000 "Maximum segment size",
2004 dissect_tcpopt_maxseg
2012 dissect_tcpopt_wscale
2025 &ett_tcp_option_sack,
2052 dissect_tcpopt_timestamp
2080 "TCP MD5 signature",
2088 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
2090 /* Determine if there is a sub-dissector and call it; return TRUE
2091 if there was a sub-dissector, FALSE otherwise.
2093 This has been separated into a stand alone routine to other protocol
2094 dissectors can call to it, e.g., SOCKS. */
2096 static gboolean try_heuristic_first = FALSE;
2099 /* this function can be called with tcpd==NULL as from the msproxy dissector */
2101 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
2102 proto_tree *tree, int src_port, int dst_port,
2103 struct tcp_analysis *tcpd)
2106 int low_port, high_port;
2108 /* dont call subdissectors for keepalive or zerowindowprobes
2109 * eventhough tehy do contain payload "data"
2110 * keeaplives just contain garbage and zwp contain too little data (1 byte)
2113 if(tcpd && tcpd->ta){
2114 if(tcpd->ta->flags&(TCP_A_ZERO_WINDOW_PROBE|TCP_A_KEEP_ALIVE)){
2119 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2121 /* determine if this packet is part of a conversation and call dissector */
2122 /* for the conversation if available */
2124 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
2125 src_port, dst_port, next_tvb, pinfo, tree)){
2126 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2130 if (try_heuristic_first) {
2131 /* do lookup with the heuristic subdissector table */
2132 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2133 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2138 /* Do lookups with the subdissector table.
2139 We try the port number with the lower value first, followed by the
2140 port number with the higher value. This means that, for packets
2141 where a dissector is registered for *both* port numbers:
2143 1) we pick the same dissector for traffic going in both directions;
2145 2) we prefer the port number that's more likely to be the right
2146 one (as that prefers well-known ports to reserved ports);
2148 although there is, of course, no guarantee that any such strategy
2149 will always pick the right port number.
2151 XXX - we ignore port numbers of 0, as some dissectors use a port
2152 number of 0 to disable the port. */
2153 if (src_port > dst_port) {
2154 low_port = dst_port;
2155 high_port = src_port;
2157 low_port = src_port;
2158 high_port = dst_port;
2160 if (low_port != 0 &&
2161 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree)){
2162 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2165 if (high_port != 0 &&
2166 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree)){
2167 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2171 if (!try_heuristic_first) {
2172 /* do lookup with the heuristic subdissector table */
2173 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2174 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2179 /* Oh, well, we don't know this; dissect it as data. */
2180 call_dissector(data_handle,next_tvb, pinfo, tree);
2182 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2187 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
2188 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
2189 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
2190 struct tcp_analysis *tcpd)
2192 pinfo->want_pdu_tracking=0;
2196 /*qqq see if it is an unaligned PDU */
2197 if(tcp_analyze_seq && (!tcp_desegment)){
2199 offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
2204 /* if offset is -1 this means that this segment is known
2205 * to be fully inside a previously detected pdu
2206 * so we dont even need to try to dissect it either.
2209 decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
2212 * We succeeded in handing off to a subdissector.
2214 * Is this a TCP segment or a reassembled chunk of
2218 /* if !visited, check want_pdu_tracking and
2219 store it in table */
2220 if((!pinfo->fd->flags.visited) &&
2221 tcp_analyze_seq && pinfo->want_pdu_tracking){
2223 pdu_store_sequencenumber_of_next_pdu(
2226 nxtseq+pinfo->bytes_until_next_pdu,
2234 /* We got an exception. At this point the dissection is
2235 * completely aborted and execution will be transfered back
2236 * to (probably) the frame dissector.
2237 * Here we have to place whatever we want the dissector
2238 * to do before aborting the tcp dissection.
2241 * Is this a TCP segment or a reassembled chunk of TCP
2246 * It's from a TCP segment.
2248 * if !visited, check want_pdu_tracking and store it
2251 if((!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking){
2253 pdu_store_sequencenumber_of_next_pdu(pinfo,
2255 nxtseq+pinfo->bytes_until_next_pdu,
2266 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
2267 guint32 nxtseq, guint32 sport, guint32 dport,
2268 proto_tree *tree, proto_tree *tcp_tree,
2269 struct tcp_analysis *tcpd)
2271 gboolean save_fragmented;
2273 /* Can we desegment this segment? */
2274 if (pinfo->can_desegment) {
2276 desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
2279 /* No - just call the subdissector.
2280 Mark this as fragmented, so if somebody throws an exception,
2281 we don't report it as a malformed frame. */
2282 save_fragmented = pinfo->fragmented;
2283 pinfo->fragmented = TRUE;
2284 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
2285 seq, nxtseq, TRUE, tcpd);
2286 pinfo->fragmented = save_fragmented;
2291 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2293 guint8 th_off_x2; /* combines th_off and th_x2 */
2296 proto_tree *tcp_tree = NULL, *field_tree = NULL;
2297 proto_item *ti = NULL, *tf;
2299 gchar *flags = "<None>";
2300 const gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
2301 size_t fpos = 0, returned_length;
2309 guint16 computed_cksum;
2310 guint16 real_window;
2311 guint length_remaining;
2312 gboolean desegment_ok;
2313 struct tcpinfo tcpinfo;
2314 static struct tcpheader tcphstruct[4], *tcph;
2315 static int tcph_count=0;
2316 proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
2317 struct tcp_analysis *tcpd=NULL;
2323 tcph=&tcphstruct[tcph_count];
2324 SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
2325 SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
2327 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2328 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2330 /* Clear out the Info column. */
2331 if (check_col(pinfo->cinfo, COL_INFO))
2332 col_clear(pinfo->cinfo, COL_INFO);
2334 tcph->th_sport = tvb_get_ntohs(tvb, offset);
2335 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
2336 if (check_col(pinfo->cinfo, COL_INFO)) {
2337 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
2338 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2341 if (tcp_summary_in_tree) {
2342 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
2343 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
2344 get_tcp_port(tcph->th_sport), tcph->th_sport,
2345 get_tcp_port(tcph->th_dport), tcph->th_dport);
2348 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
2350 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
2351 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
2352 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
2353 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
2354 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
2355 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
2356 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
2359 /* Set the source and destination port numbers as soon as we get them,
2360 so that they're available to the "Follow TCP Stream" code even if
2361 we throw an exception dissecting the rest of the TCP header. */
2362 pinfo->ptype = PT_TCP;
2363 pinfo->srcport = tcph->th_sport;
2364 pinfo->destport = tcph->th_dport;
2366 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
2367 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
2368 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
2369 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
2370 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
2371 real_window = tcph->th_win;
2372 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
2374 /* find(or create if needed) the conversation for this tcp session */
2375 tcpd=get_tcp_conversation_data(pinfo);
2378 * If we've been handed an IP fragment, we don't know how big the TCP
2379 * segment is, so don't do anything that requires that we know that.
2381 * The same applies if we're part of an error packet. (XXX - if the
2382 * ICMP and ICMPv6 dissectors could set a "this is how big the IP
2383 * header says it is" length in the tvbuff, we could use that; such
2384 * a length might also be useful for handling packets where the IP
2385 * length is bigger than the actual data available in the frame; the
2386 * dissectors should trust that length, and then throw a
2387 * ReportedBoundsError exception when they go past the end of the frame.)
2389 * We also can't determine the segment length if the reported length
2390 * of the TCP packet is less than the TCP header length.
2392 reported_len = tvb_reported_length(tvb);
2394 if (!pinfo->fragmented && !pinfo->in_error_pkt) {
2395 if (reported_len < tcph->th_hlen) {
2396 proto_tree_add_text(tcp_tree, tvb, offset, 0,
2397 "Short segment. Segment/fragment does not contain a full TCP header"
2398 " (might be NMAP or someone else deliberately sending unusual packets)");
2399 tcph->th_have_seglen = FALSE;
2401 /* Compute the length of data in this segment. */
2402 tcph->th_seglen = reported_len - tcph->th_hlen;
2403 tcph->th_have_seglen = TRUE;
2405 if (tree) { /* Add the seglen as an invisible field */
2407 proto_tree_add_uint_hidden(ti, hf_tcp_len, tvb, offset, 4, tcph->th_seglen);
2412 /* handle TCP seq# analysis parse all new segments we see */
2413 if(tcp_analyze_seq){
2414 if(!(pinfo->fd->flags.visited)){
2415 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
2417 if(tcp_relative_seq){
2418 tcp_get_relative_seq_ack(&(tcph->th_seq), &(tcph->th_ack), &(tcph->th_win), tcpd);
2422 /* Compute the sequence number of next octet after this segment. */
2423 nxtseq = tcph->th_seq + tcph->th_seglen;
2426 tcph->th_have_seglen = FALSE;
2428 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
2429 #define MAX_FLAGS_LEN 64
2430 flags=ep_alloc(MAX_FLAGS_LEN);
2432 for (i = 0; i < 8; i++) {
2434 if (tcph->th_flags & bpos) {
2435 returned_length = g_snprintf(&flags[fpos], MAX_FLAGS_LEN-fpos, "%s%s",
2438 fpos += MIN(returned_length, MAX_FLAGS_LEN-fpos);
2443 if (check_col(pinfo->cinfo, COL_INFO)) {
2444 if(tcph->th_flags&TH_ACK){
2445 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
2446 flags, tcph->th_seq, tcph->th_ack, tcph->th_win);
2448 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u",
2449 flags, tcph->th_seq);
2454 if (tcp_summary_in_tree) {
2455 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
2457 if(tcp_relative_seq){
2458 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);
2460 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
2464 if (tcph->th_hlen < TCPH_MIN_LEN) {
2465 /* Give up at this point; we put the source and destination port in
2466 the tree, before fetching the header length, so that they'll
2467 show up if this is in the failing packet in an ICMP error packet,
2468 but it's now time to give up if the header length is bogus. */
2469 if (check_col(pinfo->cinfo, COL_INFO))
2470 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
2471 tcph->th_hlen, TCPH_MIN_LEN);
2473 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2474 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
2481 if (tcp_summary_in_tree) {
2482 if(tcph->th_flags&TH_ACK){
2483 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
2485 if (tcph->th_have_seglen)
2486 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
2488 proto_item_set_len(ti, tcph->th_hlen);
2489 if (tcph->th_have_seglen) {
2490 if (nxtseq != tcph->th_seq) {
2491 if(tcp_relative_seq){
2492 tf=proto_tree_add_uint_format(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "Next sequence number: %u (relative sequence number)", nxtseq);
2494 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
2496 PROTO_ITEM_SET_GENERATED(tf);
2499 if (tcph->th_flags & TH_ACK) {
2500 if(tcp_relative_seq){
2501 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);
2503 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
2506 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2507 "Header length: %u bytes", tcph->th_hlen);
2508 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
2509 tcph->th_flags, "Flags: 0x%04x (%s)", tcph->th_flags, flags);
2510 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
2511 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
2512 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
2513 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
2514 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
2515 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
2516 tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
2517 tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
2518 tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
2519 if(tcp_relative_seq && (tcph->th_win!=real_window)){
2520 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);
2522 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
2526 if(tcph->th_flags & TH_SYN) {
2527 if(tcph->th_flags & TH_ACK)
2528 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): %s -> %s",
2529 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2531 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): %s -> %s",
2532 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2534 if(tcph->th_flags & TH_FIN)
2535 expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN): %s -> %s",
2536 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2537 if(tcph->th_flags & TH_RST)
2538 expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST): %s -> %s",
2539 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2541 /* Supply the sequence number of the first byte and of the first byte
2542 after the segment. */
2543 tcpinfo.seq = tcph->th_seq;
2544 tcpinfo.nxtseq = nxtseq;
2546 /* Assume we'll pass un-reassembled data to subdissectors. */
2547 tcpinfo.is_reassembled = FALSE;
2549 pinfo->private_data = &tcpinfo;
2552 * Assume, initially, that we can't desegment.
2554 pinfo->can_desegment = 0;
2555 th_sum = tvb_get_ntohs(tvb, offset + 16);
2556 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
2557 /* The packet isn't part of an un-reassembled fragmented datagram
2558 and isn't truncated. This means we have all the data, and thus
2559 can checksum it and, unless it's being returned in an error
2560 packet, are willing to allow subdissectors to request reassembly
2563 if (tcp_check_checksum) {
2564 /* We haven't turned checksum checking off; checksum it. */
2566 /* Set up the fields of the pseudo-header. */
2567 cksum_vec[0].ptr = pinfo->src.data;
2568 cksum_vec[0].len = pinfo->src.len;
2569 cksum_vec[1].ptr = pinfo->dst.data;
2570 cksum_vec[1].len = pinfo->dst.len;
2571 cksum_vec[2].ptr = (const guint8 *)&phdr;
2572 switch (pinfo->src.type) {
2575 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
2576 cksum_vec[2].len = 4;
2580 phdr[0] = g_htonl(reported_len);
2581 phdr[1] = g_htonl(IP_PROTO_TCP);
2582 cksum_vec[2].len = 8;
2586 /* TCP runs only atop IPv4 and IPv6.... */
2587 DISSECTOR_ASSERT_NOT_REACHED();
2590 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
2591 cksum_vec[3].len = reported_len;
2592 computed_cksum = in_cksum(&cksum_vec[0], 4);
2593 if (computed_cksum == 0) {
2594 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2595 offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
2597 /* Checksum is valid, so we're willing to desegment it. */
2598 desegment_ok = TRUE;
2602 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2603 offset + 16, 2, th_sum,
2604 "Checksum: 0x%04x [incorrect, should be 0x%04x]", th_sum,
2605 in_cksum_shouldbe(th_sum, computed_cksum));
2606 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
2607 item = proto_tree_add_boolean(tcp_tree, hf_tcp_checksum_bad, tvb,
2608 offset + 16, 2, TRUE);
2609 PROTO_ITEM_SET_GENERATED(item);
2610 /* XXX - don't use hidden fields for checksums */
2611 PROTO_ITEM_SET_HIDDEN(item);
2613 if (check_col(pinfo->cinfo, COL_INFO))
2614 col_append_fstr(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
2616 /* Checksum is invalid, so we're not willing to desegment it. */
2617 desegment_ok = FALSE;
2618 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
2621 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2622 offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
2624 /* We didn't check the checksum, and don't care if it's valid,
2625 so we're willing to desegment it. */
2626 desegment_ok = TRUE;
2629 /* We don't have all the packet data, so we can't checksum it... */
2630 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2631 offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
2633 /* ...and aren't willing to desegment it. */
2634 desegment_ok = FALSE;
2638 /* We're willing to desegment this. Is desegmentation enabled? */
2639 if (tcp_desegment) {
2640 /* Yes - is this segment being returned in an error packet? */
2641 if (!pinfo->in_error_pkt) {
2642 /* No - indicate that we will desegment.
2643 We do NOT want to desegment segments returned in error
2644 packets, as they're not part of a TCP connection. */
2645 pinfo->can_desegment = 2;
2650 if (tcph->th_flags & TH_URG) {
2651 th_urp = tvb_get_ntohs(tvb, offset + 18);
2652 /* Export the urgent pointer, for the benefit of protocols such as
2654 tcpinfo.urgent = TRUE;
2655 tcpinfo.urgent_pointer = th_urp;
2656 if (check_col(pinfo->cinfo, COL_INFO))
2657 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
2658 if (tcp_tree != NULL)
2659 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
2661 tcpinfo.urgent = FALSE;
2663 if (tcph->th_have_seglen) {
2664 if (check_col(pinfo->cinfo, COL_INFO))
2665 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
2668 /* Decode TCP options, if any. */
2669 if (tcph->th_hlen > TCPH_MIN_LEN) {
2670 /* There's more than just the fixed-length header. Decode the
2672 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
2673 tvb_ensure_bytes_exist(tvb, offset + 20, optlen);
2674 if (tcp_tree != NULL) {
2675 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
2676 "Options: (%u bytes)", optlen);
2677 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
2680 dissect_ip_tcp_options(tvb, offset + 20, optlen,
2681 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
2684 /* If there was window scaling in the SYN packet but none in the SYN+ACK
2685 * then we should just forget about the windowscaling completely.
2687 if(!pinfo->fd->flags.visited){
2688 if(tcp_analyze_seq && tcp_relative_seq){
2689 if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
2690 verify_tcp_window_scaling(tcpd);
2695 /* Skip over header + options */
2696 offset += tcph->th_hlen;
2698 /* Check the packet length to see if there's more data
2699 (it could be an ACK-only packet) */
2700 length_remaining = tvb_length_remaining(tvb, offset);
2702 if (tcph->th_have_seglen) {
2703 if( data_out_file ) {
2704 reassemble_tcp( tcph->th_seq, /* sequence number */
2705 tcph->th_seglen, /* data length */
2706 tvb_get_ptr(tvb, offset, length_remaining), /* data */
2707 length_remaining, /* captured data length */
2708 ( tcph->th_flags & TH_SYN ), /* is syn set? */
2716 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
2717 if(tcp_analyze_seq){
2718 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd);
2720 tap_queue_packet(tcp_tap, pinfo, tcph);
2723 * XXX - what, if any, of this should we do if this is included in an
2724 * error packet? It might be nice to see the details of the packet
2725 * that caused the ICMP error, but it might not be nice to have the
2726 * dissector update state based on it.
2727 * Also, we probably don't want to run TCP taps on those packets.
2729 if (length_remaining != 0) {
2730 if (tcph->th_flags & TH_RST) {
2734 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
2736 * A TCP SHOULD allow a received RST segment to include data.
2739 * It has been suggested that a RST segment could contain
2740 * ASCII text that encoded and explained the cause of the
2741 * RST. No standard has yet been established for such
2744 * so for segments with RST we just display the data as text.
2746 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
2748 tvb_format_text(tvb, offset, length_remaining));
2750 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
2751 tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd);
2757 proto_register_tcp(void)
2759 static hf_register_info hf[] = {
2762 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
2766 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
2770 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
2774 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
2778 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
2782 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
2786 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2790 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2793 { &hf_tcp_flags_cwr,
2794 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
2797 { &hf_tcp_flags_ecn,
2798 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
2801 { &hf_tcp_flags_urg,
2802 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
2805 { &hf_tcp_flags_ack,
2806 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
2809 { &hf_tcp_flags_push,
2810 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
2813 { &hf_tcp_flags_reset,
2814 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
2817 { &hf_tcp_flags_syn,
2818 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
2821 { &hf_tcp_flags_fin,
2822 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
2825 /* 32 bits so we can present some values adjusted to window scaling */
2826 { &hf_tcp_window_size,
2827 { "Window size", "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
2831 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
2834 { &hf_tcp_checksum_bad,
2835 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2838 { &hf_tcp_analysis_flags,
2839 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
2840 "This frame has some of the TCP analysis flags set", HFILL }},
2842 { &hf_tcp_analysis_retransmission,
2843 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2844 "This frame is a suspected TCP retransmission", HFILL }},
2846 { &hf_tcp_analysis_fast_retransmission,
2847 { "Fast Retransmission", "tcp.analysis.fast_retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2848 "This frame is a suspected TCP fast retransmission", HFILL }},
2850 { &hf_tcp_analysis_out_of_order,
2851 { "Out Of Order", "tcp.analysis.out_of_order", FT_NONE, BASE_NONE, NULL, 0x0,
2852 "This frame is a suspected Out-Of-Order segment", HFILL }},
2854 { &hf_tcp_analysis_lost_packet,
2855 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2856 "A segment before this one was lost from the capture", HFILL }},
2858 { &hf_tcp_analysis_ack_lost_packet,
2859 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2860 "This frame ACKs a lost segment", HFILL }},
2862 { &hf_tcp_analysis_window_update,
2863 { "Window update", "tcp.analysis.window_update", FT_NONE, BASE_NONE, NULL, 0x0,
2864 "This frame is a tcp window update", HFILL }},
2866 { &hf_tcp_analysis_window_full,
2867 { "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
2868 "This segment has caused the allowed window to become 100% full", HFILL }},
2870 { &hf_tcp_analysis_keep_alive,
2871 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
2872 "This is a keep-alive segment", HFILL }},
2874 { &hf_tcp_analysis_keep_alive_ack,
2875 { "Keep Alive ACK", "tcp.analysis.keep_alive_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2876 "This is an ACK to a keep-alive segment", HFILL }},
2878 { &hf_tcp_analysis_duplicate_ack,
2879 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2880 "This is a duplicate ACK", HFILL }},
2882 { &hf_tcp_analysis_duplicate_ack_num,
2883 { "Duplicate ACK #", "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
2884 "This is duplicate ACK number #", HFILL }},
2886 { &hf_tcp_analysis_duplicate_ack_frame,
2887 { "Duplicate to the ACK in frame", "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2888 "This is a duplicate to the ACK in frame #", HFILL }},
2890 { &hf_tcp_continuation_to,
2891 { "This is a continuation to the PDU in frame", "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2892 "This is a continuation to the PDU in frame #", HFILL }},
2894 { &hf_tcp_analysis_zero_window_probe,
2895 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
2896 "This is a zero-window-probe", HFILL }},
2898 { &hf_tcp_analysis_zero_window_probe_ack,
2899 { "Zero Window Probe Ack", "tcp.analysis.zero_window_probe_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2900 "This is an ACK to a zero-window-probe", HFILL }},
2902 { &hf_tcp_analysis_zero_window,
2903 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
2904 "This is a zero-window", HFILL }},
2907 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
2910 { &hf_tcp_analysis_acks_frame,
2911 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2912 "Which previous segment is this an ACK for", HFILL}},
2914 { &hf_tcp_analysis_ack_rtt,
2915 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2916 "How long time it took to ACK the segment (RTT)", HFILL}},
2918 { &hf_tcp_analysis_rto,
2919 { "The RTO for this segment was", "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2920 "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
2922 { &hf_tcp_analysis_rto_frame,
2923 { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2924 "This is the frame we measure the RTO from", HFILL }},
2926 { &hf_tcp_urgent_pointer,
2927 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
2930 { &hf_tcp_segment_overlap,
2931 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2932 "Segment overlaps with other segments", HFILL }},
2934 { &hf_tcp_segment_overlap_conflict,
2935 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2936 "Overlapping segments contained conflicting data", HFILL }},
2938 { &hf_tcp_segment_multiple_tails,
2939 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2940 "Several tails were found when reassembling the pdu", HFILL }},
2942 { &hf_tcp_segment_too_long_fragment,
2943 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2944 "Segment contained data past end of the pdu", HFILL }},
2946 { &hf_tcp_segment_error,
2947 { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2948 "Reassembling error due to illegal segments", HFILL }},
2951 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2952 "TCP Segment", HFILL }},
2955 { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
2956 "TCP Segments", HFILL }},
2958 { &hf_tcp_reassembled_in,
2959 { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2960 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
2962 { &hf_tcp_option_mss,
2963 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
2964 BASE_NONE, NULL, 0x0, "TCP MSS Option", HFILL }},
2966 { &hf_tcp_option_mss_val,
2967 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
2968 BASE_DEC, NULL, 0x0, "TCP MSS Option Value", HFILL}},
2970 { &hf_tcp_option_wscale,
2971 { "TCP Window Scale Option", "tcp.options.wscale",
2973 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
2975 { &hf_tcp_option_wscale_val,
2976 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
2977 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
2980 { &hf_tcp_option_sack_perm,
2981 { "TCP Sack Perm Option", "tcp.options.sack_perm",
2983 BASE_NONE, NULL, 0x0, "TCP Sack Perm Option", HFILL}},
2985 { &hf_tcp_option_sack,
2986 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
2987 BASE_NONE, NULL, 0x0, "TCP Sack Option", HFILL}},
2989 { &hf_tcp_option_sack_sle,
2990 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
2991 BASE_DEC, NULL, 0x0, "TCP Sack Left Edge", HFILL}},
2993 { &hf_tcp_option_sack_sre,
2994 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
2995 BASE_DEC, NULL, 0x0, "TCP Sack Right Edge", HFILL}},
2997 { &hf_tcp_option_echo,
2998 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
2999 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
3001 { &hf_tcp_option_echo_reply,
3002 { "TCP Echo Reply Option", "tcp.options.echo_reply",
3004 BASE_NONE, NULL, 0x0, "TCP Echo Reply Option", HFILL}},
3006 { &hf_tcp_option_time_stamp,
3007 { "TCP Time Stamp Option", "tcp.options.time_stamp",
3009 BASE_NONE, NULL, 0x0, "TCP Time Stamp Option", HFILL}},
3011 { &hf_tcp_option_cc,
3012 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
3013 NULL, 0x0, "TCP CC Option", HFILL}},
3015 { &hf_tcp_option_ccnew,
3016 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
3017 BASE_NONE, NULL, 0x0, "TCP CC New Option", HFILL}},
3019 { &hf_tcp_option_ccecho,
3020 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
3021 BASE_NONE, NULL, 0x0, "TCP CC Echo Option", HFILL}},
3023 { &hf_tcp_option_md5,
3024 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
3025 NULL, 0x0, "TCP MD5 Option", HFILL}},
3028 { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3029 "How long time has passed until the last frame of this PDU", HFILL}},
3030 { &hf_tcp_pdu_last_frame,
3031 { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3032 "This is the last frame of the PDU starting in this segment", HFILL }},
3035 static gint *ett[] = {
3039 &ett_tcp_option_sack,
3040 &ett_tcp_analysis_faults,
3045 module_t *tcp_module;
3047 proto_tcp = proto_register_protocol("Transmission Control Protocol",
3049 proto_register_field_array(proto_tcp, hf, array_length(hf));
3050 proto_register_subtree_array(ett, array_length(ett));
3052 /* subdissector code */
3053 subdissector_table = register_dissector_table("tcp.port",
3054 "TCP port", FT_UINT16, BASE_DEC);
3055 register_heur_dissector_list("tcp", &heur_subdissector_list);
3057 /* Register configuration preferences */
3058 tcp_module = prefs_register_protocol(proto_tcp, NULL);
3059 prefs_register_bool_preference(tcp_module, "summary_in_tree",
3060 "Show TCP summary in protocol tree",
3061 "Whether the TCP summary line should be shown in the protocol tree",
3062 &tcp_summary_in_tree);
3063 prefs_register_bool_preference(tcp_module, "check_checksum",
3064 "Validate the TCP checksum if possible",
3065 "Whether to validate the TCP checksum",
3066 &tcp_check_checksum);
3067 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
3068 "Allow subdissector to reassemble TCP streams",
3069 "Whether subdissector can request TCP streams to be reassembled",
3071 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
3072 "Analyze TCP sequence numbers",
3073 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
3075 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
3076 "Relative sequence numbers and window scaling",
3077 "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
3078 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
3079 "This option will also try to track and adjust the window field according to any TCP window scaling options seen.",
3081 prefs_register_bool_preference(tcp_module, "try_heuristic_first",
3082 "Try heuristic sub-dissectors first",
3083 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
3084 &try_heuristic_first);
3086 tcp_pdu_time_table=se_tree_create(SE_TREE_TYPE_RED_BLACK);
3087 register_init_routine(tcp_analyze_seq_init);
3088 register_init_routine(tcp_desegment_init);
3089 register_init_routine(tcp_fragment_init);
3093 proto_reg_handoff_tcp(void)
3095 dissector_handle_t tcp_handle;
3097 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
3098 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
3099 data_handle = find_dissector("data");
3100 tcp_tap = register_tap("tcp");