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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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-frame.h"
43 #include <epan/conversation.h>
44 #include <epan/reassemble.h>
46 #include <epan/slab.h>
47 #include <epan/expert.h>
49 static int tcp_tap = -1;
51 /* Place TCP summary in proto tree */
52 static gboolean tcp_summary_in_tree = TRUE;
55 * Flag to control whether to check the TCP checksum.
57 * In at least some Solaris network traces, there are packets with bad
58 * TCP checksums, but the traffic appears to indicate that the packets
59 * *were* received; the packets were probably sent by the host on which
60 * the capture was being done, on a network interface to which
61 * checksumming was offloaded, so that DLPI supplied an un-checksummed
62 * packet to the capture program but a checksummed packet got put onto
65 static gboolean tcp_check_checksum = FALSE;
67 extern FILE* data_out_file;
69 static int proto_tcp = -1;
70 static int hf_tcp_srcport = -1;
71 static int hf_tcp_dstport = -1;
72 static int hf_tcp_port = -1;
73 static int hf_tcp_stream = -1;
74 static int hf_tcp_seq = -1;
75 static int hf_tcp_nxtseq = -1;
76 static int hf_tcp_ack = -1;
77 static int hf_tcp_hdr_len = -1;
78 static int hf_tcp_flags = -1;
79 static int hf_tcp_flags_cwr = -1;
80 static int hf_tcp_flags_ecn = -1;
81 static int hf_tcp_flags_urg = -1;
82 static int hf_tcp_flags_ack = -1;
83 static int hf_tcp_flags_push = -1;
84 static int hf_tcp_flags_reset = -1;
85 static int hf_tcp_flags_syn = -1;
86 static int hf_tcp_flags_fin = -1;
87 static int hf_tcp_window_size = -1;
88 static int hf_tcp_checksum = -1;
89 static int hf_tcp_checksum_bad = -1;
90 static int hf_tcp_checksum_good = -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_bytes_in_flight = -1;
95 static int hf_tcp_analysis_acks_frame = -1;
96 static int hf_tcp_analysis_ack_rtt = -1;
97 static int hf_tcp_analysis_rto = -1;
98 static int hf_tcp_analysis_rto_frame = -1;
99 static int hf_tcp_analysis_retransmission = -1;
100 static int hf_tcp_analysis_fast_retransmission = -1;
101 static int hf_tcp_analysis_out_of_order = -1;
102 static int hf_tcp_analysis_reused_ports = -1;
103 static int hf_tcp_analysis_lost_packet = -1;
104 static int hf_tcp_analysis_ack_lost_packet = -1;
105 static int hf_tcp_analysis_window_update = -1;
106 static int hf_tcp_analysis_window_full = -1;
107 static int hf_tcp_analysis_keep_alive = -1;
108 static int hf_tcp_analysis_keep_alive_ack = -1;
109 static int hf_tcp_analysis_duplicate_ack = -1;
110 static int hf_tcp_analysis_duplicate_ack_num = -1;
111 static int hf_tcp_analysis_duplicate_ack_frame = -1;
112 static int hf_tcp_analysis_zero_window = -1;
113 static int hf_tcp_analysis_zero_window_probe = -1;
114 static int hf_tcp_analysis_zero_window_probe_ack = -1;
115 static int hf_tcp_continuation_to = -1;
116 static int hf_tcp_pdu_time = -1;
117 static int hf_tcp_pdu_size = -1;
118 static int hf_tcp_pdu_last_frame = -1;
119 static int hf_tcp_reassembled_in = -1;
120 static int hf_tcp_segments = -1;
121 static int hf_tcp_segment = -1;
122 static int hf_tcp_segment_overlap = -1;
123 static int hf_tcp_segment_overlap_conflict = -1;
124 static int hf_tcp_segment_multiple_tails = -1;
125 static int hf_tcp_segment_too_long_fragment = -1;
126 static int hf_tcp_segment_error = -1;
127 static int hf_tcp_options = -1;
128 static int hf_tcp_option_mss = -1;
129 static int hf_tcp_option_mss_val = -1;
130 static int hf_tcp_option_wscale = -1;
131 static int hf_tcp_option_wscale_val = -1;
132 static int hf_tcp_option_sack_perm = -1;
133 static int hf_tcp_option_sack = -1;
134 static int hf_tcp_option_sack_sle = -1;
135 static int hf_tcp_option_sack_sre = -1;
136 static int hf_tcp_option_echo = -1;
137 static int hf_tcp_option_echo_reply = -1;
138 static int hf_tcp_option_time_stamp = -1;
139 static int hf_tcp_option_cc = -1;
140 static int hf_tcp_option_ccnew = -1;
141 static int hf_tcp_option_ccecho = -1;
142 static int hf_tcp_option_md5 = -1;
143 static int hf_tcp_option_qs = -1;
144 static int hf_tcp_ts_relative = -1;
145 static int hf_tcp_ts_delta = -1;
146 static int hf_tcp_option_scps = -1;
147 static int hf_tcp_option_scps_vector = -1;
148 static int hf_tcp_option_scps_binding = -1;
149 static int hf_tcp_scpsoption_flags_bets = -1;
150 static int hf_tcp_scpsoption_flags_snack1 = -1;
151 static int hf_tcp_scpsoption_flags_snack2 = -1;
152 static int hf_tcp_scpsoption_flags_compress = -1;
153 static int hf_tcp_scpsoption_flags_nlts = -1;
154 static int hf_tcp_scpsoption_flags_resv1 = -1;
155 static int hf_tcp_scpsoption_flags_resv2 = -1;
156 static int hf_tcp_scpsoption_flags_resv3 = -1;
157 static int hf_tcp_option_snack = -1;
158 static int hf_tcp_option_snack_offset = -1;
159 static int hf_tcp_option_snack_size = -1;
160 static int hf_tcp_option_snack_le = -1;
161 static int hf_tcp_option_snack_re = -1;
163 static gint ett_tcp = -1;
164 static gint ett_tcp_flags = -1;
165 static gint ett_tcp_options = -1;
166 static gint ett_tcp_option_sack = -1;
167 static gint ett_tcp_option_scps = -1;
168 static gint ett_tcp_option_scps_extended = -1;
169 static gint ett_tcp_analysis = -1;
170 static gint ett_tcp_analysis_faults = -1;
171 static gint ett_tcp_timestamps = -1;
172 static gint ett_tcp_segments = -1;
173 static gint ett_tcp_segment = -1;
174 static gint ett_tcp_checksum = -1;
177 /* not all of the hf_fields below make sense for TCP but we have to provide
178 them anyways to comply with the api (which was aimed for ip fragment
180 static const fragment_items tcp_segment_items = {
185 &hf_tcp_segment_overlap,
186 &hf_tcp_segment_overlap_conflict,
187 &hf_tcp_segment_multiple_tails,
188 &hf_tcp_segment_too_long_fragment,
189 &hf_tcp_segment_error,
190 &hf_tcp_reassembled_in,
194 static dissector_table_t subdissector_table;
195 static heur_dissector_list_t heur_subdissector_list;
196 static dissector_handle_t data_handle;
198 /* TCP structs and definitions */
200 /* **************************************************************************
202 * RTT and reltive sequence numbers.
203 * **************************************************************************/
204 static gboolean tcp_analyze_seq = TRUE;
205 static gboolean tcp_relative_seq = TRUE;
206 static gboolean tcp_track_bytes_in_flight = TRUE;
207 static gboolean tcp_calculate_ts = FALSE;
209 /* SLAB allocator for tcp_unacked structures
211 SLAB_ITEM_TYPE_DEFINE(tcp_unacked_t)
212 static SLAB_FREE_LIST_DEFINE(tcp_unacked_t)
213 #define TCP_UNACKED_NEW(fi) \
214 SLAB_ALLOC(fi, tcp_unacked_t)
215 #define TCP_UNACKED_FREE(fi) \
216 SLAB_FREE(fi, tcp_unacked_t)
219 #define TCP_A_RETRANSMISSION 0x0001
220 #define TCP_A_LOST_PACKET 0x0002
221 #define TCP_A_ACK_LOST_PACKET 0x0004
222 #define TCP_A_KEEP_ALIVE 0x0008
223 #define TCP_A_DUPLICATE_ACK 0x0010
224 #define TCP_A_ZERO_WINDOW 0x0020
225 #define TCP_A_ZERO_WINDOW_PROBE 0x0040
226 #define TCP_A_ZERO_WINDOW_PROBE_ACK 0x0080
227 #define TCP_A_KEEP_ALIVE_ACK 0x0100
228 #define TCP_A_OUT_OF_ORDER 0x0200
229 #define TCP_A_FAST_RETRANSMISSION 0x0400
230 #define TCP_A_WINDOW_UPDATE 0x0800
231 #define TCP_A_WINDOW_FULL 0x1000
232 #define TCP_A_REUSED_PORTS 0x2000
236 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
237 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
238 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
239 struct tcp_analysis *tcpd);
242 struct tcp_analysis *
243 init_tcp_conversation_data(packet_info *pinfo)
245 struct tcp_analysis *tcpd=NULL;
247 /* Initialize the tcp protocol datat structure to add to the tcp conversation */
248 tcpd=se_alloc(sizeof(struct tcp_analysis));
249 tcpd->flow1.segments=NULL;
250 tcpd->flow1.base_seq=0;
251 tcpd->flow1.lastack=0;
252 tcpd->flow1.lastacktime.secs=0;
253 tcpd->flow1.lastacktime.nsecs=0;
254 tcpd->flow1.lastnondupack=0;
255 tcpd->flow1.nextseq=0;
256 tcpd->flow1.nextseqtime.secs=0;
257 tcpd->flow1.nextseqtime.nsecs=0;
258 tcpd->flow1.nextseqframe=0;
259 tcpd->flow1.window=0;
260 tcpd->flow1.win_scale=-1;
261 tcpd->flow1.scps_capable=0;
262 tcpd->flow1.maxsizeacked=0;
264 tcpd->flow1.multisegment_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_multisegment_pdus");
265 tcpd->flow2.segments=NULL;
266 tcpd->flow2.base_seq=0;
267 tcpd->flow2.lastack=0;
268 tcpd->flow2.lastacktime.secs=0;
269 tcpd->flow2.lastacktime.nsecs=0;
270 tcpd->flow2.lastnondupack=0;
271 tcpd->flow2.nextseq=0;
272 tcpd->flow2.nextseqtime.secs=0;
273 tcpd->flow2.nextseqtime.nsecs=0;
274 tcpd->flow2.nextseqframe=0;
275 tcpd->flow2.window=0;
276 tcpd->flow2.win_scale=-1;
277 tcpd->flow2.scps_capable=0;
278 tcpd->flow2.maxsizeacked=0;
280 tcpd->flow2.multisegment_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_multisegment_pdus");
281 tcpd->acked_table=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_analyze_acked_table");
282 tcpd->ts_first.secs=pinfo->fd->abs_ts.secs;
283 tcpd->ts_first.nsecs=pinfo->fd->abs_ts.nsecs;
284 tcpd->ts_prev.secs=pinfo->fd->abs_ts.secs;
285 tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs;
291 get_tcp_conversation(packet_info *pinfo)
293 conversation_t *conv=NULL;
295 /* Have we seen this conversation before? */
296 if( (conv=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
297 /* No this is a new conversation. */
298 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
303 struct tcp_analysis *
304 get_tcp_conversation_data(conversation_t *conv, packet_info *pinfo)
307 struct tcp_analysis *tcpd=NULL;
309 /* Did the caller supply the conversation pointer? */
311 conv = get_tcp_conversation(pinfo);
313 /* Get the data for this conversation */
314 tcpd=conversation_get_proto_data(conv, proto_tcp);
316 /* If the conversation was just created or it matched a
317 * conversation with template options, tcpd will not
318 * have been initialized. So, initialize
319 * a new tcpd structure for the conversation.
322 tcpd = init_tcp_conversation_data(pinfo);
323 conversation_add_proto_data(conv, proto_tcp, tcpd);
330 /* check direction and get ua lists */
331 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
332 /* if the addresses are equal, match the ports instead */
334 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
337 tcpd->fwd=&(tcpd->flow1);
338 tcpd->rev=&(tcpd->flow2);
340 tcpd->fwd=&(tcpd->flow2);
341 tcpd->rev=&(tcpd->flow1);
348 /* Calculate the timestamps relative to this conversation */
350 tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd,
351 struct tcp_per_packet_data_t *tcppd)
354 tcppd = se_alloc(sizeof(struct tcp_per_packet_data_t));
355 p_add_proto_data(pinfo->fd, proto_tcp, tcppd);
361 nstime_delta(&tcppd->ts_del, &pinfo->fd->abs_ts, &tcpd->ts_prev);
363 tcpd->ts_prev.secs=pinfo->fd->abs_ts.secs;
364 tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs;
367 /* Add a subtree with the timestamps relative to this conversation */
369 tcp_print_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd, struct tcp_per_packet_data_t *tcppd)
378 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "Timestamps");
379 PROTO_ITEM_SET_GENERATED(item);
380 tree=proto_item_add_subtree(item, ett_tcp_timestamps);
382 nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first);
383 item = proto_tree_add_time(tree, hf_tcp_ts_relative, tvb, 0, 0, &ts);
384 PROTO_ITEM_SET_GENERATED(item);
387 tcppd = p_get_proto_data(pinfo->fd, proto_tcp);
390 item = proto_tree_add_time(tree, hf_tcp_ts_delta, tvb, 0, 0,
392 PROTO_ITEM_SET_GENERATED(item);
397 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_multisegment_pdu *msp)
401 if (check_col(pinfo->cinfo, COL_INFO)){
402 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", msp->first_frame);
404 item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
405 tvb, 0, 0, msp->first_frame);
406 PROTO_ITEM_SET_GENERATED(item);
409 /* if we know that a PDU starts inside this segment, return the adjusted
410 offset to where that PDU starts or just return offset back
411 and let TCP try to find out what it can about this segment
414 scan_for_next_pdu(tvbuff_t *tvb, proto_tree *tcp_tree, packet_info *pinfo, int offset, guint32 seq, guint32 nxtseq, emem_tree_t *multisegment_pdus)
416 struct tcp_multisegment_pdu *msp=NULL;
418 if(!pinfo->fd->flags.visited){
419 msp=se_tree_lookup32_le(multisegment_pdus, seq-1);
421 /* If this is a continuation of a PDU started in a
422 * previous segment we need to update the last_frame
425 if(seq>msp->seq && seq<msp->nxtpdu){
426 msp->last_frame=pinfo->fd->num;
427 msp->last_frame_time=pinfo->fd->abs_ts;
428 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
431 /* If this segment is completely within a previous PDU
432 * then we just skip this packet
434 if(seq>msp->seq && nxtseq<=msp->nxtpdu){
437 if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu){
438 offset+=msp->nxtpdu-seq;
444 /* First we try to find the start and transfer time for a PDU.
445 * We only print this for the very first segment of a PDU
446 * and only for PDUs spanning multiple segments.
447 * Se we look for if there was any multisegment PDU started
448 * just BEFORE the end of this segment. I.e. either inside this
449 * segment or in a previous segment.
450 * Since this might also match PDUs that are completely within
451 * this segment we also verify that the found PDU does span
452 * beyond the end of this segment.
454 msp=se_tree_lookup32_le(multisegment_pdus, nxtseq-1);
456 if( (pinfo->fd->num==msp->first_frame)
461 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, msp->last_frame);
462 PROTO_ITEM_SET_GENERATED(item);
464 nstime_delta(&ns, &msp->last_frame_time, &pinfo->fd->abs_ts);
465 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
467 PROTO_ITEM_SET_GENERATED(item);
471 /* Second we check if this segment is part of a PDU started
472 * prior to the segment (seq-1)
474 msp=se_tree_lookup32_le(multisegment_pdus, seq-1);
476 /* If this segment is completely within a previous PDU
477 * then we just skip this packet
479 if(seq>msp->seq && nxtseq<=msp->nxtpdu){
480 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
484 if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu){
485 offset+=msp->nxtpdu-seq;
494 /* if we saw a PDU that extended beyond the end of the segment,
495 use this function to remember where the next pdu starts
497 struct tcp_multisegment_pdu *
498 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, emem_tree_t *multisegment_pdus)
500 struct tcp_multisegment_pdu *msp;
502 msp=se_alloc(sizeof(struct tcp_multisegment_pdu));
505 msp->first_frame=pinfo->fd->num;
506 msp->last_frame=pinfo->fd->num;
507 msp->last_frame_time=pinfo->fd->abs_ts;
509 se_tree_insert32(multisegment_pdus, seq, (void *)msp);
513 /* This is called for SYN+ACK packets and the purpose is to verify that we
514 * have seen window scaling in both directions.
515 * If we cant find window scaling being set in both directions
516 * that means it was present in the SYN but not in the SYN+ACK
517 * (or the SYN was missing) and then we disable the window scaling
518 * for this tcp session.
521 verify_tcp_window_scaling(struct tcp_analysis *tcpd)
523 if( tcpd && ((tcpd->flow1.win_scale==-1) || (tcpd->flow2.win_scale==-1)) ){
524 tcpd->flow1.win_scale=-1;
525 tcpd->flow2.win_scale=-1;
529 /* if we saw a window scaling option, store it for future reference
532 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
535 tcpd->fwd->win_scale=ws;
539 tcp_get_relative_seq_ack(guint32 *seq, guint32 *ack, guint32 *win, struct tcp_analysis *tcpd)
541 if (tcpd && tcp_relative_seq) {
542 (*seq) -= tcpd->fwd->base_seq;
543 (*ack) -= tcpd->rev->base_seq;
544 if(tcpd->fwd->win_scale!=-1){
545 (*win)<<=tcpd->fwd->win_scale;
551 /* when this function returns, it will (if createflag) populate the ta pointer.
554 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag, struct tcp_analysis *tcpd)
559 tcpd->ta=se_tree_lookup32(tcpd->acked_table, frame);
560 if((!tcpd->ta) && createflag){
561 tcpd->ta=se_alloc0(sizeof(struct tcp_acked));
562 se_tree_insert32(tcpd->acked_table, frame, (void *)tcpd->ta);
567 /* fwd contains a list of all segments processed but not yet ACKed in the
568 * same direction as the current segment.
569 * rev contains a list of all segments received but not yet ACKed in the
570 * opposite direction to the current segment.
572 * New segments are always added to the head of the fwd/rev lists.
576 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint32 window, struct tcp_analysis *tcpd)
578 tcp_unacked_t *ual=NULL;
582 printf("analyze_sequence numbers frame:%u direction:%s\n",pinfo->fd->num,direction>=0?"FWD":"REW");
583 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);
584 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);
591 /* if this is the first segment for this list we need to store the
594 * Start relative seq and ack numbers at 1 if this
595 * is not a SYN packet. This makes the relative
596 * seq/ack numbers to be displayed correctly in the
597 * event that the SYN or SYN/ACK packet is not seen
598 * (this solves bug 1542)
600 if(tcpd->fwd->base_seq==0){
601 tcpd->fwd->base_seq = (flags & TH_SYN) ? seq : seq-1;
604 /* Only store reverse sequence if this isn't the SYN
605 * There's no guarantee that the ACK field of a SYN
606 * contains zeros; get the ISN from the first segment
607 * with the ACK bit set instead (usually the SYN/ACK).
609 if( (tcpd->rev->base_seq==0) && (flags & TH_ACK) ){
610 tcpd->rev->base_seq = (flags & TH_SYN) ? ack : ack-1;
615 * it is a zero window probe if
616 * the sequnece number is the next expected one
617 * the window in the other direction is 0
618 * the segment is exactly 1 byte
622 && seq==tcpd->fwd->nextseq
623 && tcpd->rev->window==0 ){
625 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
627 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
633 * a zero window packet has window == 0 but none of the SYN/FIN/RST set
637 && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ){
639 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
641 tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
646 * If this segment is beyond the last seen nextseq we must
647 * have missed some previous segment
649 * We only check for this if we have actually seen segments prior to this
651 * RST packets are not checked for this.
653 if( tcpd->fwd->nextseq
654 && GT_SEQ(seq, tcpd->fwd->nextseq)
655 && (flags&(TH_RST))==0 ){
657 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
659 tcpd->ta->flags|=TCP_A_LOST_PACKET;
664 * a keepalive contains 0 or 1 bytes of data and starts one byte prior
665 * to what should be the next sequence number.
666 * SYN/FIN/RST segments are never keepalives
669 if( (seglen==0||seglen==1)
670 && seq==(tcpd->fwd->nextseq-1)
671 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
673 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
675 tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
679 * A window update is a 0 byte segment with the same SEQ/ACK numbers as
680 * the previous seen segment and with a new window value
684 && window!=tcpd->fwd->window
685 && seq==tcpd->fwd->nextseq
686 && ack==tcpd->fwd->lastack
687 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
689 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
691 tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
696 * If we know the window scaling
697 * and if this segment contains data ang goes all the way to the
698 * edge of the advertized window
699 * then we mark it as WINDOW FULL
700 * SYN/RST/FIN packets are never WINDOW FULL
704 && tcpd->fwd->win_scale!=-1
705 && tcpd->rev->win_scale!=-1
706 && (seq+seglen)==(tcpd->rev->lastack+(tcpd->rev->window<<tcpd->rev->win_scale))
707 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
709 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
711 tcpd->ta->flags|=TCP_A_WINDOW_FULL;
716 * It is a keepalive ack if it repeats the previous ACK and if
717 * the last segment in the reverse direction was a keepalive
722 && window==tcpd->fwd->window
723 && seq==tcpd->fwd->nextseq
724 && ack==tcpd->fwd->lastack
725 && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
726 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
728 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
730 tcpd->ta->flags|=TCP_A_KEEP_ALIVE_ACK;
735 /* ZERO WINDOW PROBE ACK
736 * It is a zerowindowprobe ack if it repeats the previous ACK and if
737 * the last segment in the reverse direction was a zerowindowprobe
738 * It also repeats the previous zero window indication
743 && window==tcpd->fwd->window
744 && seq==tcpd->fwd->nextseq
745 && ack==tcpd->fwd->lastack
746 && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
747 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
749 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
751 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
757 * It is a duplicate ack if window/seq/ack is the same as the previous
758 * segment and if the segment length is 0
762 && window==tcpd->fwd->window
763 && seq==tcpd->fwd->nextseq
764 && ack==tcpd->fwd->lastack
765 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
766 tcpd->fwd->dupacknum++;
768 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
770 tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
771 tcpd->ta->dupack_num=tcpd->fwd->dupacknum;
772 tcpd->ta->dupack_frame=tcpd->fwd->lastnondupack;
778 /* If this was NOT a dupack we must reset the dupack counters */
779 if( (!tcpd->ta) || !(tcpd->ta->flags&TCP_A_DUPLICATE_ACK) ){
780 tcpd->fwd->lastnondupack=pinfo->fd->num;
781 tcpd->fwd->dupacknum=0;
786 * If this segment acks beyond the nextseqnum in the other direction
787 * then that means we have missed packets going in the
790 * We only check this if we have actually seen some seq numbers
791 * in the other direction.
793 if( tcpd->rev->nextseq
794 && GT_SEQ(ack, tcpd->rev->nextseq )
795 && (flags&(TH_ACK))!=0 ){
798 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
800 tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
801 /* update nextseq in the other direction so we dont get
802 * this indication again.
804 tcpd->rev->nextseq=ack;
808 /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
809 * If the segments contains data and if it does not advance
810 * sequence number it must be either of these three.
811 * Only test for this if we know what the seq number should be
812 * (tcpd->fwd->nextseq)
814 * Note that a simple KeepAlive is not a retransmission
817 && tcpd->fwd->nextseq
818 && (LT_SEQ(seq, tcpd->fwd->nextseq)) ){
821 if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ){
822 goto finished_checking_retransmission_type;
825 /* If there were >=2 duplicate ACKs in the reverse direction
826 * (there might be duplicate acks missing from the trace)
827 * and if this sequence number matches those ACKs
828 * and if the packet occurs within 20ms of the last
830 * then this is a fast retransmission
832 t=(pinfo->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
833 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;
834 if( tcpd->rev->dupacknum>=2
835 && tcpd->rev->lastack==seq
838 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
840 tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
841 goto finished_checking_retransmission_type;
844 /* If the segment came <3ms since the segment with the highest
845 * seen sequence number, then it is an OUT-OF-ORDER segment.
846 * (3ms is an arbitrary number)
848 t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
849 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
852 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
854 tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
855 goto finished_checking_retransmission_type;
858 /* Then it has to be a generic retransmission */
860 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
862 tcpd->ta->flags|=TCP_A_RETRANSMISSION;
863 nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
864 tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
866 finished_checking_retransmission_type:
869 /* add this new sequence number to the fwd list */
870 TCP_UNACKED_NEW(ual);
871 ual->next=tcpd->fwd->segments;
872 tcpd->fwd->segments=ual;
873 ual->frame=pinfo->fd->num;
875 ual->ts=pinfo->fd->abs_ts;
877 /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
878 ual->nextseq=seq+seglen;
879 if( flags&(TH_SYN|TH_FIN) ){
883 /* Store the highest number seen so far for nextseq so we can detect
884 * when we receive segments that arrive with a "hole"
885 * If we dont have anything since before, just store what we got.
886 * ZeroWindowProbes are special and dont really advance the nextseq
888 if(GT_SEQ(ual->nextseq, tcpd->fwd->nextseq) || !tcpd->fwd->nextseq) {
889 if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ){
890 tcpd->fwd->nextseq=ual->nextseq;
891 tcpd->fwd->nextseqframe=pinfo->fd->num;
892 tcpd->fwd->nextseqtime.secs=pinfo->fd->abs_ts.secs;
893 tcpd->fwd->nextseqtime.nsecs=pinfo->fd->abs_ts.nsecs;
898 /* remember what the ack/window is so we can track window updates and retransmissions */
899 tcpd->fwd->window=window;
900 tcpd->fwd->lastack=ack;
901 tcpd->fwd->lastacktime.secs=pinfo->fd->abs_ts.secs;
902 tcpd->fwd->lastacktime.nsecs=pinfo->fd->abs_ts.nsecs;
905 /* if there were any flags set for this segment we need to remember them
906 * we only remember the flags for the very last segment though.
909 tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
911 tcpd->fwd->lastsegmentflags=0;
915 /* remove all segments this ACKs and we dont need to keep around any more
918 /* first we remove all such segments at the head of the list */
919 while((ual=tcpd->rev->segments)){
920 tcp_unacked_t *tmpual;
921 if(ack==ual->nextseq){
922 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
923 tcpd->ta->frame_acked=ual->frame;
924 nstime_delta(&tcpd->ta->ts, &pinfo->fd->abs_ts, &ual->ts);
926 if(GT_SEQ(ual->nextseq,ack)){
930 /*qqq do the ACKs segment x delta y */
933 tmpual=tcpd->rev->segments->next;
935 if (tcpd->rev->scps_capable) {
936 /* Track largest segment successfully sent for SNACK analysis */
937 if ((ual->nextseq - ual->seq) > tcpd->fwd->maxsizeacked) {
938 tcpd->fwd->maxsizeacked = (ual->nextseq - ual->seq);
942 TCP_UNACKED_FREE(ual);
943 tcpd->rev->segments=tmpual;
945 /* now we remove all such segments that are NOT at the head of the list */
946 ual=tcpd->rev->segments;
947 while(ual && ual->next){
948 tcp_unacked_t *tmpual;
949 if(GT_SEQ(ual->next->nextseq,ack)){
954 /*qqq do the ACKs segment x delta y */
957 tmpual=ual->next->next;
959 if (tcpd->rev->scps_capable) {
960 /* Track largest segment successfully sent for SNACK analysis*/
961 if ((ual->next->nextseq - ual->next->seq) > tcpd->fwd->maxsizeacked){
962 tcpd->fwd->maxsizeacked = (ual->next->nextseq - ual->next->seq);
966 TCP_UNACKED_FREE(ual->next);
971 /* how many bytes of data are there in flight after this frame
974 ual=tcpd->fwd->segments;
975 if (tcp_track_bytes_in_flight && seglen!=0 && ual) {
976 guint32 first_seq, last_seq, in_flight;
978 first_seq = ual->seq - tcpd->fwd->base_seq;
979 last_seq = ual->nextseq - tcpd->fwd->base_seq;
981 if ((ual->nextseq-tcpd->fwd->base_seq)>last_seq) {
982 last_seq = ual->nextseq-tcpd->fwd->base_seq;
984 if ((ual->seq-tcpd->fwd->base_seq)<first_seq) {
985 first_seq = ual->seq-tcpd->fwd->base_seq;
989 in_flight = last_seq-first_seq;
991 if (in_flight>0 && in_flight<2000000000) {
993 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
995 tcpd->ta->bytes_in_flight = in_flight;
1002 * Prints results of the sequence number analysis concerning tcp segments
1003 * retransmitted or out-of-order
1006 tcp_sequence_number_analysis_print_retransmission(packet_info * pinfo,
1008 proto_tree * flags_tree,
1009 struct tcp_acked *ta
1012 proto_item * flags_item;
1014 /* TCP Rentransmission */
1015 if (ta->flags & TCP_A_RETRANSMISSION) {
1016 flags_item=proto_tree_add_none_format(flags_tree,
1017 hf_tcp_analysis_retransmission,
1019 "This frame is a (suspected) "
1022 PROTO_ITEM_SET_GENERATED(flags_item);
1023 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1024 "Retransmission (suspected)");
1026 if (check_col(pinfo->cinfo, COL_INFO)) {
1027 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
1029 if (ta->rto_ts.secs || ta->rto_ts.nsecs) {
1030 flags_item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
1031 tvb, 0, 0, &ta->rto_ts);
1032 PROTO_ITEM_SET_GENERATED(flags_item);
1033 flags_item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame,
1034 tvb, 0, 0, ta->rto_frame);
1035 PROTO_ITEM_SET_GENERATED(flags_item);
1038 /* TCP Fast Rentransmission */
1039 if (ta->flags & TCP_A_FAST_RETRANSMISSION) {
1040 flags_item=proto_tree_add_none_format(flags_tree,
1041 hf_tcp_analysis_fast_retransmission,
1043 "This frame is a (suspected) fast"
1046 PROTO_ITEM_SET_GENERATED(flags_item);
1047 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1048 "Fast retransmission (suspected)");
1049 flags_item=proto_tree_add_none_format(flags_tree,
1050 hf_tcp_analysis_retransmission,
1052 "This frame is a (suspected) "
1055 PROTO_ITEM_SET_GENERATED(flags_item);
1056 if (check_col(pinfo->cinfo, COL_INFO)) {
1057 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1058 "[TCP Fast Retransmission] ");
1061 /* TCP Out-Of-Order */
1062 if (ta->flags & TCP_A_OUT_OF_ORDER) {
1063 flags_item=proto_tree_add_none_format(flags_tree,
1064 hf_tcp_analysis_out_of_order,
1066 "This frame is a (suspected) "
1067 "out-of-order segment"
1069 PROTO_ITEM_SET_GENERATED(flags_item);
1070 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1071 "Out-Of-Order segment");
1072 if (check_col(pinfo->cinfo, COL_INFO)) {
1073 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
1078 /* Prints results of the sequence number analysis concerning reused ports */
1080 tcp_sequence_number_analysis_print_reused(packet_info * pinfo,
1082 proto_tree * flags_tree,
1083 struct tcp_acked *ta
1086 proto_item * flags_item;
1088 /* TCP Ports Reused */
1089 if (ta->flags & TCP_A_REUSED_PORTS) {
1090 flags_item=proto_tree_add_none_format(flags_tree,
1091 hf_tcp_analysis_reused_ports,
1093 "A new tcp session is started with the same "
1094 "ports as an earlier session in this trace"
1096 PROTO_ITEM_SET_GENERATED(flags_item);
1097 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1098 "TCP Port numbers reused for new session");
1099 if(check_col(pinfo->cinfo, COL_INFO)){
1100 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1101 "[TCP Port numbers reused] ");
1106 /* Prints results of the sequence number analysis concerning lost tcp segments */
1108 tcp_sequence_number_analysis_print_lost(packet_info * pinfo,
1110 proto_tree * flags_tree,
1111 struct tcp_acked *ta
1114 proto_item * flags_item;
1116 /* TCP Lost Segment */
1117 if (ta->flags & TCP_A_LOST_PACKET) {
1118 flags_item=proto_tree_add_none_format(flags_tree,
1119 hf_tcp_analysis_lost_packet,
1121 "A segment before this frame was "
1124 PROTO_ITEM_SET_GENERATED(flags_item);
1125 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1126 "Previous segment lost (common at capture start)");
1127 if(check_col(pinfo->cinfo, COL_INFO)){
1128 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1129 "[TCP Previous segment lost] ");
1132 /* TCP Ack lost segment */
1133 if (ta->flags & TCP_A_ACK_LOST_PACKET) {
1134 flags_item=proto_tree_add_none_format(flags_tree,
1135 hf_tcp_analysis_ack_lost_packet,
1137 "This frame ACKs a segment we have "
1140 PROTO_ITEM_SET_GENERATED(flags_item);
1141 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1142 "ACKed lost segment (common at capture start)");
1143 if(check_col(pinfo->cinfo, COL_INFO)){
1144 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1145 "[TCP ACKed lost segment] ");
1150 /* Prints results of the sequence number analysis concerning tcp window */
1152 tcp_sequence_number_analysis_print_window(packet_info * pinfo,
1154 proto_tree * flags_tree,
1155 struct tcp_acked *ta
1158 proto_item * flags_item;
1160 /* TCP Window Update */
1161 if (ta->flags & TCP_A_WINDOW_UPDATE) {
1162 flags_item=proto_tree_add_none_format(flags_tree,
1163 hf_tcp_analysis_window_update,
1165 "This is a tcp window update"
1167 PROTO_ITEM_SET_GENERATED(flags_item);
1168 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_CHAT,
1170 if (check_col(pinfo->cinfo, COL_INFO)) {
1171 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
1174 /* TCP Full Window */
1175 if (ta->flags & TCP_A_WINDOW_FULL) {
1176 flags_item=proto_tree_add_none_format(flags_tree,
1177 hf_tcp_analysis_window_full,
1179 "The transmission window is now "
1182 PROTO_ITEM_SET_GENERATED(flags_item);
1183 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1185 if (check_col(pinfo->cinfo, COL_INFO)) {
1186 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
1191 /* Prints results of the sequence number analysis concerning tcp keepalive */
1193 tcp_sequence_number_analysis_print_keepalive(packet_info * pinfo,
1195 proto_tree * flags_tree,
1196 struct tcp_acked *ta
1199 proto_item * flags_item;
1202 if (ta->flags & TCP_A_KEEP_ALIVE){
1203 flags_item=proto_tree_add_none_format(flags_tree,
1204 hf_tcp_analysis_keep_alive,
1206 "This is a TCP keep-alive segment"
1208 PROTO_ITEM_SET_GENERATED(flags_item);
1209 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1211 if (check_col(pinfo->cinfo, COL_INFO)) {
1212 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
1215 /* TCP Ack Keep Alive */
1216 if (ta->flags & TCP_A_KEEP_ALIVE_ACK) {
1217 flags_item=proto_tree_add_none_format(flags_tree,
1218 hf_tcp_analysis_keep_alive_ack,
1220 "This is an ACK to a TCP keep-alive "
1223 PROTO_ITEM_SET_GENERATED(flags_item);
1224 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1226 if (check_col(pinfo->cinfo, COL_INFO)) {
1227 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
1232 /* Prints results of the sequence number analysis concerning tcp duplicate ack */
1234 tcp_sequence_number_analysis_print_duplicate(packet_info * pinfo,
1236 proto_tree * flags_tree,
1237 struct tcp_acked *ta,
1241 proto_item * flags_item;
1243 /* TCP Duplicate ACK */
1244 if (ta->dupack_num) {
1245 if (ta->flags & TCP_A_DUPLICATE_ACK ) {
1246 flags_item=proto_tree_add_none_format(flags_tree,
1247 hf_tcp_analysis_duplicate_ack,
1249 "This is a TCP duplicate ack"
1251 PROTO_ITEM_SET_GENERATED(flags_item);
1252 if (check_col(pinfo->cinfo, COL_INFO)) {
1253 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1254 "[TCP Dup ACK %u#%u] ",
1260 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
1261 tvb, 0, 0, ta->dupack_num);
1262 PROTO_ITEM_SET_GENERATED(flags_item);
1263 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
1264 tvb, 0, 0, ta->dupack_frame);
1265 PROTO_ITEM_SET_GENERATED(flags_item);
1266 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1267 "Duplicate ACK (#%u)",
1273 /* Prints results of the sequence number analysis concerning tcp zero window */
1275 tcp_sequence_number_analysis_print_zero_window(packet_info * pinfo,
1277 proto_tree * flags_tree,
1278 struct tcp_acked *ta
1281 proto_item * flags_item;
1283 /* TCP Zero Window Probe */
1284 if (ta->flags & TCP_A_ZERO_WINDOW_PROBE) {
1285 flags_item=proto_tree_add_none_format(flags_tree,
1286 hf_tcp_analysis_zero_window_probe,
1288 "This is a TCP zero-window-probe"
1290 PROTO_ITEM_SET_GENERATED(flags_item);
1291 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1292 "Zero window probe");
1293 if (check_col(pinfo->cinfo, COL_INFO)) {
1294 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
1297 /* TCP Zero Window */
1298 if (ta->flags&TCP_A_ZERO_WINDOW) {
1299 flags_item=proto_tree_add_none_format(flags_tree,
1300 hf_tcp_analysis_zero_window,
1302 "This is a ZeroWindow segment"
1304 PROTO_ITEM_SET_GENERATED(flags_item);
1305 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1307 if (check_col(pinfo->cinfo, COL_INFO)) {
1308 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
1311 /* TCP Zero Window Probe Ack */
1312 if (ta->flags & TCP_A_ZERO_WINDOW_PROBE_ACK) {
1313 flags_item=proto_tree_add_none_format(flags_tree,
1314 hf_tcp_analysis_zero_window_probe_ack,
1316 "This is an ACK to a TCP zero-window-probe"
1318 PROTO_ITEM_SET_GENERATED(flags_item);
1319 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1320 "Zero window probe ACK");
1321 if (check_col(pinfo->cinfo, COL_INFO)) {
1322 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1323 "[TCP ZeroWindowProbeAck] ");
1329 /* Prints results of the sequence number analysis concerning how many bytes of data are in flight */
1331 tcp_sequence_number_analysis_print_bytes_in_flight(packet_info * pinfo _U_,
1333 proto_tree * flags_tree _U_,
1334 struct tcp_acked *ta
1337 proto_item * flags_item;
1339 if (tcp_track_bytes_in_flight) {
1340 flags_item=proto_tree_add_uint(flags_tree,
1341 hf_tcp_analysis_bytes_in_flight,
1342 tvb, 0, 0, ta->bytes_in_flight);
1344 PROTO_ITEM_SET_GENERATED(flags_item);
1349 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd)
1351 struct tcp_acked *ta = NULL;
1354 proto_tree *flags_tree=NULL;
1360 tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE, tcpd);
1367 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
1368 PROTO_ITEM_SET_GENERATED(item);
1369 tree=proto_item_add_subtree(item, ett_tcp_analysis);
1371 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
1372 data we actually have */
1373 if(ta->frame_acked){
1374 item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
1375 tvb, 0, 0, ta->frame_acked);
1376 PROTO_ITEM_SET_GENERATED(item);
1378 /* only display RTT if we actually have something we are acking */
1379 if( ta->ts.secs || ta->ts.nsecs ){
1380 item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
1381 tvb, 0, 0, &ta->ts);
1382 PROTO_ITEM_SET_GENERATED(item);
1386 if(ta->bytes_in_flight) {
1387 /* print results for amount of data in flight */
1388 tcp_sequence_number_analysis_print_bytes_in_flight(pinfo, tvb, tree, ta);
1392 item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, 0, FALSE);
1393 PROTO_ITEM_SET_GENERATED(item);
1394 flags_tree=proto_item_add_subtree(item, ett_tcp_analysis);
1396 /* print results for reused tcp ports */
1397 tcp_sequence_number_analysis_print_reused(pinfo, tvb, flags_tree, ta);
1399 /* print results for retransmission and out-of-order segments */
1400 tcp_sequence_number_analysis_print_retransmission(pinfo, tvb, flags_tree, ta);
1402 /* print results for lost tcp segments */
1403 tcp_sequence_number_analysis_print_lost(pinfo, tvb, flags_tree, ta);
1405 /* print results for tcp window information */
1406 tcp_sequence_number_analysis_print_window(pinfo, tvb, flags_tree, ta);
1408 /* print results for tcp keep alive information */
1409 tcp_sequence_number_analysis_print_keepalive(pinfo, tvb, flags_tree, ta);
1411 /* print results for tcp duplicate acks */
1412 tcp_sequence_number_analysis_print_duplicate(pinfo, tvb, flags_tree, ta, tree);
1414 /* print results for tcp zero window */
1415 tcp_sequence_number_analysis_print_zero_window(pinfo, tvb, flags_tree, ta);
1422 /* **************************************************************************
1423 * End of tcp sequence number analysis
1424 * **************************************************************************/
1427 /* Minimum TCP header length. */
1428 #define TCPH_MIN_LEN 20
1434 #define TCPOPT_NOP 1 /* Padding */
1435 #define TCPOPT_EOL 0 /* End of options */
1436 #define TCPOPT_MSS 2 /* Segment size negotiating */
1437 #define TCPOPT_WINDOW 3 /* Window scaling */
1438 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
1439 #define TCPOPT_SACK 5 /* SACK Block */
1440 #define TCPOPT_ECHO 6
1441 #define TCPOPT_ECHOREPLY 7
1442 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
1443 #define TCPOPT_CC 11
1444 #define TCPOPT_CCNEW 12
1445 #define TCPOPT_CCECHO 13
1446 #define TCPOPT_MD5 19 /* RFC2385 */
1447 #define TCPOPT_SCPS 20 /* SCPS Capabilties */
1448 #define TCPOPT_SNACK 21 /* SCPS SNACK */
1449 #define TCPOPT_RECBOUND 22 /* SCPS Record Boundary */
1450 #define TCPOPT_CORREXP 23 /* SCPS Corruption Experienced */
1451 #define TCPOPT_QS 27 /* RFC4782 */
1454 * TCP option lengths
1457 #define TCPOLEN_MSS 4
1458 #define TCPOLEN_WINDOW 3
1459 #define TCPOLEN_SACK_PERM 2
1460 #define TCPOLEN_SACK_MIN 2
1461 #define TCPOLEN_ECHO 6
1462 #define TCPOLEN_ECHOREPLY 6
1463 #define TCPOLEN_TIMESTAMP 10
1464 #define TCPOLEN_CC 6
1465 #define TCPOLEN_CCNEW 6
1466 #define TCPOLEN_CCECHO 6
1467 #define TCPOLEN_MD5 18
1468 #define TCPOLEN_SCPS 4
1469 #define TCPOLEN_SNACK 6
1470 #define TCPOLEN_RECBOUND 2
1471 #define TCPOLEN_CORREXP 2
1472 #define TCPOLEN_QS 8
1476 /* Desegmentation of TCP streams */
1477 /* table to hold defragmented TCP streams */
1478 static GHashTable *tcp_fragment_table = NULL;
1480 tcp_fragment_init(void)
1482 fragment_table_init(&tcp_fragment_table);
1485 /* functions to trace tcp segments */
1486 /* Enable desegmenting of TCP streams */
1487 static gboolean tcp_desegment = TRUE;
1490 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1491 guint32 seq, guint32 nxtseq,
1492 guint32 sport, guint32 dport,
1493 proto_tree *tree, proto_tree *tcp_tree,
1494 struct tcp_analysis *tcpd)
1496 struct tcpinfo *tcpinfo = pinfo->private_data;
1497 fragment_data *ipfd_head;
1498 int last_fragment_len;
1499 gboolean must_desegment;
1500 gboolean called_dissector;
1501 int another_pdu_follows;
1506 proto_item *frag_tree_item;
1507 proto_item *tcp_tree_item;
1508 struct tcp_multisegment_pdu *msp;
1512 last_fragment_len=0;
1513 must_desegment = FALSE;
1514 called_dissector = FALSE;
1515 another_pdu_follows = 0;
1519 * Initialize these to assume no desegmentation.
1520 * If that's not the case, these will be set appropriately
1521 * by the subdissector.
1523 pinfo->desegment_offset = 0;
1524 pinfo->desegment_len = 0;
1527 * Initialize this to assume that this segment will just be
1528 * added to the middle of a desegmented chunk of data, so
1529 * that we should show it all as data.
1530 * If that's not the case, it will be set appropriately.
1532 deseg_offset = offset;
1534 /* find the most previous PDU starting before this sequence number */
1536 msp = se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
1538 if(msp && msp->seq<=seq && msp->nxtpdu>seq){
1541 if(!pinfo->fd->flags.visited){
1542 msp->last_frame=pinfo->fd->num;
1543 msp->last_frame_time=pinfo->fd->abs_ts;
1546 /* OK, this PDU was found, which means the segment continues
1547 a higher-level PDU and that we must desegment it.
1549 if(msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT){
1550 /* The dissector asked for the entire segment */
1551 len=tvb_length_remaining(tvb, offset);
1553 len=MIN(nxtseq, msp->nxtpdu) - seq;
1555 last_fragment_len = len;
1557 ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
1561 (LT_SEQ (nxtseq,msp->nxtpdu)) );
1563 if(msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT){
1564 msp->flags&=(~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT);
1566 /* If we consumed the entire segment there is no
1567 * other pdu starting anywhere inside this segment.
1568 * So update nxtpdu to point at least to the start
1569 * of the next segment.
1570 * (If the subdissector asks for even more data we
1571 * will advance nxtpdu even furhter later down in
1577 if( (msp->nxtpdu<nxtseq)
1578 && (msp->nxtpdu>=seq)
1580 another_pdu_follows=msp->nxtpdu-seq;
1583 /* This segment was not found in our table, so it doesn't
1584 contain a continuation of a higher-level PDU.
1585 Call the normal subdissector.
1587 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1588 sport, dport, 0, 0, FALSE, tcpd);
1589 called_dissector = TRUE;
1591 /* Did the subdissector ask us to desegment some more data
1592 before it could handle the packet?
1593 If so we have to create some structures in our table but
1594 this is something we only do the first time we see this
1597 if(pinfo->desegment_len) {
1598 if (!pinfo->fd->flags.visited)
1599 must_desegment = TRUE;
1602 * Set "deseg_offset" to the offset in "tvb"
1603 * of the first byte of data that the
1604 * subdissector didn't process.
1606 deseg_offset = offset + pinfo->desegment_offset;
1609 /* Either no desegmentation is necessary, or this is
1610 segment contains the beginning but not the end of
1611 a higher-level PDU and thus isn't completely
1618 /* is it completely desegmented? */
1621 * Yes, we think it is.
1622 * We only call subdissector for the last segment.
1623 * Note that the last segment may include more than what
1626 if(ipfd_head->reassembled_in==pinfo->fd->num){
1628 * OK, this is the last segment.
1629 * Let's call the subdissector with the desegmented
1635 /* create a new TVB structure for desegmented data */
1636 next_tvb = tvb_new_real_data(ipfd_head->data,
1637 ipfd_head->datalen, ipfd_head->datalen);
1639 /* add this tvb as a child to the original one */
1640 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1642 /* add desegmented data to the data source list */
1643 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1646 * Supply the sequence number of the first of the
1647 * reassembled bytes.
1649 tcpinfo->seq = msp->seq;
1651 /* indicate that this is reassembled data */
1652 tcpinfo->is_reassembled = TRUE;
1654 /* call subdissector */
1655 process_tcp_payload(next_tvb, 0, pinfo, tree,
1656 tcp_tree, sport, dport, 0, 0, FALSE, tcpd);
1657 called_dissector = TRUE;
1660 * OK, did the subdissector think it was completely
1661 * desegmented, or does it think we need even more
1664 old_len=(int)(tvb_reported_length(next_tvb)-last_fragment_len);
1665 if(pinfo->desegment_len &&
1666 pinfo->desegment_offset<=old_len){
1668 * "desegment_len" isn't 0, so it needs more
1669 * data for something - and "desegment_offset"
1670 * is before "old_len", so it needs more data
1671 * to dissect the stuff we thought was
1672 * completely desegmented (as opposed to the
1673 * stuff at the beginning being completely
1674 * desegmented, but the stuff at the end
1675 * being a new higher-level PDU that also
1676 * needs desegmentation).
1678 fragment_set_partial_reassembly(pinfo,msp->first_frame,tcp_fragment_table);
1679 /* Update msp->nxtpdu to point to the new next
1682 if(pinfo->desegment_len==DESEGMENT_ONE_MORE_SEGMENT){
1683 /* We want reassembly of at least one
1684 * more segment so set the nxtpdu
1685 * boundary to one byte into the next
1687 * This means that the next segment
1688 * will complete reassembly even if it
1689 * is only one single byte in length.
1691 msp->nxtpdu=seq+tvb_reported_length_remaining(tvb, offset) + 1;
1692 msp->flags|=MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1694 msp->nxtpdu=seq + last_fragment_len + pinfo->desegment_len;
1696 /* Since we need at least some more data
1697 * there can be no pdu following in the
1698 * tail of this segment.
1700 another_pdu_follows=0;
1701 offset += last_fragment_len;
1702 seq += last_fragment_len;
1703 if (tvb_length_remaining(tvb, offset) > 0)
1707 * Show the stuff in this TCP segment as
1708 * just raw TCP segment data.
1710 nbytes = another_pdu_follows > 0
1711 ? another_pdu_follows
1712 : tvb_reported_length_remaining(tvb, offset);
1713 proto_tree_add_text(tcp_tree, tvb, offset, nbytes,
1714 "TCP segment data (%u byte%s)", nbytes,
1715 plurality(nbytes, "", "s"));
1718 * The subdissector thought it was completely
1719 * desegmented (although the stuff at the
1720 * end may, in turn, require desegmentation),
1721 * so we show a tree with all segments.
1723 show_fragment_tree(ipfd_head, &tcp_segment_items,
1724 tree, pinfo, next_tvb, &frag_tree_item);
1726 * The toplevel fragment subtree is now
1727 * behind all desegmented data; move it
1728 * right behind the TCP tree.
1730 tcp_tree_item = proto_tree_get_parent(tcp_tree);
1731 if(frag_tree_item && tcp_tree_item) {
1732 proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1735 /* Did the subdissector ask us to desegment
1736 some more data? This means that the data
1737 at the beginning of this segment completed
1738 a higher-level PDU, but the data at the
1739 end of this segment started a higher-level
1740 PDU but didn't complete it.
1742 If so, we have to create some structures
1743 in our table, but this is something we
1744 only do the first time we see this packet.
1746 if(pinfo->desegment_len) {
1747 if (!pinfo->fd->flags.visited)
1748 must_desegment = TRUE;
1750 /* The stuff we couldn't dissect
1751 must have come from this segment,
1752 so it's all in "tvb".
1754 "pinfo->desegment_offset" is
1755 relative to the beginning of
1756 "next_tvb"; we want an offset
1757 relative to the beginning of "tvb".
1759 First, compute the offset relative
1760 to the *end* of "next_tvb" - i.e.,
1761 the number of bytes before the end
1762 of "next_tvb" at which the
1763 subdissector stopped. That's the
1764 length of "next_tvb" minus the
1765 offset, relative to the beginning
1766 of "next_tvb, at which the
1767 subdissector stopped.
1770 ipfd_head->datalen - pinfo->desegment_offset;
1772 /* "tvb" and "next_tvb" end at the
1773 same byte of data, so the offset
1774 relative to the end of "next_tvb"
1775 of the byte at which we stopped
1776 is also the offset relative to
1777 the end of "tvb" of the byte at
1780 Convert that back into an offset
1781 relative to the beginninng of
1782 "tvb", by taking the length of
1783 "tvb" and subtracting the offset
1784 relative to the end.
1786 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1792 if (must_desegment) {
1793 /* If the dissector requested "reassemble until FIN"
1794 * just set this flag for the flow and let reassembly
1795 * proceed at normal. We will check/pick up these
1796 * reassembled PDUs later down in dissect_tcp() when checking
1799 if(tcpd && pinfo->desegment_len==DESEGMENT_UNTIL_FIN) {
1800 tcpd->fwd->flags|=TCP_FLOW_REASSEMBLE_UNTIL_FIN;
1803 * The sequence number at which the stuff to be desegmented
1804 * starts is the sequence number of the byte at an offset
1805 * of "deseg_offset" into "tvb".
1807 * The sequence number of the byte at an offset of "offset"
1808 * is "seq", i.e. the starting sequence number of this
1809 * segment, so the sequence number of the byte at
1810 * "deseg_offset" is "seq + (deseg_offset - offset)".
1812 deseg_seq = seq + (deseg_offset - offset);
1814 if(tcpd && ((nxtseq - deseg_seq) <= 1024*1024)
1815 && (!pinfo->fd->flags.visited) ){
1816 if(pinfo->desegment_len==DESEGMENT_ONE_MORE_SEGMENT){
1817 /* The subdissector asked to reassemble using the
1818 * entire next segment.
1819 * Just ask reassembly for one more byte
1820 * but set this msp flag so we can pick it up
1823 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
1824 deseg_seq, nxtseq+1, tcpd->fwd->multisegment_pdus);
1825 msp->flags|=MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1827 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
1828 deseg_seq, nxtseq+pinfo->desegment_len, tcpd->fwd->multisegment_pdus);
1831 /* add this segment as the first one for this new pdu */
1832 fragment_add(tvb, deseg_offset, pinfo, msp->first_frame,
1836 LT_SEQ(nxtseq, msp->nxtpdu));
1840 if (!called_dissector || pinfo->desegment_len != 0) {
1841 if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
1842 !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
1844 * We know what frame this PDU is reassembled in;
1845 * let the user know.
1847 item=proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in,
1848 tvb, 0, 0, ipfd_head->reassembled_in);
1849 PROTO_ITEM_SET_GENERATED(item);
1853 * Either we didn't call the subdissector at all (i.e.,
1854 * this is a segment that contains the middle of a
1855 * higher-level PDU, but contains neither the beginning
1856 * nor the end), or the subdissector couldn't dissect it
1857 * all, as some data was missing (i.e., it set
1858 * "pinfo->desegment_len" to the amount of additional
1861 if (pinfo->desegment_offset == 0) {
1863 * It couldn't, in fact, dissect any of it (the
1864 * first byte it couldn't dissect is at an offset
1865 * of "pinfo->desegment_offset" from the beginning
1866 * of the payload, and that's 0).
1867 * Just mark this as TCP.
1869 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1870 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1872 if (check_col(pinfo->cinfo, COL_INFO)){
1873 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
1878 * Show what's left in the packet as just raw TCP segment
1880 * XXX - remember what protocol the last subdissector
1881 * was, and report it as a continuation of that, instead?
1883 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
1884 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
1885 "TCP segment data (%u byte%s)", nbytes,
1886 plurality(nbytes, "", "s"));
1888 pinfo->can_desegment=0;
1889 pinfo->desegment_offset = 0;
1890 pinfo->desegment_len = 0;
1892 if(another_pdu_follows){
1893 /* there was another pdu following this one. */
1894 pinfo->can_desegment=2;
1895 /* we also have to prevent the dissector from changing the
1896 * PROTOCOL and INFO colums since what follows may be an
1897 * incomplete PDU and we dont want it be changed back from
1898 * <Protocol> to <TCP>
1899 * XXX There is no good way to block the PROTOCOL column
1900 * from being changed yet so we set the entire row unwritable.
1902 col_set_fence(pinfo->cinfo, COL_INFO);
1903 col_set_writable(pinfo->cinfo, FALSE);
1904 offset += another_pdu_follows;
1905 seq += another_pdu_follows;
1911 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
1912 * consists of a fixed-length chunk of data that contains enough information
1913 * to determine the length of the PDU, followed by rest of the PDU.
1915 * The first three arguments are the arguments passed to the dissector
1916 * that calls this routine.
1918 * "proto_desegment" is the dissector's flag controlling whether it should
1919 * desegment PDUs that cross TCP segment boundaries.
1921 * "fixed_len" is the length of the fixed-length part of the PDU.
1923 * "get_pdu_len()" is a routine called to get the length of the PDU from
1924 * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset".
1926 * "dissect_pdu()" is the routine to dissect a PDU.
1929 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1930 gboolean proto_desegment, guint fixed_len,
1931 guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
1932 dissector_t dissect_pdu)
1934 volatile int offset = 0;
1936 guint length_remaining;
1940 proto_item *item=NULL;
1942 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1944 * We use "tvb_ensure_length_remaining()" to make sure there actually
1945 * *is* data remaining. The protocol we're handling could conceivably
1946 * consists of a sequence of fixed-length PDUs, and therefore the
1947 * "get_pdu_len" routine might not actually fetch anything from
1948 * the tvbuff, and thus might not cause an exception to be thrown if
1949 * we've run past the end of the tvbuff.
1951 * This means we're guaranteed that "length_remaining" is positive.
1953 length_remaining = tvb_ensure_length_remaining(tvb, offset);
1956 * Can we do reassembly?
1958 if (proto_desegment && pinfo->can_desegment) {
1960 * Yes - is the fixed-length part of the PDU split across segment
1963 if (length_remaining < fixed_len) {
1965 * Yes. Tell the TCP dissector where the data for this message
1966 * starts in the data it handed us, and how many more bytes we
1969 pinfo->desegment_offset = offset;
1970 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
1976 * Get the length of the PDU.
1978 plen = (*get_pdu_len)(pinfo, tvb, offset);
1979 if (plen < fixed_len) {
1983 * 1) the length value extracted from the fixed-length portion
1984 * doesn't include the fixed-length portion's length, and
1985 * was so large that, when the fixed-length portion's
1986 * length was added to it, the total length overflowed;
1988 * 2) the length value extracted from the fixed-length portion
1989 * includes the fixed-length portion's length, and the value
1990 * was less than the fixed-length portion's length, i.e. it
1993 * Report this as a bounds error.
1995 show_reported_bounds_error(tvb, pinfo, tree);
1999 * Display the PDU length as a field
2001 item=proto_tree_add_uint(pinfo->tcp_tree, hf_tcp_pdu_size, tvb, offset, plen, plen);
2002 PROTO_ITEM_SET_GENERATED(item);
2006 /* give a hint to TCP where the next PDU starts
2007 * so that it can attempt to find it in case it starts
2008 * somewhere in the middle of a segment.
2010 if(!pinfo->fd->flags.visited && tcp_analyze_seq){
2011 guint remaining_bytes;
2012 remaining_bytes=tvb_reported_length_remaining(tvb, offset);
2013 if(plen>remaining_bytes){
2014 pinfo->want_pdu_tracking=2;
2015 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
2020 * Can we do reassembly?
2022 if (proto_desegment && pinfo->can_desegment) {
2024 * Yes - is the PDU split across segment boundaries?
2026 if (length_remaining < plen) {
2028 * Yes. Tell the TCP dissector where the data for this message
2029 * starts in the data it handed us, and how many more bytes we
2032 pinfo->desegment_offset = offset;
2033 pinfo->desegment_len = plen - length_remaining;
2039 * Construct a tvbuff containing the amount of the payload we have
2040 * available. Make its reported length the amount of data in the PDU.
2042 * XXX - if reassembly isn't enabled. the subdissector will throw a
2043 * BoundsError exception, rather than a ReportedBoundsError exception.
2044 * We really want a tvbuff where the length is "length", the reported
2045 * length is "plen", and the "if the snapshot length were infinite"
2046 * length is the minimum of the reported length of the tvbuff handed
2047 * to us and "plen", with a new type of exception thrown if the offset
2048 * is within the reported length but beyond that third length, with
2049 * that exception getting the "Unreassembled Packet" error.
2051 length = length_remaining;
2054 next_tvb = tvb_new_subset(tvb, offset, length, plen);
2059 * Catch the ReportedBoundsError exception; if this particular message
2060 * happens to get a ReportedBoundsError exception, that doesn't mean
2061 * that we should stop dissecting PDUs within this frame or chunk of
2064 * If it gets a BoundsError, we can stop, as there's nothing more to
2065 * see, so we just re-throw it.
2068 (*dissect_pdu)(next_tvb, pinfo, tree);
2070 CATCH(BoundsError) {
2073 CATCH(ReportedBoundsError) {
2074 show_reported_bounds_error(tvb, pinfo, tree);
2079 * Step to the next PDU.
2080 * Make sure we don't overflow.
2082 offset_before = offset;
2084 if (offset <= offset_before)
2090 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
2092 if (check_col(pinfo->cinfo, COL_INFO))
2093 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
2096 /* Supports the reporting the contents of a parsed SCPS capabilities vector */
2098 tcp_info_append_str(packet_info *pinfo, const char *abbrev, const char *val)
2100 if (check_col(pinfo->cinfo, COL_INFO))
2101 col_append_fstr(pinfo->cinfo, COL_INFO, " %s[%s]", abbrev, val);
2105 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
2106 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2108 proto_item *hidden_item;
2111 mss = tvb_get_ntohs(tvb, offset + 2);
2112 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_mss, tvb, offset,
2114 PROTO_ITEM_SET_HIDDEN(hidden_item);
2115 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
2116 optlen, mss, "%s: %u bytes", optp->name, mss);
2117 tcp_info_append_uint(pinfo, "MSS", mss);
2121 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
2122 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2124 proto_item *hidden_item;
2126 struct tcp_analysis *tcpd=NULL;
2128 tcpd=get_tcp_conversation_data(NULL,pinfo);
2130 ws = tvb_get_guint8(tvb, offset + 2);
2131 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_wscale, tvb,
2132 offset, optlen, TRUE);
2133 PROTO_ITEM_SET_HIDDEN(hidden_item);
2134 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
2135 offset, optlen, ws, "%s: %u (multiply by %u)",
2136 optp->name, ws, 1 << ws);
2137 tcp_info_append_uint(pinfo, "WS", ws);
2138 if(!pinfo->fd->flags.visited && tcp_analyze_seq && tcp_relative_seq){
2139 pdu_store_window_scale_option(ws, tcpd);
2144 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
2145 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2147 proto_tree *field_tree = NULL;
2148 proto_item *tf=NULL;
2149 proto_item *hidden_item;
2150 guint32 leftedge, rightedge;
2151 struct tcp_analysis *tcpd=NULL;
2154 if(tcp_analyze_seq && tcp_relative_seq){
2155 /* find(or create if needed) the conversation for this tcp session */
2156 tcpd=get_tcp_conversation_data(NULL,pinfo);
2159 base_ack=tcpd->rev->base_seq;
2163 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
2164 offset += 2; /* skip past type and length */
2165 optlen -= 2; /* subtract size of type and length */
2166 while (optlen > 0) {
2167 if (field_tree == NULL) {
2168 /* Haven't yet made a subtree out of this option. Do so. */
2169 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2170 hidden_item = proto_tree_add_boolean(field_tree, hf_tcp_option_sack, tvb,
2171 offset, optlen, TRUE);
2172 PROTO_ITEM_SET_HIDDEN(hidden_item);
2175 proto_tree_add_text(field_tree, tvb, offset, optlen,
2176 "(suboption would go past end of option)");
2179 leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
2180 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
2181 offset, 4, leftedge,
2182 "left edge = %u%s", leftedge,
2183 tcp_relative_seq ? " (relative)" : "");
2187 proto_tree_add_text(field_tree, tvb, offset, optlen,
2188 "(suboption would go past end of option)");
2191 /* XXX - check whether it goes past end of packet */
2192 rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
2194 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
2195 offset+4, 4, rightedge,
2196 "right edge = %u%s", rightedge,
2197 tcp_relative_seq ? " (relative)" : "");
2198 tcp_info_append_uint(pinfo, "SLE", leftedge);
2199 tcp_info_append_uint(pinfo, "SRE", rightedge);
2200 proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
2206 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
2207 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2209 proto_item *hidden_item;
2212 echo = tvb_get_ntohl(tvb, offset + 2);
2213 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_echo, tvb, offset,
2215 PROTO_ITEM_SET_HIDDEN(hidden_item);
2216 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2217 "%s: %u", optp->name, echo);
2218 tcp_info_append_uint(pinfo, "ECHO", echo);
2222 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
2223 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2225 proto_item *hidden_item;
2228 tsv = tvb_get_ntohl(tvb, offset + 2);
2229 tser = tvb_get_ntohl(tvb, offset + 6);
2230 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_time_stamp, tvb,
2231 offset, optlen, TRUE);
2232 PROTO_ITEM_SET_HIDDEN(hidden_item);
2233 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2234 "%s: TSval %u, TSecr %u", optp->name, tsv, tser);
2235 tcp_info_append_uint(pinfo, "TSV", tsv);
2236 tcp_info_append_uint(pinfo, "TSER", tser);
2240 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
2241 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2243 proto_item *hidden_item;
2246 cc = tvb_get_ntohl(tvb, offset + 2);
2247 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_cc, tvb, offset,
2249 PROTO_ITEM_SET_HIDDEN(hidden_item);
2250 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2251 "%s: %u", optp->name, cc);
2252 tcp_info_append_uint(pinfo, "CC", cc);
2256 dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
2257 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2259 /* Quick-Start TCP option, as defined by RFC4782 */
2260 static const value_string qs_rates[] = {
2266 { 5, "1.28 Mbit/s"},
2267 { 6, "2.56 Mbit/s"},
2268 { 7, "5.12 Mbit/s"},
2269 { 8, "10.24 Mbit/s"},
2270 { 9, "20.48 Mbit/s"},
2271 {10, "40.96 Mbit/s"},
2272 {11, "81.92 Mbit/s"},
2273 {12, "163.84 Mbit/s"},
2274 {13, "327.68 Mbit/s"},
2275 {14, "655.36 Mbit/s"},
2276 {15, "1.31072 Gbit/s"},
2279 proto_item *hidden_item;
2281 guint8 rate = tvb_get_guint8(tvb, offset + 2) & 0x0f;
2283 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_qs, tvb, offset,
2285 PROTO_ITEM_SET_HIDDEN(hidden_item);
2286 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2287 "%s: Rate response, %s, TTL diff %u ", optp->name,
2288 val_to_str(rate, qs_rates, "Unknown"),
2289 tvb_get_guint8(tvb, offset + 3));
2290 if (check_col(pinfo->cinfo, COL_INFO))
2291 col_append_fstr(pinfo->cinfo, COL_INFO, " QSresp=%s", val_to_str(rate, qs_rates, "Unknown"));
2296 dissect_tcpopt_scps(const ip_tcp_opt *optp, tvbuff_t *tvb,
2297 int offset, guint optlen, packet_info *pinfo,
2298 proto_tree *opt_tree)
2300 struct tcp_analysis *tcpd=NULL;
2301 proto_tree *field_tree = NULL;
2304 proto_item *tf = NULL, *hidden_item;
2305 gchar flags[64] = "<None>";
2306 gchar *fstr[] = {"BETS", "SNACK1", "SNACK2", "COMP", "NLTS", "RESV1", "RESV2", "RESV3"};
2311 tcpd = get_tcp_conversation_data(NULL,pinfo);
2313 /* check direction and get ua lists */
2314 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2316 /* if the addresses are equal, match the ports instead */
2318 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
2322 flow =&(tcpd->flow1);
2324 flow =&(tcpd->flow2);
2326 /* If the option length == 4, this is a real SCPS capability option
2327 * See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS Transport Protocol
2328 * (SCPS-TP)" Section 3.2.3 for definition.
2331 capvector = tvb_get_guint8(tvb, offset + 2);
2334 /* Decode the capabilities vector for display */
2335 for (i = 0; i < 5; i++) {
2337 if (capvector & bpos) {
2339 g_strlcat(flags, ", ", 64);
2341 g_strlcat(flags, fstr[i], 64);
2345 /* If lossless header compression is offered, there will be a
2346 * single octet connectionId following the capabilities vector
2348 if (capvector & 0x10)
2349 connid = tvb_get_guint8(tvb, offset + 3);
2353 tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector, tvb,
2354 offset, optlen, capvector,
2356 optp->name, capvector, flags);
2357 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_scps,
2358 tvb, offset, optlen, TRUE);
2359 PROTO_ITEM_SET_HIDDEN(hidden_item);
2361 field_tree = proto_item_add_subtree(tf, ett_tcp_option_scps);
2363 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_bets, tvb,
2364 offset + 13, 1, capvector);
2365 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_snack1, tvb,
2366 offset + 13, 1, capvector);
2367 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_snack2, tvb,
2368 offset + 13, 1, capvector);
2369 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_compress, tvb,
2370 offset + 13, 1, capvector);
2371 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_nlts, tvb,
2372 offset + 13, 1, capvector);
2373 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_resv1, tvb,
2374 offset + 13, 1, capvector);
2375 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_resv2, tvb,
2376 offset + 13, 1, capvector);
2377 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_resv3, tvb,
2378 offset + 13, 1, capvector);
2380 tcp_info_append_str(pinfo, "SCPS", flags);
2382 flow->scps_capable = 1;
2385 tcp_info_append_uint(pinfo, "Connection ID", connid);
2388 /* The option length != 4, so this is an infamous "extended capabilities
2389 * option. See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
2390 * Transport Protocol (SCPS-TP)" Section 3.2.5 for definition.
2392 * As the format of this option is only partially defined (it is
2393 * a community (or more likely vendor) defined format beyond that, so
2394 * at least for now, we only parse the standardized portion of the option.
2396 guint8 local_offset = 2;
2397 guint8 binding_space;
2398 guint8 extended_cap_length;
2400 if (flow->scps_capable != 1) {
2401 /* There was no SCPS capabilities option preceeding this */
2402 tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector,
2403 tvb, offset, optlen, 0, "%s: (%d %s)",
2404 "Illegal SCPS Extended Capabilities",
2409 tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector,
2410 tvb, offset, optlen, 0, "%s: (%d %s)",
2411 "SCPS Extended Capabilities",
2414 field_tree=proto_item_add_subtree(tf, ett_tcp_option_scps_extended);
2415 /* There may be multiple binding spaces included in a single option,
2416 * so we will semi-parse each of the stacked binding spaces - skipping
2417 * over the octets following the binding space identifier and length.
2420 while (optlen > local_offset) {
2421 proto_item *hidden_item;
2423 /* 1st octet is Extended Capability Binding Space */
2424 binding_space = tvb_get_guint8(tvb, (offset + local_offset));
2426 /* 2nd octet (upper 4-bits) has binding space length in 16-bit words.
2427 * As defined by the specification, this length is exclusive of the
2428 * octets containing the extended capability type and length
2431 extended_cap_length =
2432 (tvb_get_guint8(tvb, (offset + local_offset + 1)) >> 4);
2434 /* Convert the extended capabilities length into bytes for display */
2435 extended_cap_length = (extended_cap_length << 1);
2437 proto_tree_add_text(field_tree, tvb, offset + local_offset, 2,
2438 "\tBinding Space %u",
2440 hidden_item = proto_tree_add_uint(field_tree, hf_tcp_option_scps_binding,
2441 tvb, (offset + local_offset), 1,
2444 PROTO_ITEM_SET_HIDDEN(hidden_item);
2446 /* Step past the binding space and length octets */
2449 proto_tree_add_text(field_tree, tvb, offset + local_offset,
2450 extended_cap_length,
2451 "\tBinding Space Data (%u bytes)",
2452 extended_cap_length);
2454 tcp_info_append_uint(pinfo, "EXCAP", binding_space);
2456 /* Step past the Extended capability data
2457 * Treat the extended capability data area as opaque;
2458 * If one desires to parse the extended capability data
2459 * (say, in a vendor aware build of wireshark), it would
2462 local_offset += extended_cap_length;
2468 /* This is called for SYN+ACK packets and the purpose is to verify that
2469 * the SCPS capabilities option has been successfully negotiated for the flow.
2470 * If the SCPS capabilities option was offered by only one party, the
2471 * proactively set scps_capable attribute of the flow (set upon seeing
2472 * the first instance of the SCPS option) is revoked.
2475 verify_scps(packet_info *pinfo, proto_item *tf_syn, struct tcp_analysis *tcpd)
2480 if ((!(tcpd->flow1.scps_capable)) || (!(tcpd->flow2.scps_capable))) {
2481 tcpd->flow1.scps_capable = 0;
2482 tcpd->flow2.scps_capable = 0;
2485 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_NOTE,
2486 "Connection establish request (SYN-ACK): SCPS Capabilities Negotiated");
2491 /* See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
2492 * Transport Protocol (SCPS-TP)" Section 3.5 for definition of the SNACK option
2495 dissect_tcpopt_snack(const ip_tcp_opt *optp, tvbuff_t *tvb,
2496 int offset, guint optlen, packet_info *pinfo,
2497 proto_tree *opt_tree)
2499 struct tcp_analysis *tcpd=NULL;
2500 guint16 relative_hole_offset;
2501 guint16 relative_hole_size;
2502 guint16 base_mss = 0;
2506 char null_modifier[] = "\0";
2507 char relative_modifier[] = "(relative)";
2508 char *modifier = null_modifier;
2509 proto_item *hidden_item;
2511 tcpd = get_tcp_conversation_data(NULL,pinfo);
2513 /* The SNACK option reports missing data with a granualarity of segments. */
2514 relative_hole_offset = tvb_get_ntohs(tvb, offset + 2);
2515 relative_hole_size = tvb_get_ntohs(tvb, offset + 4);
2517 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_snack, tvb,
2518 offset, optlen, TRUE);
2519 PROTO_ITEM_SET_HIDDEN(hidden_item);
2521 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_offset,
2522 tvb, offset, optlen, relative_hole_offset);
2523 PROTO_ITEM_SET_HIDDEN(hidden_item);
2525 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_size,
2526 tvb, offset, optlen, relative_hole_size);
2527 PROTO_ITEM_SET_HIDDEN(hidden_item);
2528 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2529 "%s: Offset %u, Size %u", optp->name,
2530 relative_hole_offset, relative_hole_size);
2532 ack = tvb_get_ntohl(tvb, 8);
2534 if (tcp_relative_seq) {
2535 ack -= tcpd->rev->base_seq;
2536 modifier = relative_modifier;
2539 /* To aid analysis, we can use a simple but generally effective heuristic
2540 * to report the most likely boundaries of the missing data. If the
2541 * flow is scps_capable, we track the maximum sized segment that was
2542 * acknowledged by the receiver and use that as the reporting granularity.
2543 * This may be different from the negotiated MTU due to PMTUD or flows
2544 * that do not send max-sized segments.
2546 base_mss = tcpd->fwd->maxsizeacked;
2549 proto_item *hidden_item;
2550 /* Scale the reported offset and hole size by the largest segment acked */
2551 hole_start = ack + (base_mss * relative_hole_offset);
2552 hole_end = hole_start + (base_mss * relative_hole_size);
2554 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_le,
2555 tvb, offset, optlen, hole_start);
2556 PROTO_ITEM_SET_HIDDEN(hidden_item);
2558 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_re,
2559 tvb, offset, optlen, hole_end);
2560 PROTO_ITEM_SET_HIDDEN(hidden_item);
2561 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2562 "\tMissing Sequence %u - %u %s",
2563 hole_start, hole_end, modifier);
2565 tcp_info_append_uint(pinfo, "SNLE", hole_start);
2566 tcp_info_append_uint(pinfo, "SNRE", hole_end);
2568 expert_add_info_format(pinfo, NULL, PI_SEQUENCE, PI_NOTE,
2569 "SNACK Sequence %u - %u %s",
2570 hole_start, hole_end, modifier);
2574 static const ip_tcp_opt tcpopts[] = {
2593 "Maximum segment size",
2597 dissect_tcpopt_maxseg
2605 dissect_tcpopt_wscale
2618 &ett_tcp_option_sack,
2645 dissect_tcpopt_timestamp
2673 "TCP MD5 signature",
2682 &ett_tcp_option_scps,
2689 "Selective Negative Acknowledgement",
2693 dissect_tcpopt_snack
2697 "SCPS record boundary",
2705 "SCPS corruption experienced",
2721 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
2723 /* Determine if there is a sub-dissector and call it; return TRUE
2724 if there was a sub-dissector, FALSE otherwise.
2726 This has been separated into a stand alone routine to other protocol
2727 dissectors can call to it, e.g., SOCKS. */
2729 static gboolean try_heuristic_first = FALSE;
2732 /* this function can be called with tcpd==NULL as from the msproxy dissector */
2734 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
2735 proto_tree *tree, int src_port, int dst_port,
2736 struct tcp_analysis *tcpd)
2739 int low_port, high_port;
2740 int save_desegment_offset;
2741 guint32 save_desegment_len;
2743 /* dont call subdissectors for keepalive or zerowindowprobes
2744 * even though they do contain payload "data"
2745 * keeaplives just contain garbage and zwp contain too little data (1 byte)
2748 if(tcpd && tcpd->ta){
2749 if(tcpd->ta->flags&(TCP_A_ZERO_WINDOW_PROBE|TCP_A_KEEP_ALIVE)){
2754 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2756 /* determine if this packet is part of a conversation and call dissector */
2757 /* for the conversation if available */
2759 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
2760 src_port, dst_port, next_tvb, pinfo, tree)){
2761 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2765 if (try_heuristic_first) {
2766 /* do lookup with the heuristic subdissector table */
2767 save_desegment_offset = pinfo->desegment_offset;
2768 save_desegment_len = pinfo->desegment_len;
2769 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2770 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2774 * They rejected the packet; make sure they didn't also request
2775 * desegmentation (we could just override the request, but
2776 * rejecting a packet *and* requesting desegmentation is a sign
2777 * of the dissector's code needing clearer thought, so we fail
2778 * so that the problem is made more obvious).
2780 DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
2781 save_desegment_len == pinfo->desegment_len);
2784 /* Do lookups with the subdissector table.
2785 We try the port number with the lower value first, followed by the
2786 port number with the higher value. This means that, for packets
2787 where a dissector is registered for *both* port numbers:
2789 1) we pick the same dissector for traffic going in both directions;
2791 2) we prefer the port number that's more likely to be the right
2792 one (as that prefers well-known ports to reserved ports);
2794 although there is, of course, no guarantee that any such strategy
2795 will always pick the right port number.
2797 XXX - we ignore port numbers of 0, as some dissectors use a port
2798 number of 0 to disable the port. */
2799 if (src_port > dst_port) {
2800 low_port = dst_port;
2801 high_port = src_port;
2803 low_port = src_port;
2804 high_port = dst_port;
2806 if (low_port != 0 &&
2807 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree)){
2808 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2811 if (high_port != 0 &&
2812 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree)){
2813 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2817 if (!try_heuristic_first) {
2818 /* do lookup with the heuristic subdissector table */
2819 save_desegment_offset = pinfo->desegment_offset;
2820 save_desegment_len = pinfo->desegment_len;
2821 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2822 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2826 * They rejected the packet; make sure they didn't also request
2827 * desegmentation (we could just override the request, but
2828 * rejecting a packet *and* requesting desegmentation is a sign
2829 * of the dissector's code needing clearer thought, so we fail
2830 * so that the problem is made more obvious).
2832 DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
2833 save_desegment_len == pinfo->desegment_len);
2836 /* Oh, well, we don't know this; dissect it as data. */
2837 call_dissector(data_handle,next_tvb, pinfo, tree);
2839 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2844 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
2845 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
2846 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
2847 struct tcp_analysis *tcpd)
2849 pinfo->want_pdu_tracking=0;
2853 /*qqq see if it is an unaligned PDU */
2854 if(tcpd && tcp_analyze_seq && (!tcp_desegment)){
2856 offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
2857 seq, nxtseq, tcpd->fwd->multisegment_pdus);
2861 /* if offset is -1 this means that this segment is known
2862 * to be fully inside a previously detected pdu
2863 * so we dont even need to try to dissect it either.
2866 decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
2869 * We succeeded in handing off to a subdissector.
2871 * Is this a TCP segment or a reassembled chunk of
2875 /* if !visited, check want_pdu_tracking and
2876 store it in table */
2877 if(tcpd && (!pinfo->fd->flags.visited) &&
2878 tcp_analyze_seq && pinfo->want_pdu_tracking){
2880 pdu_store_sequencenumber_of_next_pdu(
2883 nxtseq+pinfo->bytes_until_next_pdu,
2884 tcpd->fwd->multisegment_pdus);
2891 /* We got an exception. At this point the dissection is
2892 * completely aborted and execution will be transfered back
2893 * to (probably) the frame dissector.
2894 * Here we have to place whatever we want the dissector
2895 * to do before aborting the tcp dissection.
2898 * Is this a TCP segment or a reassembled chunk of TCP
2903 * It's from a TCP segment.
2905 * if !visited, check want_pdu_tracking and store it
2908 if(tcpd && (!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking){
2910 pdu_store_sequencenumber_of_next_pdu(pinfo,
2912 nxtseq+pinfo->bytes_until_next_pdu,
2913 tcpd->fwd->multisegment_pdus);
2923 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
2924 guint32 nxtseq, guint32 sport, guint32 dport,
2925 proto_tree *tree, proto_tree *tcp_tree,
2926 struct tcp_analysis *tcpd)
2928 gboolean save_fragmented;
2930 /* Can we desegment this segment? */
2931 if (pinfo->can_desegment) {
2933 desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
2936 /* No - just call the subdissector.
2937 Mark this as fragmented, so if somebody throws an exception,
2938 we don't report it as a malformed frame. */
2939 save_fragmented = pinfo->fragmented;
2940 pinfo->fragmented = TRUE;
2941 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
2942 seq, nxtseq, TRUE, tcpd);
2943 pinfo->fragmented = save_fragmented;
2948 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2950 guint8 th_off_x2; /* combines th_off and th_x2 */
2953 proto_tree *tcp_tree = NULL, *field_tree = NULL;
2954 proto_item *ti = NULL, *tf, *hidden_item;
2956 gchar *flags = "<None>";
2957 const gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR"};
2958 size_t fpos = 0, returned_length;
2966 guint16 computed_cksum;
2967 guint16 real_window;
2968 guint length_remaining;
2969 gboolean desegment_ok;
2970 struct tcpinfo tcpinfo;
2971 struct tcpheader *tcph;
2972 proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
2973 conversation_t *conv=NULL;
2974 struct tcp_analysis *tcpd=NULL;
2975 struct tcp_per_packet_data_t *tcppd=NULL;
2977 proto_tree *checksum_tree;
2981 tcph=ep_alloc(sizeof(struct tcpheader));
2982 SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
2983 SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
2985 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2986 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2988 /* Clear out the Info column. */
2989 if (check_col(pinfo->cinfo, COL_INFO))
2990 col_clear(pinfo->cinfo, COL_INFO);
2992 tcph->th_sport = tvb_get_ntohs(tvb, offset);
2993 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
2994 if (check_col(pinfo->cinfo, COL_INFO)) {
2995 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
2996 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
2999 if (tcp_summary_in_tree) {
3000 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
3001 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
3002 get_tcp_port(tcph->th_sport), tcph->th_sport,
3003 get_tcp_port(tcph->th_dport), tcph->th_dport);
3006 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
3008 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
3009 pinfo->tcp_tree=tcp_tree;
3011 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
3012 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
3013 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
3014 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
3015 hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
3016 PROTO_ITEM_SET_HIDDEN(hidden_item);
3017 hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
3018 PROTO_ITEM_SET_HIDDEN(hidden_item);
3020 /* If we're dissecting the headers of a TCP packet in an ICMP packet
3021 * then go ahead and put the sequence numbers in the tree now (because
3022 * they won't be put in later because the ICMP packet only contains up
3023 * to the sequence number).
3024 * We should only need to do this for IPv4 since IPv6 will hopefully
3025 * carry enough TCP payload for this dissector to put the sequence
3026 * numbers in via the regular code path.
3028 if (pinfo->layer_names != NULL && pinfo->layer_names->str != NULL) {
3029 /* use strstr because g_strrstr is only present in glib2.0 and
3030 * g_str_has_suffix in glib2.2
3032 if (strstr(pinfo->layer_names->str, "icmp:ip") != NULL)
3033 proto_tree_add_item(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, FALSE);
3037 /* Set the source and destination port numbers as soon as we get them,
3038 so that they're available to the "Follow TCP Stream" code even if
3039 we throw an exception dissecting the rest of the TCP header. */
3040 pinfo->ptype = PT_TCP;
3041 pinfo->srcport = tcph->th_sport;
3042 pinfo->destport = tcph->th_dport;
3044 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
3045 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
3046 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
3047 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
3048 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
3049 real_window = tcph->th_win;
3050 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
3052 /* find(or create if needed) the conversation for this tcp session */
3053 conv=get_tcp_conversation(pinfo);
3054 tcpd=get_tcp_conversation_data(conv,pinfo);
3056 item = proto_tree_add_uint(tcp_tree, hf_tcp_stream, tvb, offset, 0, conv->index);
3057 PROTO_ITEM_SET_GENERATED(item);
3059 /* If this is a SYN packet, then check if it's seq-nr is different
3060 * from the base_seq of the retrieved conversation. If this is the
3061 * case, create a new conversation with the same addresses and ports
3062 * and set the TA_PORTS_REUSED flag. If the seq-nr is the same as
3063 * the base_seq, then do nothing so it will be marked as a retrans-
3066 if(tcpd && ((tcph->th_flags&(TH_SYN|TH_ACK))==TH_SYN) &&
3067 (tcpd->fwd->base_seq!=0) &&
3068 (tcph->th_seq!=tcpd->fwd->base_seq) ) {
3069 if (!(pinfo->fd->flags.visited)) {
3070 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
3071 tcpd=get_tcp_conversation_data(conv,pinfo);
3074 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
3075 tcpd->ta->flags|=TCP_A_REUSED_PORTS;
3079 /* Do we need to calculate timestamps relative to the tcp-stream? */
3080 if (tcp_calculate_ts) {
3081 tcppd = p_get_proto_data(pinfo->fd, proto_tcp);
3084 * Calculate the timestamps relative to this conversation (but only on the
3085 * first run when frames are accessed sequentially)
3087 if (!(pinfo->fd->flags.visited))
3088 tcp_calculate_timestamps(pinfo, tcpd, tcppd);
3090 /* Fill the conversation timestamp columns */
3091 if (tcpd && check_col(pinfo->cinfo, COL_REL_CONV_TIME)) {
3092 nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first);
3093 col_set_time(pinfo->cinfo, COL_REL_CONV_TIME, &ts, "tcp.time_relative");
3096 if (check_col(pinfo->cinfo, COL_DELTA_CONV_TIME)) {
3098 col_set_time(pinfo->cinfo, COL_DELTA_CONV_TIME, &tcppd->ts_del, "tcp.time_delta");
3104 * If we've been handed an IP fragment, we don't know how big the TCP
3105 * segment is, so don't do anything that requires that we know that.
3107 * The same applies if we're part of an error packet. (XXX - if the
3108 * ICMP and ICMPv6 dissectors could set a "this is how big the IP
3109 * header says it is" length in the tvbuff, we could use that; such
3110 * a length might also be useful for handling packets where the IP
3111 * length is bigger than the actual data available in the frame; the
3112 * dissectors should trust that length, and then throw a
3113 * ReportedBoundsError exception when they go past the end of the frame.)
3115 * We also can't determine the segment length if the reported length
3116 * of the TCP packet is less than the TCP header length.
3118 reported_len = tvb_reported_length(tvb);
3120 if (!pinfo->fragmented && !pinfo->in_error_pkt) {
3121 if (reported_len < tcph->th_hlen) {
3123 pi = proto_tree_add_text(tcp_tree, tvb, offset, 0,
3124 "Short segment. Segment/fragment does not contain a full TCP header"
3125 " (might be NMAP or someone else deliberately sending unusual packets)");
3126 PROTO_ITEM_SET_GENERATED(pi);
3127 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_WARN, "Short segment");
3128 tcph->th_have_seglen = FALSE;
3130 /* Compute the length of data in this segment. */
3131 tcph->th_seglen = reported_len - tcph->th_hlen;
3132 tcph->th_have_seglen = TRUE;
3134 if (tree) { /* Add the seglen as an invisible field */
3136 hidden_item = proto_tree_add_uint(ti, hf_tcp_len, tvb, offset+12, 1, tcph->th_seglen);
3137 PROTO_ITEM_SET_HIDDEN(hidden_item);
3142 /* handle TCP seq# analysis parse all new segments we see */
3143 if(tcp_analyze_seq){
3144 if(!(pinfo->fd->flags.visited)){
3145 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
3147 if(tcp_relative_seq){
3148 tcp_get_relative_seq_ack(&(tcph->th_seq), &(tcph->th_ack), &(tcph->th_win), tcpd);
3152 /* Compute the sequence number of next octet after this segment. */
3153 nxtseq = tcph->th_seq + tcph->th_seglen;
3156 tcph->th_have_seglen = FALSE;
3158 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
3159 #define MAX_FLAGS_LEN 64
3160 flags=ep_alloc(MAX_FLAGS_LEN);
3162 for (i = 0; i < 8; i++) {
3164 if (tcph->th_flags & bpos) {
3165 returned_length = g_snprintf(&flags[fpos], MAX_FLAGS_LEN-fpos, "%s%s",
3168 fpos += MIN(returned_length, MAX_FLAGS_LEN-fpos);
3173 if (check_col(pinfo->cinfo, COL_INFO)) {
3174 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u", flags, tcph->th_seq);
3175 if (tcph->th_flags&TH_ACK) {
3176 col_append_fstr(pinfo->cinfo, COL_INFO, " Ack=%u", tcph->th_ack);
3178 if (tcph->th_flags&TH_SYN) { /* SYNs are never scaled */
3179 col_append_fstr(pinfo->cinfo, COL_INFO, " Win=%u", real_window);
3181 col_append_fstr(pinfo->cinfo, COL_INFO, " Win=%u", tcph->th_win);
3186 if (tcp_summary_in_tree) {
3187 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
3189 if(tcp_relative_seq){
3190 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);
3192 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
3196 if (tcph->th_hlen < TCPH_MIN_LEN) {
3197 /* Give up at this point; we put the source and destination port in
3198 the tree, before fetching the header length, so that they'll
3199 show up if this is in the failing packet in an ICMP error packet,
3200 but it's now time to give up if the header length is bogus. */
3201 if (check_col(pinfo->cinfo, COL_INFO))
3202 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
3203 tcph->th_hlen, TCPH_MIN_LEN);
3205 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
3206 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
3213 if (tcp_summary_in_tree) {
3214 if(tcph->th_flags&TH_ACK){
3215 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
3217 if (tcph->th_have_seglen)
3218 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
3220 proto_item_set_len(ti, tcph->th_hlen);
3221 if (tcph->th_have_seglen) {
3222 if (nxtseq != tcph->th_seq) {
3223 if(tcp_relative_seq){
3224 tf=proto_tree_add_uint_format(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "Next sequence number: %u (relative sequence number)", nxtseq);
3226 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
3228 PROTO_ITEM_SET_GENERATED(tf);
3231 if (tcph->th_flags & TH_ACK) {
3232 if(tcp_relative_seq){
3233 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);
3235 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
3238 /* Verify that the ACK field is zero */
3239 if(tvb_get_ntohl(tvb, offset+8) != 0){
3240 proto_tree_add_text(tcp_tree, tvb, offset+8, 4,"Acknowledgement number: Broken TCP. The acknowledge field is nonzero while the ACK flag is not set");
3243 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
3244 "Header length: %u bytes", tcph->th_hlen);
3245 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
3246 tcph->th_flags, "Flags: 0x%02x (%s)", tcph->th_flags, flags);
3247 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
3248 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
3249 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
3250 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
3251 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
3252 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
3253 tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
3254 tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
3255 tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
3257 && (tcph->th_win!=real_window)
3258 && !(tcph->th_flags&TH_SYN) ){ /* SYNs are never scaled */
3259 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);
3261 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, real_window);
3265 if(tcph->th_flags & TH_SYN) {
3266 if(tcph->th_flags & TH_ACK)
3267 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): server port %s",
3268 get_tcp_port(tcph->th_sport));
3270 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): server port %s",
3271 get_tcp_port(tcph->th_dport));
3273 if(tcph->th_flags & TH_FIN)
3274 /* XXX - find a way to know the server port and output only that one */
3275 expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN)");
3276 if(tcph->th_flags & TH_RST)
3277 /* XXX - find a way to know the server port and output only that one */
3278 expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST)");
3280 /* Supply the sequence number of the first byte and of the first byte
3281 after the segment. */
3282 tcpinfo.seq = tcph->th_seq;
3283 tcpinfo.nxtseq = nxtseq;
3284 tcpinfo.lastackseq = tcph->th_ack;
3286 /* Assume we'll pass un-reassembled data to subdissectors. */
3287 tcpinfo.is_reassembled = FALSE;
3289 pinfo->private_data = &tcpinfo;
3292 * Assume, initially, that we can't desegment.
3294 pinfo->can_desegment = 0;
3295 th_sum = tvb_get_ntohs(tvb, offset + 16);
3296 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
3297 /* The packet isn't part of an un-reassembled fragmented datagram
3298 and isn't truncated. This means we have all the data, and thus
3299 can checksum it and, unless it's being returned in an error
3300 packet, are willing to allow subdissectors to request reassembly
3303 if (tcp_check_checksum) {
3304 /* We haven't turned checksum checking off; checksum it. */
3306 /* Set up the fields of the pseudo-header. */
3307 cksum_vec[0].ptr = pinfo->src.data;
3308 cksum_vec[0].len = pinfo->src.len;
3309 cksum_vec[1].ptr = pinfo->dst.data;
3310 cksum_vec[1].len = pinfo->dst.len;
3311 cksum_vec[2].ptr = (const guint8 *)phdr;
3312 switch (pinfo->src.type) {
3315 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
3316 cksum_vec[2].len = 4;
3320 phdr[0] = g_htonl(reported_len);
3321 phdr[1] = g_htonl(IP_PROTO_TCP);
3322 cksum_vec[2].len = 8;
3326 /* TCP runs only atop IPv4 and IPv6.... */
3327 DISSECTOR_ASSERT_NOT_REACHED();
3330 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
3331 cksum_vec[3].len = reported_len;
3332 computed_cksum = in_cksum(cksum_vec, 4);
3333 if (computed_cksum == 0 && th_sum == 0xffff) {
3334 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3335 offset + 16, 2, th_sum,
3336 "Checksum: 0x%04x [should be 0x0000 (see RFC 1624)]", th_sum);
3338 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3339 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3340 offset + 16, 2, FALSE);
3341 PROTO_ITEM_SET_GENERATED(item);
3342 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3343 offset + 16, 2, FALSE);
3344 PROTO_ITEM_SET_GENERATED(item);
3345 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_WARN, "TCP Checksum 0xffff instead of 0x0000 (see RFC 1624)");
3347 if (check_col(pinfo->cinfo, COL_INFO))
3348 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM 0xFFFF]");
3350 /* Checksum is treated as valid on most systems, so we're willing to desegment it. */
3351 desegment_ok = TRUE;
3352 } else if (computed_cksum == 0) {
3353 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3354 offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
3356 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3357 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3358 offset + 16, 2, TRUE);
3359 PROTO_ITEM_SET_GENERATED(item);
3360 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3361 offset + 16, 2, FALSE);
3362 PROTO_ITEM_SET_GENERATED(item);
3364 /* Checksum is valid, so we're willing to desegment it. */
3365 desegment_ok = TRUE;
3366 } else if (th_sum == 0) {
3367 /* checksum is probably fine but checksum offload is used */
3368 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3369 offset + 16, 2, th_sum, "Checksum: 0x%04x [Checksum Offloaded]", th_sum);
3371 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3372 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3373 offset + 16, 2, FALSE);
3374 PROTO_ITEM_SET_GENERATED(item);
3375 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3376 offset + 16, 2, FALSE);
3377 PROTO_ITEM_SET_GENERATED(item);
3379 /* Checksum is (probably) valid, so we're willing to desegment it. */
3380 desegment_ok = TRUE;
3382 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3383 offset + 16, 2, th_sum,
3384 "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by \"TCP checksum offload\"?)]", th_sum,
3385 in_cksum_shouldbe(th_sum, computed_cksum));
3387 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3388 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3389 offset + 16, 2, FALSE);
3390 PROTO_ITEM_SET_GENERATED(item);
3391 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3392 offset + 16, 2, TRUE);
3393 PROTO_ITEM_SET_GENERATED(item);
3394 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
3396 if (check_col(pinfo->cinfo, COL_INFO))
3397 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
3399 /* Checksum is invalid, so we're not willing to desegment it. */
3400 desegment_ok = FALSE;
3401 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
3404 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3405 offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
3407 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3408 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3409 offset + 16, 2, FALSE);
3410 PROTO_ITEM_SET_GENERATED(item);
3411 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3412 offset + 16, 2, FALSE);
3413 PROTO_ITEM_SET_GENERATED(item);
3415 /* We didn't check the checksum, and don't care if it's valid,
3416 so we're willing to desegment it. */
3417 desegment_ok = TRUE;
3420 /* We don't have all the packet data, so we can't checksum it... */
3421 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3422 offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
3424 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3425 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3426 offset + 16, 2, FALSE);
3427 PROTO_ITEM_SET_GENERATED(item);
3428 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3429 offset + 16, 2, FALSE);
3430 PROTO_ITEM_SET_GENERATED(item);
3432 /* ...and aren't willing to desegment it. */
3433 desegment_ok = FALSE;
3437 /* We're willing to desegment this. Is desegmentation enabled? */
3438 if (tcp_desegment) {
3439 /* Yes - is this segment being returned in an error packet? */
3440 if (!pinfo->in_error_pkt) {
3441 /* No - indicate that we will desegment.
3442 We do NOT want to desegment segments returned in error
3443 packets, as they're not part of a TCP connection. */
3444 pinfo->can_desegment = 2;
3449 if (tcph->th_flags & TH_URG) {
3450 th_urp = tvb_get_ntohs(tvb, offset + 18);
3451 /* Export the urgent pointer, for the benefit of protocols such as
3453 tcpinfo.urgent = TRUE;
3454 tcpinfo.urgent_pointer = th_urp;
3455 if (check_col(pinfo->cinfo, COL_INFO))
3456 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
3457 if (tcp_tree != NULL)
3458 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
3460 tcpinfo.urgent = FALSE;
3462 if (tcph->th_have_seglen) {
3463 if (check_col(pinfo->cinfo, COL_INFO))
3464 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
3467 /* Decode TCP options, if any. */
3468 if (tcph->th_hlen > TCPH_MIN_LEN) {
3469 /* There's more than just the fixed-length header. Decode the
3471 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
3472 tvb_ensure_bytes_exist(tvb, offset + 20, optlen);
3473 if (tcp_tree != NULL) {
3474 guint8 *p_options = ep_tvb_memdup(tvb, offset + 20, optlen);
3475 tf = proto_tree_add_bytes_format(tcp_tree, hf_tcp_options, tvb, offset + 20,
3476 optlen, p_options, "Options: (%u bytes)", optlen);
3477 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
3480 dissect_ip_tcp_options(tvb, offset + 20, optlen,
3481 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
3484 if(!pinfo->fd->flags.visited){
3485 if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
3486 /* If there was window scaling in the SYN packet but none in the SYN+ACK
3487 * then we should just forget about the windowscaling completely.
3489 if(tcp_analyze_seq && tcp_relative_seq){
3490 verify_tcp_window_scaling(tcpd);
3492 /* If the SYN or the SYN+ACK offered SCPS capabilities,
3493 * validate the flow's bidirectional scps capabilities.
3494 * The or protects against broken implementations offering
3495 * SCPS capabilities on SYN+ACK even if it wasn't offered with the SYN
3497 if(tcpd && ((tcpd->rev->scps_capable) || (tcpd->fwd->scps_capable))) {
3498 verify_scps(pinfo, tf_syn, tcpd);
3503 /* Skip over header + options */
3504 offset += tcph->th_hlen;
3506 /* Check the packet length to see if there's more data
3507 (it could be an ACK-only packet) */
3508 length_remaining = tvb_length_remaining(tvb, offset);
3510 if (tcph->th_have_seglen) {
3511 if( data_out_file ) {
3512 reassemble_tcp( tcph->th_seq, /* sequence number */
3513 tcph->th_ack, /* acknowledgement number */
3514 tcph->th_seglen, /* data length */
3515 (gchar*)tvb_get_ptr(tvb, offset, length_remaining), /* data */
3516 length_remaining, /* captured data length */
3517 ( tcph->th_flags & TH_SYN ), /* is syn set? */
3525 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
3526 if(tcp_analyze_seq){
3527 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd);
3530 /* handle conversation timestamps */
3531 if(tcp_calculate_ts){
3532 tcp_print_timestamps(pinfo, tvb, tcp_tree, tcpd, tcppd);
3535 tap_queue_packet(tcp_tap, pinfo, tcph);
3538 /* A FIN packet might complete reassembly so we need to explicitly
3539 * check for this here.
3541 if(tcpd && (tcph->th_flags & TH_FIN)
3542 && (tcpd->fwd->flags&TCP_FLOW_REASSEMBLE_UNTIL_FIN) ){
3543 struct tcp_multisegment_pdu *msp;
3545 /* find the most previous PDU starting before this sequence number */
3546 msp=se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, tcph->th_seq-1);
3548 fragment_data *ipfd_head;
3550 ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
3552 tcph->th_seq - msp->seq,
3558 /* create a new TVB structure for desegmented data */
3559 next_tvb = tvb_new_real_data(ipfd_head->data, ipfd_head->datalen, ipfd_head->datalen);
3561 /* add this tvb as a child to the original one */
3562 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
3564 /* add desegmented data to the data source list */
3565 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
3567 /* call the payload dissector
3568 * but make sure we don't offer desegmentation any more
3570 pinfo->can_desegment = 0;
3572 process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, tcph->th_sport, tcph->th_dport, tcph->th_seq, nxtseq, FALSE, tcpd);
3580 * XXX - what, if any, of this should we do if this is included in an
3581 * error packet? It might be nice to see the details of the packet
3582 * that caused the ICMP error, but it might not be nice to have the
3583 * dissector update state based on it.
3584 * Also, we probably don't want to run TCP taps on those packets.
3586 if (length_remaining != 0) {
3587 if (tcph->th_flags & TH_RST) {
3591 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
3593 * A TCP SHOULD allow a received RST segment to include data.
3596 * It has been suggested that a RST segment could contain
3597 * ASCII text that encoded and explained the cause of the
3598 * RST. No standard has yet been established for such
3601 * so for segments with RST we just display the data as text.
3603 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
3605 tvb_format_text(tvb, offset, length_remaining));
3607 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
3608 tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd);
3614 proto_register_tcp(void)
3616 static hf_register_info hf[] = {
3619 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
3623 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
3627 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
3631 { "Stream index", "tcp.stream", FT_UINT32, BASE_DEC, NULL, 0x0,
3635 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
3639 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
3643 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
3647 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
3651 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
3654 { &hf_tcp_flags_cwr,
3655 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
3658 { &hf_tcp_flags_ecn,
3659 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
3662 { &hf_tcp_flags_urg,
3663 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
3666 { &hf_tcp_flags_ack,
3667 { "Acknowledgement", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
3670 { &hf_tcp_flags_push,
3671 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
3674 { &hf_tcp_flags_reset,
3675 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
3678 { &hf_tcp_flags_syn,
3679 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
3682 { &hf_tcp_flags_fin,
3683 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
3686 /* 32 bits so we can present some values adjusted to window scaling */
3687 { &hf_tcp_window_size,
3688 { "Window size", "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
3692 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
3693 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
3695 { &hf_tcp_checksum_good,
3696 { "Good Checksum", "tcp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3697 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
3699 { &hf_tcp_checksum_bad,
3700 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3701 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
3703 { &hf_tcp_analysis_flags,
3704 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
3705 "This frame has some of the TCP analysis flags set", HFILL }},
3707 { &hf_tcp_analysis_retransmission,
3708 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
3709 "This frame is a suspected TCP retransmission", HFILL }},
3711 { &hf_tcp_analysis_fast_retransmission,
3712 { "Fast Retransmission", "tcp.analysis.fast_retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
3713 "This frame is a suspected TCP fast retransmission", HFILL }},
3715 { &hf_tcp_analysis_out_of_order,
3716 { "Out Of Order", "tcp.analysis.out_of_order", FT_NONE, BASE_NONE, NULL, 0x0,
3717 "This frame is a suspected Out-Of-Order segment", HFILL }},
3719 { &hf_tcp_analysis_reused_ports,
3720 { "TCP Port numbers reused", "tcp.analysis.reused_ports", FT_NONE, BASE_NONE, NULL, 0x0,
3721 "A new tcp session has started with previously used port numbers", HFILL }},
3723 { &hf_tcp_analysis_lost_packet,
3724 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
3725 "A segment before this one was lost from the capture", HFILL }},
3727 { &hf_tcp_analysis_ack_lost_packet,
3728 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
3729 "This frame ACKs a lost segment", HFILL }},
3731 { &hf_tcp_analysis_window_update,
3732 { "Window update", "tcp.analysis.window_update", FT_NONE, BASE_NONE, NULL, 0x0,
3733 "This frame is a tcp window update", HFILL }},
3735 { &hf_tcp_analysis_window_full,
3736 { "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
3737 "This segment has caused the allowed window to become 100% full", HFILL }},
3739 { &hf_tcp_analysis_keep_alive,
3740 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
3741 "This is a keep-alive segment", HFILL }},
3743 { &hf_tcp_analysis_keep_alive_ack,
3744 { "Keep Alive ACK", "tcp.analysis.keep_alive_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3745 "This is an ACK to a keep-alive segment", HFILL }},
3747 { &hf_tcp_analysis_duplicate_ack,
3748 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3749 "This is a duplicate ACK", HFILL }},
3751 { &hf_tcp_analysis_duplicate_ack_num,
3752 { "Duplicate ACK #", "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
3753 "This is duplicate ACK number #", HFILL }},
3755 { &hf_tcp_analysis_duplicate_ack_frame,
3756 { "Duplicate to the ACK in frame", "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3757 "This is a duplicate to the ACK in frame #", HFILL }},
3759 { &hf_tcp_continuation_to,
3760 { "This is a continuation to the PDU in frame", "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3761 "This is a continuation to the PDU in frame #", HFILL }},
3763 { &hf_tcp_analysis_zero_window_probe,
3764 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
3765 "This is a zero-window-probe", HFILL }},
3767 { &hf_tcp_analysis_zero_window_probe_ack,
3768 { "Zero Window Probe Ack", "tcp.analysis.zero_window_probe_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3769 "This is an ACK to a zero-window-probe", HFILL }},
3771 { &hf_tcp_analysis_zero_window,
3772 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
3773 "This is a zero-window", HFILL }},
3776 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
3779 { &hf_tcp_analysis_acks_frame,
3780 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3781 "Which previous segment is this an ACK for", HFILL}},
3783 { &hf_tcp_analysis_bytes_in_flight,
3784 { "Number of bytes in flight", "tcp.analysis.bytes_in_flight", FT_UINT32, BASE_DEC, NULL, 0x0,
3785 "How many bytes are now in flight for this connection", HFILL}},
3787 { &hf_tcp_analysis_ack_rtt,
3788 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3789 "How long time it took to ACK the segment (RTT)", HFILL}},
3791 { &hf_tcp_analysis_rto,
3792 { "The RTO for this segment was", "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3793 "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
3795 { &hf_tcp_analysis_rto_frame,
3796 { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3797 "This is the frame we measure the RTO from", HFILL }},
3799 { &hf_tcp_urgent_pointer,
3800 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
3803 { &hf_tcp_segment_overlap,
3804 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3805 "Segment overlaps with other segments", HFILL }},
3807 { &hf_tcp_segment_overlap_conflict,
3808 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3809 "Overlapping segments contained conflicting data", HFILL }},
3811 { &hf_tcp_segment_multiple_tails,
3812 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3813 "Several tails were found when reassembling the pdu", HFILL }},
3815 { &hf_tcp_segment_too_long_fragment,
3816 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3817 "Segment contained data past end of the pdu", HFILL }},
3819 { &hf_tcp_segment_error,
3820 { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3821 "Reassembling error due to illegal segments", HFILL }},
3824 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3825 "TCP Segment", HFILL }},
3828 { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
3829 "TCP Segments", HFILL }},
3831 { &hf_tcp_reassembled_in,
3832 { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3833 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
3836 { "TCP Options", "tcp.options", FT_BYTES,
3837 BASE_HEX, NULL, 0x0, "TCP Options", HFILL }},
3839 { &hf_tcp_option_mss,
3840 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
3841 BASE_NONE, NULL, 0x0, "TCP MSS Option", HFILL }},
3843 { &hf_tcp_option_mss_val,
3844 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
3845 BASE_DEC, NULL, 0x0, "TCP MSS Option Value", HFILL}},
3847 { &hf_tcp_option_wscale,
3848 { "TCP Window Scale Option", "tcp.options.wscale",
3850 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
3852 { &hf_tcp_option_wscale_val,
3853 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
3854 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
3857 { &hf_tcp_option_sack_perm,
3858 { "TCP Sack Perm Option", "tcp.options.sack_perm",
3860 BASE_NONE, NULL, 0x0, "TCP Sack Perm Option", HFILL}},
3862 { &hf_tcp_option_sack,
3863 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
3864 BASE_NONE, NULL, 0x0, "TCP Sack Option", HFILL}},
3866 { &hf_tcp_option_sack_sle,
3867 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
3868 BASE_DEC, NULL, 0x0, "TCP Sack Left Edge", HFILL}},
3870 { &hf_tcp_option_sack_sre,
3871 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
3872 BASE_DEC, NULL, 0x0, "TCP Sack Right Edge", HFILL}},
3874 { &hf_tcp_option_echo,
3875 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
3876 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
3878 { &hf_tcp_option_echo_reply,
3879 { "TCP Echo Reply Option", "tcp.options.echo_reply",
3881 BASE_NONE, NULL, 0x0, "TCP Echo Reply Option", HFILL}},
3883 { &hf_tcp_option_time_stamp,
3884 { "TCP Time Stamp Option", "tcp.options.time_stamp",
3886 BASE_NONE, NULL, 0x0, "TCP Time Stamp Option", HFILL}},
3888 { &hf_tcp_option_cc,
3889 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
3890 NULL, 0x0, "TCP CC Option", HFILL}},
3892 { &hf_tcp_option_ccnew,
3893 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
3894 BASE_NONE, NULL, 0x0, "TCP CC New Option", HFILL}},
3896 { &hf_tcp_option_ccecho,
3897 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
3898 BASE_NONE, NULL, 0x0, "TCP CC Echo Option", HFILL}},
3900 { &hf_tcp_option_md5,
3901 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
3902 NULL, 0x0, "TCP MD5 Option", HFILL}},
3904 { &hf_tcp_option_qs,
3905 { "TCP QS Option", "tcp.options.qs", FT_BOOLEAN, BASE_NONE,
3906 NULL, 0x0, "TCP QS Option", HFILL}},
3908 { &hf_tcp_option_scps,
3909 { "TCP SCPS Capabilities Option", "tcp.options.scps",
3910 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3911 "TCP SCPS Capabilities Option", HFILL}},
3913 { &hf_tcp_option_scps_vector,
3914 { "TCP SCPS Capabilities Vector", "tcp.options.scps.vector",
3915 FT_UINT8, BASE_DEC, NULL, 0x0,
3916 "TCP SCPS Capabilities Vector", HFILL}},
3918 { &hf_tcp_option_scps_binding,
3919 { "TCP SCPS Extended Binding Spacce",
3920 "tcp.options.scps.binding",
3921 FT_UINT8, BASE_DEC, NULL, 0x0,
3922 "TCP SCPS Extended Binding Space", HFILL}},
3924 { &hf_tcp_option_snack,
3925 { "TCP Selective Negative Acknowledgement Option",
3926 "tcp.options.snack",
3927 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3928 "TCP Selective Negative Acknowledgement Option", HFILL}},
3930 { &hf_tcp_option_snack_offset,
3931 { "TCP SNACK Offset", "tcp.options.snack.offset",
3932 FT_UINT16, BASE_DEC, NULL, 0x0,
3933 "TCP SNACK Offset", HFILL}},
3935 { &hf_tcp_option_snack_size,
3936 { "TCP SNACK Size", "tcp.options.snack.size",
3937 FT_UINT16, BASE_DEC, NULL, 0x0,
3938 "TCP SNACK Size", HFILL}},
3940 { &hf_tcp_option_snack_le,
3941 { "TCP SNACK Left Edge", "tcp.options.snack.le",
3942 FT_UINT16, BASE_DEC, NULL, 0x0,
3943 "TCP SNACK Left Edge", HFILL}},
3945 { &hf_tcp_option_snack_re,
3946 { "TCP SNACK Right Edge", "tcp.options.snack.re",
3947 FT_UINT16, BASE_DEC, NULL, 0x0,
3948 "TCP SNACK Right Edge", HFILL}},
3950 { &hf_tcp_scpsoption_flags_bets,
3951 { "Partial Reliability Capable (BETS)",
3952 "tcp.options.scpsflags.bets", FT_BOOLEAN, 8,
3953 TFS(&flags_set_truth), 0x80, "", HFILL }},
3955 { &hf_tcp_scpsoption_flags_snack1,
3956 { "Short Form SNACK Capable (SNACK1)",
3957 "tcp.options.scpsflags.snack1", FT_BOOLEAN, 8,
3958 TFS(&flags_set_truth), 0x40, "", HFILL }},
3960 { &hf_tcp_scpsoption_flags_snack2,
3961 { "Long Form SNACK Capable (SNACK2)",
3962 "tcp.options.scpsflags.snack2", FT_BOOLEAN, 8,
3963 TFS(&flags_set_truth), 0x20, "", HFILL }},
3965 { &hf_tcp_scpsoption_flags_compress,
3966 { "Lossless Header Compression (COMP)",
3967 "tcp.options.scpsflags.compress", FT_BOOLEAN, 8,
3968 TFS(&flags_set_truth), 0x10, "", HFILL }},
3970 { &hf_tcp_scpsoption_flags_nlts,
3971 { "Network Layer Timestamp (NLTS)",
3972 "tcp.options.scpsflags.nlts", FT_BOOLEAN, 8,
3973 TFS(&flags_set_truth), 0x8, "", HFILL }},
3975 { &hf_tcp_scpsoption_flags_resv1,
3977 "tcp.options.scpsflags.reserved1", FT_BOOLEAN, 8,
3978 TFS(&flags_set_truth), 0x4, "", HFILL }},
3980 { &hf_tcp_scpsoption_flags_resv2,
3982 "tcp.options.scpsflags.reserved2", FT_BOOLEAN, 8,
3983 TFS(&flags_set_truth), 0x2, "", HFILL }},
3985 { &hf_tcp_scpsoption_flags_resv3,
3987 "tcp.options.scpsflags.reserved3", FT_BOOLEAN, 8,
3988 TFS(&flags_set_truth), 0x1, "", HFILL }},
3991 { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3992 "How long time has passed until the last frame of this PDU", HFILL}},
3995 { "PDU Size", "tcp.pdu.size", FT_UINT32, BASE_DEC, NULL, 0x0,
3996 "The size of this PDU", HFILL}},
3998 { &hf_tcp_pdu_last_frame,
3999 { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4000 "This is the last frame of the PDU starting in this segment", HFILL }},
4002 { &hf_tcp_ts_relative,
4003 { "Time since first frame in this TCP stream", "tcp.time_relative", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4004 "Time relative to first frame in this TCP stream", HFILL}},
4007 { "Time since previous frame in this TCP stream", "tcp.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4008 "Time delta from previous frame in this TCP stream", HFILL}},
4011 static gint *ett[] = {
4015 &ett_tcp_option_sack,
4016 &ett_tcp_option_scps,
4017 &ett_tcp_option_scps_extended,
4018 &ett_tcp_analysis_faults,
4020 &ett_tcp_timestamps,
4025 module_t *tcp_module;
4027 proto_tcp = proto_register_protocol("Transmission Control Protocol",
4029 proto_register_field_array(proto_tcp, hf, array_length(hf));
4030 proto_register_subtree_array(ett, array_length(ett));
4032 /* subdissector code */
4033 subdissector_table = register_dissector_table("tcp.port",
4034 "TCP port", FT_UINT16, BASE_DEC);
4035 register_heur_dissector_list("tcp", &heur_subdissector_list);
4037 /* Register configuration preferences */
4038 tcp_module = prefs_register_protocol(proto_tcp, NULL);
4039 prefs_register_bool_preference(tcp_module, "summary_in_tree",
4040 "Show TCP summary in protocol tree",
4041 "Whether the TCP summary line should be shown in the protocol tree",
4042 &tcp_summary_in_tree);
4043 prefs_register_bool_preference(tcp_module, "check_checksum",
4044 "Validate the TCP checksum if possible",
4045 "Whether to validate the TCP checksum",
4046 &tcp_check_checksum);
4047 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
4048 "Allow subdissector to reassemble TCP streams",
4049 "Whether subdissector can request TCP streams to be reassembled",
4051 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
4052 "Analyze TCP sequence numbers",
4053 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
4055 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
4056 "Relative sequence numbers and window scaling",
4057 "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
4058 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
4059 "This option will also try to track and adjust the window field according to any TCP window scaling options seen.",
4061 prefs_register_bool_preference(tcp_module, "track_bytes_in_flight",
4062 "Track number of bytes in flight",
4063 "Make the TCP dissector track the number on un-ACKed bytes of data are in flight per packet. "
4064 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
4065 "This takes a lot of memory but allows you to track how much data are in flight at a time and graphing it in io-graphs",
4066 &tcp_track_bytes_in_flight);
4067 prefs_register_bool_preference(tcp_module, "calculate_timestamps",
4068 "Calculate conversation timestamps",
4069 "Calculate timestamps relative to the first frame and the previous frame in the tcp conversation",
4071 prefs_register_bool_preference(tcp_module, "try_heuristic_first",
4072 "Try heuristic sub-dissectors first",
4073 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
4074 &try_heuristic_first);
4076 register_init_routine(tcp_fragment_init);
4080 proto_reg_handoff_tcp(void)
4082 dissector_handle_t tcp_handle;
4084 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
4085 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
4086 data_handle = find_dissector("data");
4087 tcp_tap = register_tap("tcp");