2 * Routines for TCP packet disassembly
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/in_cksum.h>
34 #include <epan/packet.h>
35 #include <epan/addr_resolv.h>
36 #include <epan/ipproto.h>
37 #include <epan/ip_opts.h>
38 #include <epan/follow.h>
39 #include <epan/prefs.h>
40 #include <epan/emem.h>
41 #include "packet-tcp.h"
42 #include "packet-ip.h"
43 #include "packet-frame.h"
44 #include <epan/conversation.h>
45 #include <epan/strutil.h>
46 #include <epan/reassemble.h>
48 #include <epan/slab.h>
49 #include <epan/expert.h>
51 static int tcp_tap = -1;
53 /* Place TCP summary in proto tree */
54 static gboolean tcp_summary_in_tree = TRUE;
57 * Flag to control whether to check the TCP checksum.
59 * In at least some Solaris network traces, there are packets with bad
60 * TCP checksums, but the traffic appears to indicate that the packets
61 * *were* received; the packets were probably sent by the host on which
62 * the capture was being done, on a network interface to which
63 * checksumming was offloaded, so that DLPI supplied an un-checksummed
64 * packet to the capture program but a checksummed packet got put onto
67 static gboolean tcp_check_checksum = TRUE;
69 extern FILE* data_out_file;
71 static int proto_tcp = -1;
72 static int hf_tcp_srcport = -1;
73 static int hf_tcp_dstport = -1;
74 static int hf_tcp_port = -1;
75 static int hf_tcp_seq = -1;
76 static int hf_tcp_nxtseq = -1;
77 static int hf_tcp_ack = -1;
78 static int hf_tcp_hdr_len = -1;
79 static int hf_tcp_flags = -1;
80 static int hf_tcp_flags_cwr = -1;
81 static int hf_tcp_flags_ecn = -1;
82 static int hf_tcp_flags_urg = -1;
83 static int hf_tcp_flags_ack = -1;
84 static int hf_tcp_flags_push = -1;
85 static int hf_tcp_flags_reset = -1;
86 static int hf_tcp_flags_syn = -1;
87 static int hf_tcp_flags_fin = -1;
88 static int hf_tcp_window_size = -1;
89 static int hf_tcp_checksum = -1;
90 static int hf_tcp_checksum_bad = -1;
91 static int hf_tcp_len = -1;
92 static int hf_tcp_urgent_pointer = -1;
93 static int hf_tcp_analysis_flags = -1;
94 static int hf_tcp_analysis_acks_frame = -1;
95 static int hf_tcp_analysis_ack_rtt = -1;
96 static int hf_tcp_analysis_rto = -1;
97 static int hf_tcp_analysis_rto_frame = -1;
98 static int hf_tcp_analysis_retransmission = -1;
99 static int hf_tcp_analysis_fast_retransmission = -1;
100 static int hf_tcp_analysis_out_of_order = -1;
101 static int hf_tcp_analysis_lost_packet = -1;
102 static int hf_tcp_analysis_ack_lost_packet = -1;
103 static int hf_tcp_analysis_window_update = -1;
104 static int hf_tcp_analysis_window_full = -1;
105 static int hf_tcp_analysis_keep_alive = -1;
106 static int hf_tcp_analysis_keep_alive_ack = -1;
107 static int hf_tcp_analysis_duplicate_ack = -1;
108 static int hf_tcp_analysis_duplicate_ack_num = -1;
109 static int hf_tcp_analysis_duplicate_ack_frame = -1;
110 static int hf_tcp_analysis_zero_window = -1;
111 static int hf_tcp_analysis_zero_window_probe = -1;
112 static int hf_tcp_analysis_zero_window_probe_ack = -1;
113 static int hf_tcp_continuation_to = -1;
114 static int hf_tcp_pdu_time = -1;
115 static int hf_tcp_pdu_size = -1;
116 static int hf_tcp_pdu_last_frame = -1;
117 static int hf_tcp_reassembled_in = -1;
118 static int hf_tcp_segments = -1;
119 static int hf_tcp_segment = -1;
120 static int hf_tcp_segment_overlap = -1;
121 static int hf_tcp_segment_overlap_conflict = -1;
122 static int hf_tcp_segment_multiple_tails = -1;
123 static int hf_tcp_segment_too_long_fragment = -1;
124 static int hf_tcp_segment_error = -1;
125 static int hf_tcp_option_mss = -1;
126 static int hf_tcp_option_mss_val = -1;
127 static int hf_tcp_option_wscale = -1;
128 static int hf_tcp_option_wscale_val = -1;
129 static int hf_tcp_option_sack_perm = -1;
130 static int hf_tcp_option_sack = -1;
131 static int hf_tcp_option_sack_sle = -1;
132 static int hf_tcp_option_sack_sre = -1;
133 static int hf_tcp_option_echo = -1;
134 static int hf_tcp_option_echo_reply = -1;
135 static int hf_tcp_option_time_stamp = -1;
136 static int hf_tcp_option_cc = -1;
137 static int hf_tcp_option_ccnew = -1;
138 static int hf_tcp_option_ccecho = -1;
139 static int hf_tcp_option_md5 = -1;
141 static gint ett_tcp = -1;
142 static gint ett_tcp_flags = -1;
143 static gint ett_tcp_options = -1;
144 static gint ett_tcp_option_sack = -1;
145 static gint ett_tcp_analysis = -1;
146 static gint ett_tcp_analysis_faults = -1;
147 static gint ett_tcp_segments = -1;
148 static gint ett_tcp_segment = -1;
151 /* not all of the hf_fields below make sense for TCP but we have to provide
152 them anyways to comply with the api (which was aimed for ip fragment
154 static const fragment_items tcp_segment_items = {
159 &hf_tcp_segment_overlap,
160 &hf_tcp_segment_overlap_conflict,
161 &hf_tcp_segment_multiple_tails,
162 &hf_tcp_segment_too_long_fragment,
163 &hf_tcp_segment_error,
164 &hf_tcp_reassembled_in,
168 static dissector_table_t subdissector_table;
169 static heur_dissector_list_t heur_subdissector_list;
170 static dissector_handle_t data_handle;
172 /* TCP structs and definitions */
174 /* **************************************************************************
176 * RTT and reltive sequence numbers.
177 * **************************************************************************/
178 static gboolean tcp_analyze_seq = TRUE;
179 static gboolean tcp_relative_seq = TRUE;
181 /* SLAB allocator for tcp_unacked structures
183 SLAB_ITEM_TYPE_DEFINE(tcp_unacked_t)
184 static SLAB_FREE_LIST_DEFINE(tcp_unacked_t)
185 #define TCP_UNACKED_NEW(fi) \
186 SLAB_ALLOC(fi, tcp_unacked_t)
187 #define TCP_UNACKED_FREE(fi) \
188 SLAB_FREE(fi, tcp_unacked_t)
191 /* Idea for gt: either x > y, or y is much bigger (assume wrap) */
192 #define GT_SEQ(x, y) ((gint32)((y) - (x)) < 0)
193 #define LT_SEQ(x, y) ((gint32)((x) - (y)) < 0)
194 #define GE_SEQ(x, y) ((gint32)((y) - (x)) <= 0)
195 #define LE_SEQ(x, y) ((gint32)((x) - (y)) <= 0)
196 #define EQ_SEQ(x, y) ((x) == (y))
198 #define TCP_A_RETRANSMISSION 0x0001
199 #define TCP_A_LOST_PACKET 0x0002
200 #define TCP_A_ACK_LOST_PACKET 0x0004
201 #define TCP_A_KEEP_ALIVE 0x0008
202 #define TCP_A_DUPLICATE_ACK 0x0010
203 #define TCP_A_ZERO_WINDOW 0x0020
204 #define TCP_A_ZERO_WINDOW_PROBE 0x0040
205 #define TCP_A_ZERO_WINDOW_PROBE_ACK 0x0080
206 #define TCP_A_KEEP_ALIVE_ACK 0x0100
207 #define TCP_A_OUT_OF_ORDER 0x0200
208 #define TCP_A_FAST_RETRANSMISSION 0x0400
209 #define TCP_A_WINDOW_UPDATE 0x0800
210 #define TCP_A_WINDOW_FULL 0x1000
214 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
215 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
216 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
217 struct tcp_analysis *tcpd);
220 struct tcp_analysis *
221 get_tcp_conversation_data(packet_info *pinfo)
224 conversation_t *conv=NULL;
225 struct tcp_analysis *tcpd=NULL;
227 /* Have we seen this conversation before? */
228 if( (conv=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
229 /* No this is a new conversation. */
230 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
233 /* check if we have any data for this conversation */
234 tcpd=conversation_get_proto_data(conv, proto_tcp);
236 /* No no such data yet. Allocate and init it */
237 tcpd=se_alloc(sizeof(struct tcp_analysis));
238 tcpd->flow1.segments=NULL;
239 tcpd->flow1.base_seq=0;
240 tcpd->flow1.lastack=0;
241 tcpd->flow1.lastacktime.secs=0;
242 tcpd->flow1.lastacktime.nsecs=0;
243 tcpd->flow1.lastnondupack=0;
244 tcpd->flow1.nextseq=0;
245 tcpd->flow1.nextseqtime.secs=0;
246 tcpd->flow1.nextseqtime.nsecs=0;
247 tcpd->flow1.nextseqframe=0;
248 tcpd->flow1.window=0;
249 tcpd->flow1.win_scale=-1;
251 tcpd->flow1.multisegment_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_multisegment_pdus");
252 tcpd->flow2.segments=NULL;
253 tcpd->flow2.base_seq=0;
254 tcpd->flow2.lastack=0;
255 tcpd->flow2.lastacktime.secs=0;
256 tcpd->flow2.lastacktime.nsecs=0;
257 tcpd->flow2.lastnondupack=0;
258 tcpd->flow2.nextseq=0;
259 tcpd->flow2.nextseqtime.secs=0;
260 tcpd->flow2.nextseqtime.nsecs=0;
261 tcpd->flow2.nextseqframe=0;
262 tcpd->flow2.window=0;
263 tcpd->flow2.win_scale=-1;
265 tcpd->flow2.multisegment_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_multisegment_pdus");
266 tcpd->acked_table=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_analyze_acked_table");
269 conversation_add_proto_data(conv, proto_tcp, tcpd);
273 /* check direction and get ua lists */
274 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
275 /* if the addresses are equal, match the ports instead */
277 direction= (pinfo->srcport > pinfo->destport)*2-1;
280 tcpd->fwd=&(tcpd->flow1);
281 tcpd->rev=&(tcpd->flow2);
283 tcpd->fwd=&(tcpd->flow2);
284 tcpd->rev=&(tcpd->flow1);
292 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_multisegment_pdu *msp)
296 if (check_col(pinfo->cinfo, COL_INFO)){
297 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", msp->first_frame);
299 item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
300 tvb, 0, 0, msp->first_frame);
301 PROTO_ITEM_SET_GENERATED(item);
304 /* if we know that a PDU starts inside this segment, return the adjusted
305 offset to where that PDU starts or just return offset back
306 and let TCP try to find out what it can about this segment
309 scan_for_next_pdu(tvbuff_t *tvb, proto_tree *tcp_tree, packet_info *pinfo, int offset, guint32 seq, guint32 nxtseq, struct tcp_analysis *tcpd)
311 struct tcp_multisegment_pdu *msp=NULL;
313 if(!pinfo->fd->flags.visited){
314 msp=se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
316 /* If this segment is completely within a previous PDU
317 * then we just skip this packet
319 if(seq>msp->seq && nxtseq<=msp->nxtpdu){
320 msp->last_frame=pinfo->fd->num;
321 msp->last_frame_time=pinfo->fd->abs_ts;
322 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
325 if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu){
326 offset+=msp->nxtpdu-seq;
332 msp=se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
334 if(pinfo->fd->num==msp->first_frame){
338 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, msp->last_frame);
339 PROTO_ITEM_SET_GENERATED(item);
341 nstime_delta(&ns, &msp->last_frame_time, &pinfo->fd->abs_ts);
342 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
344 PROTO_ITEM_SET_GENERATED(item);
347 /* If this segment is completely within a previous PDU
348 * then we just skip this packet
350 if(seq>msp->seq && nxtseq<=msp->nxtpdu){
351 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
355 if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu){
356 offset+=msp->nxtpdu-seq;
364 /* if we saw a PDU that extended beyond the end of the segment,
365 use this function to remember where the next pdu starts
367 static struct tcp_multisegment_pdu *
368 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, struct tcp_analysis *tcpd)
370 struct tcp_multisegment_pdu *msp;
372 msp=se_alloc(sizeof(struct tcp_multisegment_pdu));
375 msp->first_frame=pinfo->fd->num;
376 msp->last_frame=pinfo->fd->num;
377 msp->last_frame_time=pinfo->fd->abs_ts;
378 se_tree_insert32(tcpd->fwd->multisegment_pdus, seq, (void *)msp);
382 /* This is called for SYN+ACK packets and the purpose is to verify that we
383 * have seen window scaling in both directions.
384 * If we cant find window scaling being set in both directions
385 * that means it was present in the SYN but not in the SYN+ACK
386 * (or the SYN was missing) and then we disable the window scaling
387 * for this tcp session.
390 verify_tcp_window_scaling(struct tcp_analysis *tcpd)
392 if( tcpd && ((tcpd->flow1.win_scale==-1) || (tcpd->flow2.win_scale==-1)) ){
393 tcpd->flow1.win_scale=-1;
394 tcpd->flow2.win_scale=-1;
398 /* if we saw a window scaling option, store it for future reference
401 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
403 tcpd->fwd->win_scale=ws;
407 tcp_get_relative_seq_ack(guint32 *seq, guint32 *ack, guint32 *win, struct tcp_analysis *tcpd)
409 if(tcp_relative_seq){
410 (*seq) -= tcpd->fwd->base_seq;
411 (*ack) -= tcpd->rev->base_seq;
412 if(tcpd->fwd->win_scale!=-1){
413 (*win)<<=tcpd->fwd->win_scale;
419 /* when this function returns, it will (if createflag) populate the ta pointer.
422 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag, struct tcp_analysis *tcpd)
424 tcpd->ta=se_tree_lookup32(tcpd->acked_table, frame);
425 if((!tcpd->ta) && createflag){
426 tcpd->ta=se_alloc(sizeof(struct tcp_acked));
427 tcpd->ta->frame_acked=0;
429 tcpd->ta->ts.nsecs=0;
431 tcpd->ta->dupack_num=0;
432 tcpd->ta->dupack_frame=0;
433 se_tree_insert32(tcpd->acked_table, frame, (void *)tcpd->ta);
438 /* fwd contains a list of all segments processed but not yet ACKed in the
439 * same direction as the current segment.
440 * rev contains a list of all segments received but not yet ACKed in the
441 * opposite direction to the current segment.
443 * New segments are always added to the head of the fwd/rev lists.
447 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint32 window, struct tcp_analysis *tcpd)
449 tcp_unacked_t *ual=NULL;
453 printf("analyze_sequence numbers frame:%d direction:%s\n",pinfo->fd->num,direction>=0?"FWD":"REW");
454 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);
455 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);
460 /* if this is the first segment for this list we need to store the
463 if(tcpd->fwd->base_seq==0){
464 tcpd->fwd->base_seq=seq;
466 /* if we have spotted a new base_Seq in the reverse direction
469 if(tcpd->rev->base_seq==0){
470 tcpd->rev->base_seq=ack;
476 * it is a zero window probe if
477 * the sequnece number is the next expected one
478 * the window in the other direction is 0
479 * the segment is exactly 1 byte
483 && seq==tcpd->fwd->nextseq
484 && tcpd->rev->window==0 ){
486 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
488 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
494 * a zero window packet has window == 0 but none of the SYN/FIN/RST set
498 && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ){
500 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
502 tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
507 * If this segment is beyond the last seen nextseq we must
508 * have missed some previous segment
510 * We only check for this if we have actually seen segments prior to this
512 * RST packets are not checked for this.
514 if( tcpd->fwd->nextseq
515 && GT_SEQ(seq, tcpd->fwd->nextseq)
516 && (flags&(TH_RST))==0 ){
518 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
520 tcpd->ta->flags|=TCP_A_LOST_PACKET;
525 * a keepalive contains 0 or 1 bytes of data and starts one byte prior
526 * to what should be the next sequence number.
527 * SYN/FIN/RST segments are never keepalives
530 if( (seglen==0||seglen==1)
531 && seq==(tcpd->fwd->nextseq-1)
532 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
534 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
536 tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
540 * A window update is a 0 byte segment with the same SEQ/ACK numbers as
541 * the previous seen segment and with a new window value
545 && window!=tcpd->fwd->window
546 && seq==tcpd->fwd->nextseq
547 && ack==tcpd->fwd->lastack
548 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
550 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
552 tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
557 * If we know the window scaling
558 * and if this segment contains data ang goes all the way to the
559 * edge of the advertized window
560 * then we mark it as WINDOW FULL
561 * SYN/RST/FIN packets are never WINDOW FULL
565 && tcpd->fwd->win_scale!=-1
566 && tcpd->rev->win_scale!=-1
567 && (seq+seglen)==(tcpd->rev->lastack+(tcpd->rev->window<<tcpd->rev->win_scale))
568 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
570 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
572 tcpd->ta->flags|=TCP_A_WINDOW_FULL;
577 * It is a keepalive ack if it repeats the previous ACK and if
578 * the last segment in the reverse direction was a keepalive
583 && window==tcpd->fwd->window
584 && seq==tcpd->fwd->nextseq
585 && ack==tcpd->fwd->lastack
586 && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
587 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
589 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
591 tcpd->ta->flags|=TCP_A_KEEP_ALIVE_ACK;
596 /* ZERO WINDOW PROBE ACK
597 * It is a zerowindowprobe ack if it repeats the previous ACK and if
598 * the last segment in the reverse direction was a zerowindowprobe
599 * It also repeats the previous zero window indication
604 && window==tcpd->fwd->window
605 && seq==tcpd->fwd->nextseq
606 && ack==tcpd->fwd->lastack
607 && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
608 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
610 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
612 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
618 * It is a duplicate ack if window/seq/ack is the same as the previous
619 * segment and if the segment length is 0
623 && window==tcpd->fwd->window
624 && seq==tcpd->fwd->nextseq
625 && ack==tcpd->fwd->lastack
626 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
627 tcpd->fwd->dupacknum++;
629 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
631 tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
632 tcpd->ta->dupack_num=tcpd->fwd->dupacknum;
633 tcpd->ta->dupack_frame=tcpd->fwd->lastnondupack;
638 /* If this was NOT a dupack we must reset the dupack counters */
639 if( (!tcpd->ta) || !(tcpd->ta->flags&TCP_A_DUPLICATE_ACK) ){
640 tcpd->fwd->lastnondupack=pinfo->fd->num;
641 tcpd->fwd->dupacknum=0;
646 * If this segment acks beyond the nextseqnum in the other direction
647 * then that means we have missed packets going in the
650 * We only check this if we have actually seen some seq numbers
651 * in the other direction.
653 if( tcpd->rev->nextseq
654 && GT_SEQ(ack, tcpd->rev->nextseq )
655 && (flags&(TH_ACK))!=0 ){
658 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
660 tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
661 /* update nextseq in the other direction so we dont get
662 * this indication again.
664 tcpd->rev->nextseq=ack;
668 /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
669 * If the segments contains data and if it does not advance
670 * sequence number it must be either of these three.
671 * Only test for this if we know what the seq number should be
672 * (tcpd->fwd->nextseq)
674 * Note that a simple KeepAlive is not a retransmission
677 && tcpd->fwd->nextseq
678 && (LT_SEQ(seq, tcpd->fwd->nextseq)) ){
681 if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ){
682 goto finished_checking_retransmission_type;
685 /* If there were >=2 duplicate ACKs in the reverse direction
686 * (there might be duplicate acks missing from the trace)
687 * and if this sequence number matches those ACKs
688 * and if the packet occurs within 20ms of the last
690 * then this is a fast retransmission
692 t=(pinfo->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
693 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;
694 if( tcpd->rev->dupacknum>=2
695 && tcpd->rev->lastack==seq
698 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
700 tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
701 goto finished_checking_retransmission_type;
704 /* If the segment came <3ms since the segment with the highest
705 * seen sequence number, then it is an OUT-OF-ORDER segment.
706 * (3ms is an arbitrary number)
708 t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
709 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
712 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
714 tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
715 goto finished_checking_retransmission_type;
718 /* Then it has to be a generic retransmission */
720 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
722 tcpd->ta->flags|=TCP_A_RETRANSMISSION;
723 nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
724 tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
726 finished_checking_retransmission_type:
729 /* add this new sequence number to the fwd list */
730 TCP_UNACKED_NEW(ual);
731 ual->next=tcpd->fwd->segments;
732 tcpd->fwd->segments=ual;
733 ual->frame=pinfo->fd->num;
735 ual->ts=pinfo->fd->abs_ts;
737 /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
738 ual->nextseq=seq+seglen;
739 if( flags&(TH_SYN|TH_FIN) ){
743 /* Store the highest number seen so far for nextseq so we can detect
744 * when we receive segments that arrive with a "hole"
745 * If we dont have anything since before, just store what we got.
746 * ZeroWindowProbes are special and dont really advance the nextseq
748 if(GT_SEQ(ual->nextseq, tcpd->fwd->nextseq) || !tcpd->fwd->nextseq) {
749 if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ){
750 tcpd->fwd->nextseq=ual->nextseq;
751 tcpd->fwd->nextseqframe=pinfo->fd->num;
752 tcpd->fwd->nextseqtime.secs=pinfo->fd->abs_ts.secs;
753 tcpd->fwd->nextseqtime.nsecs=pinfo->fd->abs_ts.nsecs;
758 /* remember what the ack/window is so we can track window updates and retransmissions */
759 tcpd->fwd->window=window;
760 tcpd->fwd->lastack=ack;
761 tcpd->fwd->lastacktime.secs=pinfo->fd->abs_ts.secs;
762 tcpd->fwd->lastacktime.nsecs=pinfo->fd->abs_ts.nsecs;
765 /* if there were any flags set for this segment we need to remember them
766 * we only remember the flags for the very last segment though.
769 tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
771 tcpd->fwd->lastsegmentflags=0;
775 /* remove all segments this ACKs and we dont need to keep around any more
778 /* first we remove all such segments at the head of the list */
779 while((ual=tcpd->rev->segments)){
780 tcp_unacked_t *tmpual;
781 if(ack==ual->nextseq){
782 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
783 tcpd->ta->frame_acked=ual->frame;
784 nstime_delta(&tcpd->ta->ts, &pinfo->fd->abs_ts, &ual->ts);
786 if(GT_SEQ(ual->nextseq,ack)){
790 /*qqq do the ACKs segment x delta y */
793 tmpual=tcpd->rev->segments->next;
794 TCP_UNACKED_FREE(ual);
795 tcpd->rev->segments=tmpual;
797 /* now we remove all such segments that are NOT at the head of the list */
798 ual=tcpd->rev->segments;
799 while(ual && ual->next){
800 tcp_unacked_t *tmpual;
801 if(GT_SEQ(ual->next->nextseq,ack)){
806 /*qqq do the ACKs segment x delta y */
809 tmpual=ual->next->next;
810 TCP_UNACKED_FREE(ual->next);
818 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd)
820 struct tcp_acked *ta;
825 tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE, tcpd);
832 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
833 PROTO_ITEM_SET_GENERATED(item);
834 tree=proto_item_add_subtree(item, ett_tcp_analysis);
836 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
837 data we actually have */
839 item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
840 tvb, 0, 0, ta->frame_acked);
841 PROTO_ITEM_SET_GENERATED(item);
843 /* only display RTT if we actually have something we are acking */
844 if( ta->ts.secs || ta->ts.nsecs ){
845 item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
847 PROTO_ITEM_SET_GENERATED(item);
852 proto_item *flags_item=NULL;
853 proto_tree *flags_tree=NULL;
855 flags_item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, -1, FALSE);
856 PROTO_ITEM_SET_GENERATED(flags_item);
857 flags_tree=proto_item_add_subtree(flags_item, ett_tcp_analysis);
858 if( ta->flags&TCP_A_RETRANSMISSION ){
859 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
860 PROTO_ITEM_SET_GENERATED(flags_item);
861 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Retransmission (suspected)");
862 if(check_col(pinfo->cinfo, COL_INFO)){
863 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
865 if( ta->rto_ts.secs || ta->rto_ts.nsecs ){
866 item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
867 tvb, 0, 0, &ta->rto_ts);
868 PROTO_ITEM_SET_GENERATED(item);
869 item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame, tvb, 0, 0, ta->rto_frame);
870 PROTO_ITEM_SET_GENERATED(item);
873 if( ta->flags&TCP_A_FAST_RETRANSMISSION ){
874 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_fast_retransmission, tvb, 0, 0, "This frame is a (suspected) fast retransmission");
875 PROTO_ITEM_SET_GENERATED(flags_item);
876 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Fast retransmission (suspected)");
877 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
878 PROTO_ITEM_SET_GENERATED(flags_item);
879 if(check_col(pinfo->cinfo, COL_INFO)){
880 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Fast Retransmission] ");
883 if( ta->flags&TCP_A_OUT_OF_ORDER ){
884 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");
885 PROTO_ITEM_SET_GENERATED(flags_item);
886 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Out-Of-Order segment");
887 if(check_col(pinfo->cinfo, COL_INFO)){
888 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
891 if( ta->flags&TCP_A_LOST_PACKET ){
892 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_lost_packet, tvb, 0, 0, "A segment before this frame was lost");
893 PROTO_ITEM_SET_GENERATED(flags_item);
894 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Previous segment lost (common at capture start)");
895 if(check_col(pinfo->cinfo, COL_INFO)){
896 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] ");
899 if( ta->flags&TCP_A_ACK_LOST_PACKET ){
900 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?)");
901 PROTO_ITEM_SET_GENERATED(flags_item);
902 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "ACKed lost segment (common at capture start)");
903 if(check_col(pinfo->cinfo, COL_INFO)){
904 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] ");
907 if( ta->flags&TCP_A_WINDOW_UPDATE ){
908 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_update, tvb, 0, 0, "This is a tcp window update");
909 PROTO_ITEM_SET_GENERATED(flags_item);
910 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window update");
911 if(check_col(pinfo->cinfo, COL_INFO)){
912 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
915 if( ta->flags&TCP_A_WINDOW_FULL ){
916 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_full, tvb, 0, 0, "The transmission window is now completely full");
917 PROTO_ITEM_SET_GENERATED(flags_item);
918 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window is full");
919 if(check_col(pinfo->cinfo, COL_INFO)){
920 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
923 if( ta->flags&TCP_A_KEEP_ALIVE ){
924 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive, tvb, 0, 0, "This is a TCP keep-alive segment");
925 PROTO_ITEM_SET_GENERATED(flags_item);
926 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive");
927 if(check_col(pinfo->cinfo, COL_INFO)){
928 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
931 if( ta->flags&TCP_A_KEEP_ALIVE_ACK ){
932 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");
933 PROTO_ITEM_SET_GENERATED(flags_item);
934 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive ACK");
935 if(check_col(pinfo->cinfo, COL_INFO)){
936 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
940 if( ta->flags&TCP_A_DUPLICATE_ACK ){
941 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_duplicate_ack, tvb, 0, 0, "This is a TCP duplicate ack");
942 PROTO_ITEM_SET_GENERATED(flags_item);
943 if(check_col(pinfo->cinfo, COL_INFO)){
944 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Dup ACK %u#%u] ", ta->dupack_frame, ta->dupack_num);
947 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
948 tvb, 0, 0, ta->dupack_num);
949 PROTO_ITEM_SET_GENERATED(flags_item);
950 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
951 tvb, 0, 0, ta->dupack_frame);
952 PROTO_ITEM_SET_GENERATED(flags_item);
953 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Duplicate ACK (#%u)",
956 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE ){
957 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");
958 PROTO_ITEM_SET_GENERATED(flags_item);
959 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe");
960 if(check_col(pinfo->cinfo, COL_INFO)){
961 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
964 if( ta->flags&TCP_A_ZERO_WINDOW ){
965 flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window, tvb, 0, 0, "This is a ZeroWindow segment");
966 PROTO_ITEM_SET_GENERATED(flags_item);
967 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window");
968 if(check_col(pinfo->cinfo, COL_INFO)){
969 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
972 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE_ACK ){
973 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");
974 PROTO_ITEM_SET_GENERATED(flags_item);
975 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe ACK");
976 if(check_col(pinfo->cinfo, COL_INFO)){
977 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbeAck] ");
985 /* **************************************************************************
986 * End of tcp sequence number analysis
987 * **************************************************************************/
992 /* Minimum TCP header length. */
993 #define TCPH_MIN_LEN 20
999 #define TCPOPT_NOP 1 /* Padding */
1000 #define TCPOPT_EOL 0 /* End of options */
1001 #define TCPOPT_MSS 2 /* Segment size negotiating */
1002 #define TCPOPT_WINDOW 3 /* Window scaling */
1003 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
1004 #define TCPOPT_SACK 5 /* SACK Block */
1005 #define TCPOPT_ECHO 6
1006 #define TCPOPT_ECHOREPLY 7
1007 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
1008 #define TCPOPT_CC 11
1009 #define TCPOPT_CCNEW 12
1010 #define TCPOPT_CCECHO 13
1011 #define TCPOPT_MD5 19 /* RFC2385 */
1014 * TCP option lengths
1017 #define TCPOLEN_MSS 4
1018 #define TCPOLEN_WINDOW 3
1019 #define TCPOLEN_SACK_PERM 2
1020 #define TCPOLEN_SACK_MIN 2
1021 #define TCPOLEN_ECHO 6
1022 #define TCPOLEN_ECHOREPLY 6
1023 #define TCPOLEN_TIMESTAMP 10
1024 #define TCPOLEN_CC 6
1025 #define TCPOLEN_CCNEW 6
1026 #define TCPOLEN_CCECHO 6
1027 #define TCPOLEN_MD5 18
1031 /* Desegmentation of TCP streams */
1032 /* table to hold defragmented TCP streams */
1033 static GHashTable *tcp_fragment_table = NULL;
1035 tcp_fragment_init(void)
1037 fragment_table_init(&tcp_fragment_table);
1040 /* functions to trace tcp segments */
1041 /* Enable desegmenting of TCP streams */
1042 static gboolean tcp_desegment = TRUE;
1045 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1046 guint32 seq, guint32 nxtseq,
1047 guint32 sport, guint32 dport,
1048 proto_tree *tree, proto_tree *tcp_tree,
1049 struct tcp_analysis *tcpd)
1051 struct tcpinfo *tcpinfo = pinfo->private_data;
1052 fragment_data *ipfd_head;
1053 gboolean must_desegment;
1054 gboolean called_dissector;
1055 int another_pdu_follows;
1060 proto_item *frag_tree_item;
1061 proto_item *tcp_tree_item;
1062 struct tcp_multisegment_pdu *msp;
1066 must_desegment = FALSE;
1067 called_dissector = FALSE;
1068 another_pdu_follows = 0;
1072 * Initialize these to assume no desegmentation.
1073 * If that's not the case, these will be set appropriately
1074 * by the subdissector.
1076 pinfo->desegment_offset = 0;
1077 pinfo->desegment_len = 0;
1080 * Initialize this to assume that this segment will just be
1081 * added to the middle of a desegmented chunk of data, so
1082 * that we should show it all as data.
1083 * If that's not the case, it will be set appropriately.
1085 deseg_offset = offset;
1087 /* find the most previous PDU starting before this sequence number */
1088 msp=se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
1089 if(msp && msp->seq<=seq && msp->nxtpdu>seq){
1092 if(!pinfo->fd->flags.visited){
1093 msp->last_frame=pinfo->fd->num;
1094 msp->last_frame_time=pinfo->fd->abs_ts;
1097 /* OK, this PDU was found, which means the segment continues
1098 a higher-level PDU and that we must desegment it.
1100 len=MIN(nxtseq, msp->nxtpdu) - seq;
1101 ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
1105 (LT_SEQ (nxtseq,msp->nxtpdu)) );
1106 /* if we didnt consume the entire segment there is another pdu
1107 * starting beyong the end of this one
1109 if(msp->nxtpdu<nxtseq && len>0){
1110 another_pdu_follows=len;
1113 /* This segment was not found in our table, so it doesn't
1114 contain a continuation of a higher-level PDU.
1115 Call the normal subdissector.
1117 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1118 sport, dport, 0, 0, FALSE, tcpd);
1119 called_dissector = TRUE;
1121 /* Did the subdissector ask us to desegment some more data
1122 before it could handle the packet?
1123 If so we have to create some structures in our table but
1124 this is something we only do the first time we see this
1127 if(pinfo->desegment_len) {
1128 if (!pinfo->fd->flags.visited)
1129 must_desegment = TRUE;
1132 * Set "deseg_offset" to the offset in "tvb"
1133 * of the first byte of data that the
1134 * subdissector didn't process.
1136 deseg_offset = offset + pinfo->desegment_offset;
1139 /* Either no desegmentation is necessary, or this is
1140 segment contains the beginning but not the end of
1141 a higher-level PDU and thus isn't completely
1148 /* is it completely desegmented? */
1151 * Yes, we think it is.
1152 * We only call subdissector for the last segment.
1153 * Note that the last segment may include more than what
1156 if(ipfd_head->reassembled_in==pinfo->fd->num){
1158 * OK, this is the last segment.
1159 * Let's call the subdissector with the desegmented
1165 /* create a new TVB structure for desegmented data */
1166 next_tvb = tvb_new_real_data(ipfd_head->data,
1167 ipfd_head->datalen, ipfd_head->datalen);
1169 /* add this tvb as a child to the original one */
1170 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1172 /* add desegmented data to the data source list */
1173 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1176 * Supply the sequence number of the first of the
1177 * reassembled bytes.
1179 tcpinfo->seq = msp->seq;
1181 /* indicate that this is reassembled data */
1182 tcpinfo->is_reassembled = TRUE;
1184 /* call subdissector */
1185 process_tcp_payload(next_tvb, 0, pinfo, tree,
1186 tcp_tree, sport, dport, 0, 0, FALSE, tcpd);
1187 called_dissector = TRUE;
1190 * OK, did the subdissector think it was completely
1191 * desegmented, or does it think we need even more
1194 old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
1195 if(pinfo->desegment_len &&
1196 pinfo->desegment_offset<=old_len){
1198 * "desegment_len" isn't 0, so it needs more
1199 * data for something - and "desegment_offset"
1200 * is before "old_len", so it needs more data
1201 * to dissect the stuff we thought was
1202 * completely desegmented (as opposed to the
1203 * stuff at the beginning being completely
1204 * desegmented, but the stuff at the end
1205 * being a new higher-level PDU that also
1206 * needs desegmentation).
1208 fragment_set_partial_reassembly(pinfo,msp->first_frame,tcp_fragment_table);
1209 msp->nxtpdu=msp->seq+tvb_reported_length(next_tvb) + pinfo->desegment_len;
1212 * Show the stuff in this TCP segment as
1213 * just raw TCP segment data.
1216 tvb_reported_length_remaining(tvb, offset);
1217 proto_tree_add_text(tcp_tree, tvb, offset, -1,
1218 "TCP segment data (%u byte%s)", nbytes,
1219 plurality(nbytes, "", "s"));
1222 * The subdissector thought it was completely
1223 * desegmented (although the stuff at the
1224 * end may, in turn, require desegmentation),
1225 * so we show a tree with all segments.
1227 show_fragment_tree(ipfd_head, &tcp_segment_items,
1228 tree, pinfo, next_tvb, &frag_tree_item);
1230 * The toplevel fragment subtree is now
1231 * behind all desegmented data; move it
1232 * right behind the TCP tree.
1234 tcp_tree_item = proto_tree_get_parent(tcp_tree);
1235 if(frag_tree_item && tcp_tree_item) {
1236 proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1239 /* Did the subdissector ask us to desegment
1240 some more data? This means that the data
1241 at the beginning of this segment completed
1242 a higher-level PDU, but the data at the
1243 end of this segment started a higher-level
1244 PDU but didn't complete it.
1246 If so, we have to create some structures
1247 in our table, but this is something we
1248 only do the first time we see this packet.
1250 if(pinfo->desegment_len) {
1251 if (!pinfo->fd->flags.visited)
1252 must_desegment = TRUE;
1254 /* The stuff we couldn't dissect
1255 must have come from this segment,
1256 so it's all in "tvb".
1258 "pinfo->desegment_offset" is
1259 relative to the beginning of
1260 "next_tvb"; we want an offset
1261 relative to the beginning of "tvb".
1263 First, compute the offset relative
1264 to the *end* of "next_tvb" - i.e.,
1265 the number of bytes before the end
1266 of "next_tvb" at which the
1267 subdissector stopped. That's the
1268 length of "next_tvb" minus the
1269 offset, relative to the beginning
1270 of "next_tvb, at which the
1271 subdissector stopped.
1274 ipfd_head->datalen - pinfo->desegment_offset;
1276 /* "tvb" and "next_tvb" end at the
1277 same byte of data, so the offset
1278 relative to the end of "next_tvb"
1279 of the byte at which we stopped
1280 is also the offset relative to
1281 the end of "tvb" of the byte at
1284 Convert that back into an offset
1285 relative to the beginninng of
1286 "tvb", by taking the length of
1287 "tvb" and subtracting the offset
1288 relative to the end.
1290 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1296 if (must_desegment) {
1297 /* If the dissector requested "reassemble until FIN"
1298 * just set this flag for the flow and let reassembly
1299 * proceed at normal. We will check/pick up these
1300 * reassembled PDUs later down in dissect_tcp() when checking
1303 if(pinfo->desegment_len==DESEGMENT_UNTIL_FIN){
1304 tcpd->fwd->flags|=TCP_FLOW_REASSEMBLE_UNTIL_FIN;
1308 * The sequence number at which the stuff to be desegmented
1309 * starts is the sequence number of the byte at an offset
1310 * of "deseg_offset" into "tvb".
1312 * The sequence number of the byte at an offset of "offset"
1313 * is "seq", i.e. the starting sequence number of this
1314 * segment, so the sequence number of the byte at
1315 * "deseg_offset" is "seq + (deseg_offset - offset)".
1317 deseg_seq = seq + (deseg_offset - offset);
1319 if( ((nxtseq - deseg_seq) <= 1024*1024)
1320 && (!pinfo->fd->flags.visited) ){
1321 msp = pdu_store_sequencenumber_of_next_pdu(pinfo, deseg_seq,
1322 nxtseq + pinfo->desegment_len, tcpd);
1324 /* add this segment as the first one for this new pdu */
1325 fragment_add(tvb, deseg_offset, pinfo, msp->first_frame,
1329 LT_SEQ(nxtseq, msp->nxtpdu));
1333 if (!called_dissector || pinfo->desegment_len != 0) {
1334 if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
1335 !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
1337 * We know what frame this PDU is reassembled in;
1338 * let the user know.
1340 item=proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in,
1341 tvb, 0, 0, ipfd_head->reassembled_in);
1342 PROTO_ITEM_SET_GENERATED(item);
1346 * Either we didn't call the subdissector at all (i.e.,
1347 * this is a segment that contains the middle of a
1348 * higher-level PDU, but contains neither the beginning
1349 * nor the end), or the subdissector couldn't dissect it
1350 * all, as some data was missing (i.e., it set
1351 * "pinfo->desegment_len" to the amount of additional
1354 if (pinfo->desegment_offset == 0) {
1356 * It couldn't, in fact, dissect any of it (the
1357 * first byte it couldn't dissect is at an offset
1358 * of "pinfo->desegment_offset" from the beginning
1359 * of the payload, and that's 0).
1360 * Just mark this as TCP.
1362 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1363 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1365 if (check_col(pinfo->cinfo, COL_INFO)){
1366 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
1371 * Show what's left in the packet as just raw TCP segment
1373 * XXX - remember what protocol the last subdissector
1374 * was, and report it as a continuation of that, instead?
1376 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
1377 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
1378 "TCP segment data (%u byte%s)", nbytes,
1379 plurality(nbytes, "", "s"));
1381 pinfo->can_desegment=0;
1382 pinfo->desegment_offset = 0;
1383 pinfo->desegment_len = 0;
1385 if(another_pdu_follows){
1386 /* there was another pdu following this one. */
1387 pinfo->can_desegment=2;
1388 /* we also have to prevent the dissector from changing the
1389 * PROTOCOL and INFO colums since what follows may be an
1390 * incomplete PDU and we dont want it be changed back from
1391 * <Protocol> to <TCP>
1392 * XXX There is no good way to block the PROTOCOL column
1393 * from being changed yet so we set the entire row unwritable.
1395 col_set_fence(pinfo->cinfo, COL_INFO);
1396 col_set_writable(pinfo->cinfo, FALSE);
1397 offset += another_pdu_follows;
1398 seq += another_pdu_follows;
1404 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
1405 * consists of a fixed-length chunk of data that contains enough information
1406 * to determine the length of the PDU, followed by rest of the PDU.
1408 * The first three arguments are the arguments passed to the dissector
1409 * that calls this routine.
1411 * "proto_desegment" is the dissector's flag controlling whether it should
1412 * desegment PDUs that cross TCP segment boundaries.
1414 * "fixed_len" is the length of the fixed-length part of the PDU.
1416 * "get_pdu_len()" is a routine called to get the length of the PDU from
1417 * the fixed-length part of the PDU; it's passed "tvb" and "offset".
1419 * "dissect_pdu()" is the routine to dissect a PDU.
1422 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1423 gboolean proto_desegment, guint fixed_len,
1424 guint (*get_pdu_len)(tvbuff_t *, int),
1425 dissector_t dissect_pdu)
1427 volatile int offset = 0;
1429 guint length_remaining;
1433 proto_item *item=NULL;
1435 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1437 * We use "tvb_ensure_length_remaining()" to make sure there actually
1438 * *is* data remaining. The protocol we're handling could conceivably
1439 * consists of a sequence of fixed-length PDUs, and therefore the
1440 * "get_pdu_len" routine might not actually fetch anything from
1441 * the tvbuff, and thus might not cause an exception to be thrown if
1442 * we've run past the end of the tvbuff.
1444 * This means we're guaranteed that "length_remaining" is positive.
1446 length_remaining = tvb_ensure_length_remaining(tvb, offset);
1449 * Can we do reassembly?
1451 if (proto_desegment && pinfo->can_desegment) {
1453 * Yes - is the fixed-length part of the PDU split across segment
1456 if (length_remaining < fixed_len) {
1458 * Yes. Tell the TCP dissector where the data for this message
1459 * starts in the data it handed us, and how many more bytes we
1462 pinfo->desegment_offset = offset;
1463 pinfo->desegment_len = fixed_len - length_remaining;
1469 * Get the length of the PDU.
1471 plen = (*get_pdu_len)(tvb, offset);
1472 if (plen < fixed_len) {
1474 * The PDU length from the fixed-length portion probably didn't
1475 * include the fixed-length portion's length, and was probably so
1476 * large that the total length overflowed.
1478 * Report this as an error.
1480 show_reported_bounds_error(tvb, pinfo, tree);
1484 * Display the PDU length as a field
1486 item=proto_tree_add_uint(pinfo->tcp_tree, hf_tcp_pdu_size, tvb, 0, 0, plen);
1487 PROTO_ITEM_SET_GENERATED(item);
1491 /* give a hint to TCP where the next PDU starts
1492 * so that it can attempt to find it in case it starts
1493 * somewhere in the middle of a segment.
1495 if(!pinfo->fd->flags.visited && tcp_analyze_seq){
1496 guint remaining_bytes;
1497 remaining_bytes=tvb_reported_length_remaining(tvb, offset);
1498 if(plen>remaining_bytes){
1499 pinfo->want_pdu_tracking=2;
1500 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
1505 * Can we do reassembly?
1507 if (proto_desegment && pinfo->can_desegment) {
1509 * Yes - is the PDU split across segment boundaries?
1511 if (length_remaining < plen) {
1513 * Yes. Tell the TCP dissector where the data for this message
1514 * starts in the data it handed us, and how many more bytes we
1517 pinfo->desegment_offset = offset;
1518 pinfo->desegment_len = plen - length_remaining;
1524 * Construct a tvbuff containing the amount of the payload we have
1525 * available. Make its reported length the amount of data in the PDU.
1527 * XXX - if reassembly isn't enabled. the subdissector will throw a
1528 * BoundsError exception, rather than a ReportedBoundsError exception.
1529 * We really want a tvbuff where the length is "length", the reported
1530 * length is "plen", and the "if the snapshot length were infinite"
1531 * length is the minimum of the reported length of the tvbuff handed
1532 * to us and "plen", with a new type of exception thrown if the offset
1533 * is within the reported length but beyond that third length, with
1534 * that exception getting the "Unreassembled Packet" error.
1536 length = length_remaining;
1539 next_tvb = tvb_new_subset(tvb, offset, length, plen);
1544 * Catch the ReportedBoundsError exception; if this particular message
1545 * happens to get a ReportedBoundsError exception, that doesn't mean
1546 * that we should stop dissecting PDUs within this frame or chunk of
1549 * If it gets a BoundsError, we can stop, as there's nothing more to
1550 * see, so we just re-throw it.
1553 (*dissect_pdu)(next_tvb, pinfo, tree);
1555 CATCH(BoundsError) {
1558 CATCH(ReportedBoundsError) {
1559 show_reported_bounds_error(tvb, pinfo, tree);
1564 * Step to the next PDU.
1565 * Make sure we don't overflow.
1567 offset_before = offset;
1569 if (offset <= offset_before)
1575 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
1577 if (check_col(pinfo->cinfo, COL_INFO))
1578 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
1582 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
1583 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1587 mss = tvb_get_ntohs(tvb, offset + 2);
1588 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_mss, tvb, offset,
1590 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
1591 optlen, mss, "%s: %u bytes", optp->name, mss);
1592 tcp_info_append_uint(pinfo, "MSS", mss);
1596 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
1597 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1600 struct tcp_analysis *tcpd=NULL;
1602 tcpd=get_tcp_conversation_data(pinfo);
1604 ws = tvb_get_guint8(tvb, offset + 2);
1605 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_wscale, tvb,
1606 offset, optlen, TRUE);
1607 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
1608 offset, optlen, ws, "%s: %u (multiply by %u)",
1609 optp->name, ws, 1 << ws);
1610 tcp_info_append_uint(pinfo, "WS", ws);
1611 if(!pinfo->fd->flags.visited && tcp_analyze_seq && tcp_relative_seq){
1612 pdu_store_window_scale_option(ws, tcpd);
1617 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
1618 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1620 proto_tree *field_tree = NULL;
1621 proto_item *tf=NULL;
1622 guint32 leftedge, rightedge;
1623 struct tcp_analysis *tcpd=NULL;
1626 if(tcp_analyze_seq && tcp_relative_seq){
1627 /* find(or create if needed) the conversation for this tcp session */
1628 tcpd=get_tcp_conversation_data(pinfo);
1630 base_ack=tcpd->rev->base_seq;
1633 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
1634 offset += 2; /* skip past type and length */
1635 optlen -= 2; /* subtract size of type and length */
1636 while (optlen > 0) {
1637 if (field_tree == NULL) {
1638 /* Haven't yet made a subtree out of this option. Do so. */
1639 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1640 proto_tree_add_boolean_hidden(field_tree, hf_tcp_option_sack, tvb,
1641 offset, optlen, TRUE);
1644 proto_tree_add_text(field_tree, tvb, offset, optlen,
1645 "(suboption would go past end of option)");
1648 leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
1649 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
1650 offset, 4, leftedge,
1651 "left edge = %u%s", leftedge,
1652 tcp_relative_seq ? " (relative)" : "");
1656 proto_tree_add_text(field_tree, tvb, offset, optlen,
1657 "(suboption would go past end of option)");
1660 /* XXX - check whether it goes past end of packet */
1661 rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
1663 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
1664 offset+4, 4, rightedge,
1665 "right edge = %u%s", rightedge,
1666 tcp_relative_seq ? " (relative)" : "");
1667 tcp_info_append_uint(pinfo, "SLE", leftedge);
1668 tcp_info_append_uint(pinfo, "SRE", rightedge);
1669 proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
1675 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
1676 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1680 echo = tvb_get_ntohl(tvb, offset + 2);
1681 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_echo, tvb, offset,
1683 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1684 "%s: %u", optp->name, echo);
1685 tcp_info_append_uint(pinfo, "ECHO", echo);
1689 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
1690 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1694 tsv = tvb_get_ntohl(tvb, offset + 2);
1695 tser = tvb_get_ntohl(tvb, offset + 6);
1696 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_time_stamp, tvb,
1697 offset, optlen, TRUE);
1698 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1699 "%s: TSval %u, TSecr %u", optp->name, tsv, tser);
1700 tcp_info_append_uint(pinfo, "TSV", tsv);
1701 tcp_info_append_uint(pinfo, "TSER", tser);
1705 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
1706 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1710 cc = tvb_get_ntohl(tvb, offset + 2);
1711 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_cc, tvb, offset,
1713 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1714 "%s: %u", optp->name, cc);
1715 tcp_info_append_uint(pinfo, "CC", cc);
1718 static const ip_tcp_opt tcpopts[] = {
1737 "Maximum segment size",
1741 dissect_tcpopt_maxseg
1749 dissect_tcpopt_wscale
1762 &ett_tcp_option_sack,
1789 dissect_tcpopt_timestamp
1817 "TCP MD5 signature",
1825 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
1827 /* Determine if there is a sub-dissector and call it; return TRUE
1828 if there was a sub-dissector, FALSE otherwise.
1830 This has been separated into a stand alone routine to other protocol
1831 dissectors can call to it, e.g., SOCKS. */
1833 static gboolean try_heuristic_first = FALSE;
1836 /* this function can be called with tcpd==NULL as from the msproxy dissector */
1838 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
1839 proto_tree *tree, int src_port, int dst_port,
1840 struct tcp_analysis *tcpd)
1843 int low_port, high_port;
1844 int save_desegment_offset;
1845 guint32 save_desegment_len;
1847 /* dont call subdissectors for keepalive or zerowindowprobes
1848 * even though they do contain payload "data"
1849 * keeaplives just contain garbage and zwp contain too little data (1 byte)
1852 if(tcpd && tcpd->ta){
1853 if(tcpd->ta->flags&(TCP_A_ZERO_WINDOW_PROBE|TCP_A_KEEP_ALIVE)){
1858 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1860 /* determine if this packet is part of a conversation and call dissector */
1861 /* for the conversation if available */
1863 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
1864 src_port, dst_port, next_tvb, pinfo, tree)){
1865 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
1869 if (try_heuristic_first) {
1870 /* do lookup with the heuristic subdissector table */
1871 save_desegment_offset = pinfo->desegment_offset;
1872 save_desegment_len = pinfo->desegment_len;
1873 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
1874 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
1878 * They rejected the packet; make sure they didn't also request
1879 * desegmentation (we could just override the request, but
1880 * rejecting a packet *and* requesting desegmentation is a sign
1881 * of the dissector's code needing clearer thought, so we fail
1882 * so that the problem is made more obvious).
1884 DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
1885 save_desegment_len == pinfo->desegment_len);
1888 /* Do lookups with the subdissector table.
1889 We try the port number with the lower value first, followed by the
1890 port number with the higher value. This means that, for packets
1891 where a dissector is registered for *both* port numbers:
1893 1) we pick the same dissector for traffic going in both directions;
1895 2) we prefer the port number that's more likely to be the right
1896 one (as that prefers well-known ports to reserved ports);
1898 although there is, of course, no guarantee that any such strategy
1899 will always pick the right port number.
1901 XXX - we ignore port numbers of 0, as some dissectors use a port
1902 number of 0 to disable the port. */
1903 if (src_port > dst_port) {
1904 low_port = dst_port;
1905 high_port = src_port;
1907 low_port = src_port;
1908 high_port = dst_port;
1910 if (low_port != 0 &&
1911 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree)){
1912 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
1915 if (high_port != 0 &&
1916 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree)){
1917 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
1921 if (!try_heuristic_first) {
1922 /* do lookup with the heuristic subdissector table */
1923 save_desegment_offset = pinfo->desegment_offset;
1924 save_desegment_len = pinfo->desegment_len;
1925 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
1926 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
1930 * They rejected the packet; make sure they didn't also request
1931 * desegmentation (we could just override the request, but
1932 * rejecting a packet *and* requesting desegmentation is a sign
1933 * of the dissector's code needing clearer thought, so we fail
1934 * so that the problem is made more obvious).
1936 DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
1937 save_desegment_len == pinfo->desegment_len);
1940 /* Oh, well, we don't know this; dissect it as data. */
1941 call_dissector(data_handle,next_tvb, pinfo, tree);
1943 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
1948 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
1949 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
1950 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
1951 struct tcp_analysis *tcpd)
1953 pinfo->want_pdu_tracking=0;
1957 /*qqq see if it is an unaligned PDU */
1958 if(tcp_analyze_seq && (!tcp_desegment)){
1960 offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
1965 /* if offset is -1 this means that this segment is known
1966 * to be fully inside a previously detected pdu
1967 * so we dont even need to try to dissect it either.
1970 decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
1973 * We succeeded in handing off to a subdissector.
1975 * Is this a TCP segment or a reassembled chunk of
1979 /* if !visited, check want_pdu_tracking and
1980 store it in table */
1981 if((!pinfo->fd->flags.visited) &&
1982 tcp_analyze_seq && pinfo->want_pdu_tracking){
1984 pdu_store_sequencenumber_of_next_pdu(
1987 nxtseq+pinfo->bytes_until_next_pdu,
1995 /* We got an exception. At this point the dissection is
1996 * completely aborted and execution will be transfered back
1997 * to (probably) the frame dissector.
1998 * Here we have to place whatever we want the dissector
1999 * to do before aborting the tcp dissection.
2002 * Is this a TCP segment or a reassembled chunk of TCP
2007 * It's from a TCP segment.
2009 * if !visited, check want_pdu_tracking and store it
2012 if((!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking){
2014 pdu_store_sequencenumber_of_next_pdu(pinfo,
2016 nxtseq+pinfo->bytes_until_next_pdu,
2027 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
2028 guint32 nxtseq, guint32 sport, guint32 dport,
2029 proto_tree *tree, proto_tree *tcp_tree,
2030 struct tcp_analysis *tcpd)
2032 gboolean save_fragmented;
2034 /* Can we desegment this segment? */
2035 if (pinfo->can_desegment) {
2037 desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
2040 /* No - just call the subdissector.
2041 Mark this as fragmented, so if somebody throws an exception,
2042 we don't report it as a malformed frame. */
2043 save_fragmented = pinfo->fragmented;
2044 pinfo->fragmented = TRUE;
2045 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
2046 seq, nxtseq, TRUE, tcpd);
2047 pinfo->fragmented = save_fragmented;
2052 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2054 guint8 th_off_x2; /* combines th_off and th_x2 */
2057 proto_tree *tcp_tree = NULL, *field_tree = NULL;
2058 proto_item *ti = NULL, *tf;
2060 gchar *flags = "<None>";
2061 const gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
2062 size_t fpos = 0, returned_length;
2070 guint16 computed_cksum;
2071 guint16 real_window;
2072 guint length_remaining;
2073 gboolean desegment_ok;
2074 struct tcpinfo tcpinfo;
2075 struct tcpheader *tcph;
2076 proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
2077 struct tcp_analysis *tcpd=NULL;
2079 tcph=ep_alloc(sizeof(struct tcpheader));
2080 SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
2081 SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
2083 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2084 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2086 /* Clear out the Info column. */
2087 if (check_col(pinfo->cinfo, COL_INFO))
2088 col_clear(pinfo->cinfo, COL_INFO);
2090 tcph->th_sport = tvb_get_ntohs(tvb, offset);
2091 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
2092 if (check_col(pinfo->cinfo, COL_INFO)) {
2093 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
2094 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2097 if (tcp_summary_in_tree) {
2098 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
2099 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
2100 get_tcp_port(tcph->th_sport), tcph->th_sport,
2101 get_tcp_port(tcph->th_dport), tcph->th_dport);
2104 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
2106 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
2107 pinfo->tcp_tree=tcp_tree;
2109 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
2110 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
2111 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
2112 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
2113 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
2114 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
2117 /* Set the source and destination port numbers as soon as we get them,
2118 so that they're available to the "Follow TCP Stream" code even if
2119 we throw an exception dissecting the rest of the TCP header. */
2120 pinfo->ptype = PT_TCP;
2121 pinfo->srcport = tcph->th_sport;
2122 pinfo->destport = tcph->th_dport;
2124 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
2125 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
2126 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
2127 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
2128 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
2129 real_window = tcph->th_win;
2130 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
2132 /* find(or create if needed) the conversation for this tcp session */
2133 tcpd=get_tcp_conversation_data(pinfo);
2136 * If we've been handed an IP fragment, we don't know how big the TCP
2137 * segment is, so don't do anything that requires that we know that.
2139 * The same applies if we're part of an error packet. (XXX - if the
2140 * ICMP and ICMPv6 dissectors could set a "this is how big the IP
2141 * header says it is" length in the tvbuff, we could use that; such
2142 * a length might also be useful for handling packets where the IP
2143 * length is bigger than the actual data available in the frame; the
2144 * dissectors should trust that length, and then throw a
2145 * ReportedBoundsError exception when they go past the end of the frame.)
2147 * We also can't determine the segment length if the reported length
2148 * of the TCP packet is less than the TCP header length.
2150 reported_len = tvb_reported_length(tvb);
2152 if (!pinfo->fragmented && !pinfo->in_error_pkt) {
2153 if (reported_len < tcph->th_hlen) {
2155 pi = proto_tree_add_text(tcp_tree, tvb, offset, 0,
2156 "Short segment. Segment/fragment does not contain a full TCP header"
2157 " (might be NMAP or someone else deliberately sending unusual packets)");
2158 PROTO_ITEM_SET_GENERATED(pi);
2159 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_WARN, "Short segment");
2160 tcph->th_have_seglen = FALSE;
2162 /* Compute the length of data in this segment. */
2163 tcph->th_seglen = reported_len - tcph->th_hlen;
2164 tcph->th_have_seglen = TRUE;
2166 if (tree) { /* Add the seglen as an invisible field */
2168 proto_tree_add_uint_hidden(ti, hf_tcp_len, tvb, offset, 4, tcph->th_seglen);
2173 /* handle TCP seq# analysis parse all new segments we see */
2174 if(tcp_analyze_seq){
2175 if(!(pinfo->fd->flags.visited)){
2176 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
2178 if(tcp_relative_seq){
2179 tcp_get_relative_seq_ack(&(tcph->th_seq), &(tcph->th_ack), &(tcph->th_win), tcpd);
2183 /* Compute the sequence number of next octet after this segment. */
2184 nxtseq = tcph->th_seq + tcph->th_seglen;
2187 tcph->th_have_seglen = FALSE;
2189 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
2190 #define MAX_FLAGS_LEN 64
2191 flags=ep_alloc(MAX_FLAGS_LEN);
2193 for (i = 0; i < 8; i++) {
2195 if (tcph->th_flags & bpos) {
2196 returned_length = g_snprintf(&flags[fpos], MAX_FLAGS_LEN-fpos, "%s%s",
2199 fpos += MIN(returned_length, MAX_FLAGS_LEN-fpos);
2204 if (check_col(pinfo->cinfo, COL_INFO)) {
2205 if(tcph->th_flags&TH_ACK){
2206 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
2207 flags, tcph->th_seq, tcph->th_ack, tcph->th_win);
2209 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u",
2210 flags, tcph->th_seq);
2215 if (tcp_summary_in_tree) {
2216 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
2218 if(tcp_relative_seq){
2219 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);
2221 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
2225 if (tcph->th_hlen < TCPH_MIN_LEN) {
2226 /* Give up at this point; we put the source and destination port in
2227 the tree, before fetching the header length, so that they'll
2228 show up if this is in the failing packet in an ICMP error packet,
2229 but it's now time to give up if the header length is bogus. */
2230 if (check_col(pinfo->cinfo, COL_INFO))
2231 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
2232 tcph->th_hlen, TCPH_MIN_LEN);
2234 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2235 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
2242 if (tcp_summary_in_tree) {
2243 if(tcph->th_flags&TH_ACK){
2244 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
2246 if (tcph->th_have_seglen)
2247 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
2249 proto_item_set_len(ti, tcph->th_hlen);
2250 if (tcph->th_have_seglen) {
2251 if (nxtseq != tcph->th_seq) {
2252 if(tcp_relative_seq){
2253 tf=proto_tree_add_uint_format(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "Next sequence number: %u (relative sequence number)", nxtseq);
2255 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
2257 PROTO_ITEM_SET_GENERATED(tf);
2260 if (tcph->th_flags & TH_ACK) {
2261 if(tcp_relative_seq){
2262 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);
2264 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
2267 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
2268 "Header length: %u bytes", tcph->th_hlen);
2269 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
2270 tcph->th_flags, "Flags: 0x%02x (%s)", tcph->th_flags, flags);
2271 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
2272 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
2273 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
2274 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
2275 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
2276 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
2277 tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
2278 tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
2279 tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
2281 && (tcph->th_win!=real_window)
2282 && !(tcph->th_flags&TH_SYN) ){ /* SYNs are never scaled */
2283 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);
2285 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, real_window);
2289 if(tcph->th_flags & TH_SYN) {
2290 if(tcph->th_flags & TH_ACK)
2291 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): server port %s",
2292 get_tcp_port(tcph->th_sport));
2294 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): server port %s",
2295 get_tcp_port(tcph->th_dport));
2297 if(tcph->th_flags & TH_FIN)
2298 /* XXX - find a way to know the server port and output only that one */
2299 expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN)");
2300 if(tcph->th_flags & TH_RST)
2301 /* XXX - find a way to know the server port and output only that one */
2302 expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST)");
2304 /* Supply the sequence number of the first byte and of the first byte
2305 after the segment. */
2306 tcpinfo.seq = tcph->th_seq;
2307 tcpinfo.nxtseq = nxtseq;
2309 /* Assume we'll pass un-reassembled data to subdissectors. */
2310 tcpinfo.is_reassembled = FALSE;
2312 pinfo->private_data = &tcpinfo;
2315 * Assume, initially, that we can't desegment.
2317 pinfo->can_desegment = 0;
2318 th_sum = tvb_get_ntohs(tvb, offset + 16);
2319 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
2320 /* The packet isn't part of an un-reassembled fragmented datagram
2321 and isn't truncated. This means we have all the data, and thus
2322 can checksum it and, unless it's being returned in an error
2323 packet, are willing to allow subdissectors to request reassembly
2326 if (tcp_check_checksum) {
2327 /* We haven't turned checksum checking off; checksum it. */
2329 /* Set up the fields of the pseudo-header. */
2330 cksum_vec[0].ptr = pinfo->src.data;
2331 cksum_vec[0].len = pinfo->src.len;
2332 cksum_vec[1].ptr = pinfo->dst.data;
2333 cksum_vec[1].len = pinfo->dst.len;
2334 cksum_vec[2].ptr = (const guint8 *)&phdr;
2335 switch (pinfo->src.type) {
2338 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
2339 cksum_vec[2].len = 4;
2343 phdr[0] = g_htonl(reported_len);
2344 phdr[1] = g_htonl(IP_PROTO_TCP);
2345 cksum_vec[2].len = 8;
2349 /* TCP runs only atop IPv4 and IPv6.... */
2350 DISSECTOR_ASSERT_NOT_REACHED();
2353 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
2354 cksum_vec[3].len = reported_len;
2355 computed_cksum = in_cksum(&cksum_vec[0], 4);
2356 if (computed_cksum == 0) {
2357 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2358 offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
2360 /* Checksum is valid, so we're willing to desegment it. */
2361 desegment_ok = TRUE;
2362 } else if (th_sum == 0) {
2363 /* checksum is probably fine but checksum offload is used */
2364 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2365 offset + 16, 2, th_sum, "Checksum: 0x%04x [Checksum Offloaded]", th_sum);
2367 /* Checksum is (probably) valid, so we're willing to desegment it. */
2368 desegment_ok = TRUE;
2372 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2373 offset + 16, 2, th_sum,
2374 "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by checksum offloading?)]", th_sum,
2375 in_cksum_shouldbe(th_sum, computed_cksum));
2376 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
2377 item = proto_tree_add_boolean(tcp_tree, hf_tcp_checksum_bad, tvb,
2378 offset + 16, 2, TRUE);
2379 PROTO_ITEM_SET_GENERATED(item);
2380 /* XXX - don't use hidden fields for checksums */
2381 PROTO_ITEM_SET_HIDDEN(item);
2383 if (check_col(pinfo->cinfo, COL_INFO))
2384 col_append_fstr(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
2386 /* Checksum is invalid, so we're not willing to desegment it. */
2387 desegment_ok = FALSE;
2388 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
2391 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2392 offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
2394 /* We didn't check the checksum, and don't care if it's valid,
2395 so we're willing to desegment it. */
2396 desegment_ok = TRUE;
2399 /* We don't have all the packet data, so we can't checksum it... */
2400 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2401 offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
2403 /* ...and aren't willing to desegment it. */
2404 desegment_ok = FALSE;
2408 /* We're willing to desegment this. Is desegmentation enabled? */
2409 if (tcp_desegment) {
2410 /* Yes - is this segment being returned in an error packet? */
2411 if (!pinfo->in_error_pkt) {
2412 /* No - indicate that we will desegment.
2413 We do NOT want to desegment segments returned in error
2414 packets, as they're not part of a TCP connection. */
2415 pinfo->can_desegment = 2;
2420 if (tcph->th_flags & TH_URG) {
2421 th_urp = tvb_get_ntohs(tvb, offset + 18);
2422 /* Export the urgent pointer, for the benefit of protocols such as
2424 tcpinfo.urgent = TRUE;
2425 tcpinfo.urgent_pointer = th_urp;
2426 if (check_col(pinfo->cinfo, COL_INFO))
2427 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
2428 if (tcp_tree != NULL)
2429 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
2431 tcpinfo.urgent = FALSE;
2433 if (tcph->th_have_seglen) {
2434 if (check_col(pinfo->cinfo, COL_INFO))
2435 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
2438 /* Decode TCP options, if any. */
2439 if (tcph->th_hlen > TCPH_MIN_LEN) {
2440 /* There's more than just the fixed-length header. Decode the
2442 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
2443 tvb_ensure_bytes_exist(tvb, offset + 20, optlen);
2444 if (tcp_tree != NULL) {
2445 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
2446 "Options: (%u bytes)", optlen);
2447 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
2450 dissect_ip_tcp_options(tvb, offset + 20, optlen,
2451 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
2454 /* If there was window scaling in the SYN packet but none in the SYN+ACK
2455 * then we should just forget about the windowscaling completely.
2457 if(!pinfo->fd->flags.visited){
2458 if(tcp_analyze_seq && tcp_relative_seq){
2459 if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
2460 verify_tcp_window_scaling(tcpd);
2465 /* Skip over header + options */
2466 offset += tcph->th_hlen;
2468 /* Check the packet length to see if there's more data
2469 (it could be an ACK-only packet) */
2470 length_remaining = tvb_length_remaining(tvb, offset);
2472 if (tcph->th_have_seglen) {
2473 if( data_out_file ) {
2474 reassemble_tcp( tcph->th_seq, /* sequence number */
2475 tcph->th_seglen, /* data length */
2476 tvb_get_ptr(tvb, offset, length_remaining), /* data */
2477 length_remaining, /* captured data length */
2478 ( tcph->th_flags & TH_SYN ), /* is syn set? */
2486 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
2487 if(tcp_analyze_seq){
2488 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd);
2490 tap_queue_packet(tcp_tap, pinfo, tcph);
2493 /* A FIN packet might complete reassembly so we need to explicitely
2494 * check for this here.
2495 * If this segment completes reassembly we add the FIN as a final dummy
2496 * byte to the reassembled PDU and check if reassembly completed successfully
2498 if( (tcph->th_flags & TH_FIN)
2499 && (tcpd->fwd->flags&TCP_FLOW_REASSEMBLE_UNTIL_FIN) ){
2500 struct tcp_multisegment_pdu *msp;
2502 /* find the most previous PDU starting before this sequence number */
2503 msp=se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, tcph->th_seq-1);
2505 fragment_data *ipfd_head;
2507 ipfd_head = fragment_add(tvb, offset-1, pinfo, msp->first_frame,
2509 tcph->th_seq - msp->seq,
2515 /* create a new TVB structure for desegmented data
2516 * datalen-1 to strip the dummy FIN byte off
2518 next_tvb = tvb_new_real_data(ipfd_head->data, ipfd_head->datalen-1, ipfd_head->datalen-1);
2520 /* add this tvb as a child to the original one */
2521 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
2523 /* add desegmented data to the data source list */
2524 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
2526 /* call the payload dissector
2527 * but make sure we dont offer desegmentation any more
2529 pinfo->can_desegment = 0;
2531 process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, tcph->th_sport, tcph->th_dport, tcph->th_seq, nxtseq, FALSE, tcpd);
2539 * XXX - what, if any, of this should we do if this is included in an
2540 * error packet? It might be nice to see the details of the packet
2541 * that caused the ICMP error, but it might not be nice to have the
2542 * dissector update state based on it.
2543 * Also, we probably don't want to run TCP taps on those packets.
2545 if (length_remaining != 0) {
2546 if (tcph->th_flags & TH_RST) {
2550 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
2552 * A TCP SHOULD allow a received RST segment to include data.
2555 * It has been suggested that a RST segment could contain
2556 * ASCII text that encoded and explained the cause of the
2557 * RST. No standard has yet been established for such
2560 * so for segments with RST we just display the data as text.
2562 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
2564 tvb_format_text(tvb, offset, length_remaining));
2566 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
2567 tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd);
2573 proto_register_tcp(void)
2575 static hf_register_info hf[] = {
2578 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
2582 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
2586 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
2590 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
2594 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
2598 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
2602 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2606 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2609 { &hf_tcp_flags_cwr,
2610 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
2613 { &hf_tcp_flags_ecn,
2614 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
2617 { &hf_tcp_flags_urg,
2618 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
2621 { &hf_tcp_flags_ack,
2622 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
2625 { &hf_tcp_flags_push,
2626 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
2629 { &hf_tcp_flags_reset,
2630 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
2633 { &hf_tcp_flags_syn,
2634 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
2637 { &hf_tcp_flags_fin,
2638 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
2641 /* 32 bits so we can present some values adjusted to window scaling */
2642 { &hf_tcp_window_size,
2643 { "Window size", "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
2647 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
2648 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
2650 { &hf_tcp_checksum_bad,
2651 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2652 "Maybe caused by checksum offloading, see: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
2654 { &hf_tcp_analysis_flags,
2655 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
2656 "This frame has some of the TCP analysis flags set", HFILL }},
2658 { &hf_tcp_analysis_retransmission,
2659 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2660 "This frame is a suspected TCP retransmission", HFILL }},
2662 { &hf_tcp_analysis_fast_retransmission,
2663 { "Fast Retransmission", "tcp.analysis.fast_retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2664 "This frame is a suspected TCP fast retransmission", HFILL }},
2666 { &hf_tcp_analysis_out_of_order,
2667 { "Out Of Order", "tcp.analysis.out_of_order", FT_NONE, BASE_NONE, NULL, 0x0,
2668 "This frame is a suspected Out-Of-Order segment", HFILL }},
2670 { &hf_tcp_analysis_lost_packet,
2671 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2672 "A segment before this one was lost from the capture", HFILL }},
2674 { &hf_tcp_analysis_ack_lost_packet,
2675 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2676 "This frame ACKs a lost segment", HFILL }},
2678 { &hf_tcp_analysis_window_update,
2679 { "Window update", "tcp.analysis.window_update", FT_NONE, BASE_NONE, NULL, 0x0,
2680 "This frame is a tcp window update", HFILL }},
2682 { &hf_tcp_analysis_window_full,
2683 { "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
2684 "This segment has caused the allowed window to become 100% full", HFILL }},
2686 { &hf_tcp_analysis_keep_alive,
2687 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
2688 "This is a keep-alive segment", HFILL }},
2690 { &hf_tcp_analysis_keep_alive_ack,
2691 { "Keep Alive ACK", "tcp.analysis.keep_alive_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2692 "This is an ACK to a keep-alive segment", HFILL }},
2694 { &hf_tcp_analysis_duplicate_ack,
2695 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2696 "This is a duplicate ACK", HFILL }},
2698 { &hf_tcp_analysis_duplicate_ack_num,
2699 { "Duplicate ACK #", "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
2700 "This is duplicate ACK number #", HFILL }},
2702 { &hf_tcp_analysis_duplicate_ack_frame,
2703 { "Duplicate to the ACK in frame", "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2704 "This is a duplicate to the ACK in frame #", HFILL }},
2706 { &hf_tcp_continuation_to,
2707 { "This is a continuation to the PDU in frame", "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2708 "This is a continuation to the PDU in frame #", HFILL }},
2710 { &hf_tcp_analysis_zero_window_probe,
2711 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
2712 "This is a zero-window-probe", HFILL }},
2714 { &hf_tcp_analysis_zero_window_probe_ack,
2715 { "Zero Window Probe Ack", "tcp.analysis.zero_window_probe_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2716 "This is an ACK to a zero-window-probe", HFILL }},
2718 { &hf_tcp_analysis_zero_window,
2719 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
2720 "This is a zero-window", HFILL }},
2723 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
2726 { &hf_tcp_analysis_acks_frame,
2727 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2728 "Which previous segment is this an ACK for", HFILL}},
2730 { &hf_tcp_analysis_ack_rtt,
2731 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2732 "How long time it took to ACK the segment (RTT)", HFILL}},
2734 { &hf_tcp_analysis_rto,
2735 { "The RTO for this segment was", "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2736 "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
2738 { &hf_tcp_analysis_rto_frame,
2739 { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2740 "This is the frame we measure the RTO from", HFILL }},
2742 { &hf_tcp_urgent_pointer,
2743 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
2746 { &hf_tcp_segment_overlap,
2747 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2748 "Segment overlaps with other segments", HFILL }},
2750 { &hf_tcp_segment_overlap_conflict,
2751 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2752 "Overlapping segments contained conflicting data", HFILL }},
2754 { &hf_tcp_segment_multiple_tails,
2755 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2756 "Several tails were found when reassembling the pdu", HFILL }},
2758 { &hf_tcp_segment_too_long_fragment,
2759 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2760 "Segment contained data past end of the pdu", HFILL }},
2762 { &hf_tcp_segment_error,
2763 { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2764 "Reassembling error due to illegal segments", HFILL }},
2767 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2768 "TCP Segment", HFILL }},
2771 { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
2772 "TCP Segments", HFILL }},
2774 { &hf_tcp_reassembled_in,
2775 { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2776 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
2778 { &hf_tcp_option_mss,
2779 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
2780 BASE_NONE, NULL, 0x0, "TCP MSS Option", HFILL }},
2782 { &hf_tcp_option_mss_val,
2783 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
2784 BASE_DEC, NULL, 0x0, "TCP MSS Option Value", HFILL}},
2786 { &hf_tcp_option_wscale,
2787 { "TCP Window Scale Option", "tcp.options.wscale",
2789 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
2791 { &hf_tcp_option_wscale_val,
2792 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
2793 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
2796 { &hf_tcp_option_sack_perm,
2797 { "TCP Sack Perm Option", "tcp.options.sack_perm",
2799 BASE_NONE, NULL, 0x0, "TCP Sack Perm Option", HFILL}},
2801 { &hf_tcp_option_sack,
2802 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
2803 BASE_NONE, NULL, 0x0, "TCP Sack Option", HFILL}},
2805 { &hf_tcp_option_sack_sle,
2806 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
2807 BASE_DEC, NULL, 0x0, "TCP Sack Left Edge", HFILL}},
2809 { &hf_tcp_option_sack_sre,
2810 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
2811 BASE_DEC, NULL, 0x0, "TCP Sack Right Edge", HFILL}},
2813 { &hf_tcp_option_echo,
2814 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
2815 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
2817 { &hf_tcp_option_echo_reply,
2818 { "TCP Echo Reply Option", "tcp.options.echo_reply",
2820 BASE_NONE, NULL, 0x0, "TCP Echo Reply Option", HFILL}},
2822 { &hf_tcp_option_time_stamp,
2823 { "TCP Time Stamp Option", "tcp.options.time_stamp",
2825 BASE_NONE, NULL, 0x0, "TCP Time Stamp Option", HFILL}},
2827 { &hf_tcp_option_cc,
2828 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
2829 NULL, 0x0, "TCP CC Option", HFILL}},
2831 { &hf_tcp_option_ccnew,
2832 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
2833 BASE_NONE, NULL, 0x0, "TCP CC New Option", HFILL}},
2835 { &hf_tcp_option_ccecho,
2836 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
2837 BASE_NONE, NULL, 0x0, "TCP CC Echo Option", HFILL}},
2839 { &hf_tcp_option_md5,
2840 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
2841 NULL, 0x0, "TCP MD5 Option", HFILL}},
2844 { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2845 "How long time has passed until the last frame of this PDU", HFILL}},
2847 { "PDU Size", "tcp.pdu.size", FT_UINT32, BASE_DEC, NULL, 0x0,
2848 "The size of this PDU", HFILL}},
2850 { &hf_tcp_pdu_last_frame,
2851 { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2852 "This is the last frame of the PDU starting in this segment", HFILL }},
2855 static gint *ett[] = {
2859 &ett_tcp_option_sack,
2860 &ett_tcp_analysis_faults,
2865 module_t *tcp_module;
2867 proto_tcp = proto_register_protocol("Transmission Control Protocol",
2869 proto_register_field_array(proto_tcp, hf, array_length(hf));
2870 proto_register_subtree_array(ett, array_length(ett));
2872 /* subdissector code */
2873 subdissector_table = register_dissector_table("tcp.port",
2874 "TCP port", FT_UINT16, BASE_DEC);
2875 register_heur_dissector_list("tcp", &heur_subdissector_list);
2877 /* Register configuration preferences */
2878 tcp_module = prefs_register_protocol(proto_tcp, NULL);
2879 prefs_register_bool_preference(tcp_module, "summary_in_tree",
2880 "Show TCP summary in protocol tree",
2881 "Whether the TCP summary line should be shown in the protocol tree",
2882 &tcp_summary_in_tree);
2883 prefs_register_bool_preference(tcp_module, "check_checksum",
2884 "Validate the TCP checksum if possible",
2885 "Whether to validate the TCP checksum",
2886 &tcp_check_checksum);
2887 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
2888 "Allow subdissector to reassemble TCP streams",
2889 "Whether subdissector can request TCP streams to be reassembled",
2891 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
2892 "Analyze TCP sequence numbers",
2893 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
2895 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
2896 "Relative sequence numbers and window scaling",
2897 "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
2898 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
2899 "This option will also try to track and adjust the window field according to any TCP window scaling options seen.",
2901 prefs_register_bool_preference(tcp_module, "try_heuristic_first",
2902 "Try heuristic sub-dissectors first",
2903 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
2904 &try_heuristic_first);
2906 register_init_routine(tcp_fragment_init);
2910 proto_reg_handoff_tcp(void)
2912 dissector_handle_t tcp_handle;
2914 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
2915 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
2916 data_handle = find_dissector("data");
2917 tcp_tap = register_tap("tcp");