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;
162 static int hf_tcp_proc_src_uid = -1;
163 static int hf_tcp_proc_src_pid = -1;
164 static int hf_tcp_proc_src_uname = -1;
165 static int hf_tcp_proc_src_cmd = -1;
166 static int hf_tcp_proc_dst_uid = -1;
167 static int hf_tcp_proc_dst_pid = -1;
168 static int hf_tcp_proc_dst_uname = -1;
169 static int hf_tcp_proc_dst_cmd = -1;
171 static gint ett_tcp = -1;
172 static gint ett_tcp_flags = -1;
173 static gint ett_tcp_options = -1;
174 static gint ett_tcp_option_sack = -1;
175 static gint ett_tcp_option_scps = -1;
176 static gint ett_tcp_option_scps_extended = -1;
177 static gint ett_tcp_analysis = -1;
178 static gint ett_tcp_analysis_faults = -1;
179 static gint ett_tcp_timestamps = -1;
180 static gint ett_tcp_segments = -1;
181 static gint ett_tcp_segment = -1;
182 static gint ett_tcp_checksum = -1;
183 static gint ett_tcp_process_info = -1;
186 /* not all of the hf_fields below make sense for TCP but we have to provide
187 them anyways to comply with the api (which was aimed for ip fragment
189 static const fragment_items tcp_segment_items = {
194 &hf_tcp_segment_overlap,
195 &hf_tcp_segment_overlap_conflict,
196 &hf_tcp_segment_multiple_tails,
197 &hf_tcp_segment_too_long_fragment,
198 &hf_tcp_segment_error,
199 &hf_tcp_reassembled_in,
203 static dissector_table_t subdissector_table;
204 static heur_dissector_list_t heur_subdissector_list;
205 static dissector_handle_t data_handle;
207 /* TCP structs and definitions */
209 /* **************************************************************************
211 * RTT and reltive sequence numbers.
212 * **************************************************************************/
213 static gboolean tcp_analyze_seq = TRUE;
214 static gboolean tcp_relative_seq = TRUE;
215 static gboolean tcp_track_bytes_in_flight = TRUE;
216 static gboolean tcp_calculate_ts = FALSE;
218 /* SLAB allocator for tcp_unacked structures
220 SLAB_ITEM_TYPE_DEFINE(tcp_unacked_t)
221 static SLAB_FREE_LIST_DEFINE(tcp_unacked_t)
222 #define TCP_UNACKED_NEW(fi) \
223 SLAB_ALLOC(fi, tcp_unacked_t)
224 #define TCP_UNACKED_FREE(fi) \
225 SLAB_FREE(fi, tcp_unacked_t)
228 #define TCP_A_RETRANSMISSION 0x0001
229 #define TCP_A_LOST_PACKET 0x0002
230 #define TCP_A_ACK_LOST_PACKET 0x0004
231 #define TCP_A_KEEP_ALIVE 0x0008
232 #define TCP_A_DUPLICATE_ACK 0x0010
233 #define TCP_A_ZERO_WINDOW 0x0020
234 #define TCP_A_ZERO_WINDOW_PROBE 0x0040
235 #define TCP_A_ZERO_WINDOW_PROBE_ACK 0x0080
236 #define TCP_A_KEEP_ALIVE_ACK 0x0100
237 #define TCP_A_OUT_OF_ORDER 0x0200
238 #define TCP_A_FAST_RETRANSMISSION 0x0400
239 #define TCP_A_WINDOW_UPDATE 0x0800
240 #define TCP_A_WINDOW_FULL 0x1000
241 #define TCP_A_REUSED_PORTS 0x2000
245 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
246 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
247 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
248 struct tcp_analysis *tcpd);
251 struct tcp_analysis *
252 init_tcp_conversation_data(packet_info *pinfo)
254 struct tcp_analysis *tcpd=NULL;
256 /* Initialize the tcp protocol datat structure to add to the tcp conversation */
257 tcpd=se_alloc0(sizeof(struct tcp_analysis));
258 memset(&tcpd->flow1, 0, sizeof(tcp_flow_t));
259 memset(&tcpd->flow2, 0, sizeof(tcp_flow_t));
260 tcpd->flow1.win_scale=-1;
261 tcpd->flow1.multisegment_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_multisegment_pdus");
262 tcpd->flow1.username = NULL;
263 tcpd->flow1.command = NULL;
264 tcpd->flow2.win_scale=-1;
265 tcpd->flow2.multisegment_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_multisegment_pdus");
266 tcpd->flow2.username = NULL;
267 tcpd->flow2.command = NULL;
268 tcpd->acked_table=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "tcp_analyze_acked_table");
269 tcpd->ts_first.secs=pinfo->fd->abs_ts.secs;
270 tcpd->ts_first.nsecs=pinfo->fd->abs_ts.nsecs;
271 tcpd->ts_prev.secs=pinfo->fd->abs_ts.secs;
272 tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs;
278 get_tcp_conversation(packet_info *pinfo)
280 conversation_t *conv=NULL;
282 /* Have we seen this conversation before? */
283 if( (conv=find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
284 /* No this is a new conversation. */
285 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
290 struct tcp_analysis *
291 get_tcp_conversation_data(conversation_t *conv, packet_info *pinfo)
294 struct tcp_analysis *tcpd=NULL;
296 /* Did the caller supply the conversation pointer? */
298 conv = get_tcp_conversation(pinfo);
300 /* Get the data for this conversation */
301 tcpd=conversation_get_proto_data(conv, proto_tcp);
303 /* If the conversation was just created or it matched a
304 * conversation with template options, tcpd will not
305 * have been initialized. So, initialize
306 * a new tcpd structure for the conversation.
309 tcpd = init_tcp_conversation_data(pinfo);
310 conversation_add_proto_data(conv, proto_tcp, tcpd);
317 /* check direction and get ua lists */
318 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
319 /* if the addresses are equal, match the ports instead */
321 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
324 tcpd->fwd=&(tcpd->flow1);
325 tcpd->rev=&(tcpd->flow2);
327 tcpd->fwd=&(tcpd->flow2);
328 tcpd->rev=&(tcpd->flow1);
335 /* Attach process info to a flow */
336 /* XXX - We depend on the TCP dissector finding the conversation first */
338 add_tcp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, gchar *username, gchar *command) {
339 conversation_t *conv;
340 struct tcp_analysis *tcpd;
341 tcp_flow_t *flow = NULL;
343 conv = find_conversation(frame_num, local_addr, remote_addr, PT_TCP, local_port, remote_port, 0);
348 tcpd = conversation_get_proto_data(conv, proto_tcp);
353 if (CMP_ADDRESS(local_addr, &conv->key_ptr->addr1) == 0 && local_port == conv->key_ptr->port1) {
355 } else if (CMP_ADDRESS(remote_addr, &conv->key_ptr->addr1) == 0 && remote_port == conv->key_ptr->port1) {
358 if (!flow || flow->command) {
362 flow->process_uid = uid;
363 flow->process_pid = pid;
364 flow->username = se_strdup(username);
365 flow->command = se_strdup(command);
369 /* Calculate the timestamps relative to this conversation */
371 tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd,
372 struct tcp_per_packet_data_t *tcppd)
375 tcppd = se_alloc(sizeof(struct tcp_per_packet_data_t));
376 p_add_proto_data(pinfo->fd, proto_tcp, tcppd);
382 nstime_delta(&tcppd->ts_del, &pinfo->fd->abs_ts, &tcpd->ts_prev);
384 tcpd->ts_prev.secs=pinfo->fd->abs_ts.secs;
385 tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs;
388 /* Add a subtree with the timestamps relative to this conversation */
390 tcp_print_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd, struct tcp_per_packet_data_t *tcppd)
399 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "Timestamps");
400 PROTO_ITEM_SET_GENERATED(item);
401 tree=proto_item_add_subtree(item, ett_tcp_timestamps);
403 nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first);
404 item = proto_tree_add_time(tree, hf_tcp_ts_relative, tvb, 0, 0, &ts);
405 PROTO_ITEM_SET_GENERATED(item);
408 tcppd = p_get_proto_data(pinfo->fd, proto_tcp);
411 item = proto_tree_add_time(tree, hf_tcp_ts_delta, tvb, 0, 0,
413 PROTO_ITEM_SET_GENERATED(item);
418 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_multisegment_pdu *msp)
422 if (check_col(pinfo->cinfo, COL_INFO)){
423 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", msp->first_frame);
425 item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
426 tvb, 0, 0, msp->first_frame);
427 PROTO_ITEM_SET_GENERATED(item);
430 /* if we know that a PDU starts inside this segment, return the adjusted
431 offset to where that PDU starts or just return offset back
432 and let TCP try to find out what it can about this segment
435 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)
437 struct tcp_multisegment_pdu *msp=NULL;
439 if(!pinfo->fd->flags.visited){
440 msp=se_tree_lookup32_le(multisegment_pdus, seq-1);
442 /* If this is a continuation of a PDU started in a
443 * previous segment we need to update the last_frame
446 if(seq>msp->seq && seq<msp->nxtpdu){
447 msp->last_frame=pinfo->fd->num;
448 msp->last_frame_time=pinfo->fd->abs_ts;
449 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
452 /* If this segment is completely within a previous PDU
453 * then we just skip this packet
455 if(seq>msp->seq && nxtseq<=msp->nxtpdu){
458 if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu){
459 offset+=msp->nxtpdu-seq;
465 /* First we try to find the start and transfer time for a PDU.
466 * We only print this for the very first segment of a PDU
467 * and only for PDUs spanning multiple segments.
468 * Se we look for if there was any multisegment PDU started
469 * just BEFORE the end of this segment. I.e. either inside this
470 * segment or in a previous segment.
471 * Since this might also match PDUs that are completely within
472 * this segment we also verify that the found PDU does span
473 * beyond the end of this segment.
475 msp=se_tree_lookup32_le(multisegment_pdus, nxtseq-1);
477 if( (pinfo->fd->num==msp->first_frame)
482 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, msp->last_frame);
483 PROTO_ITEM_SET_GENERATED(item);
485 nstime_delta(&ns, &msp->last_frame_time, &pinfo->fd->abs_ts);
486 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
488 PROTO_ITEM_SET_GENERATED(item);
492 /* Second we check if this segment is part of a PDU started
493 * prior to the segment (seq-1)
495 msp=se_tree_lookup32_le(multisegment_pdus, seq-1);
497 /* If this segment is completely within a previous PDU
498 * then we just skip this packet
500 if(seq>msp->seq && nxtseq<=msp->nxtpdu){
501 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
505 if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu){
506 offset+=msp->nxtpdu-seq;
515 /* if we saw a PDU that extended beyond the end of the segment,
516 use this function to remember where the next pdu starts
518 struct tcp_multisegment_pdu *
519 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, emem_tree_t *multisegment_pdus)
521 struct tcp_multisegment_pdu *msp;
523 msp=se_alloc(sizeof(struct tcp_multisegment_pdu));
526 msp->first_frame=pinfo->fd->num;
527 msp->last_frame=pinfo->fd->num;
528 msp->last_frame_time=pinfo->fd->abs_ts;
530 se_tree_insert32(multisegment_pdus, seq, (void *)msp);
534 /* This is called for SYN+ACK packets and the purpose is to verify that we
535 * have seen window scaling in both directions.
536 * If we cant find window scaling being set in both directions
537 * that means it was present in the SYN but not in the SYN+ACK
538 * (or the SYN was missing) and then we disable the window scaling
539 * for this tcp session.
542 verify_tcp_window_scaling(struct tcp_analysis *tcpd)
544 if( tcpd && ((tcpd->flow1.win_scale==-1) || (tcpd->flow2.win_scale==-1)) ){
545 tcpd->flow1.win_scale=-1;
546 tcpd->flow2.win_scale=-1;
550 /* if we saw a window scaling option, store it for future reference
553 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
556 tcpd->fwd->win_scale=ws;
560 tcp_get_relative_seq_ack(guint32 *seq, guint32 *ack, guint32 *win, struct tcp_analysis *tcpd)
562 if (tcpd && tcp_relative_seq) {
563 (*seq) -= tcpd->fwd->base_seq;
564 (*ack) -= tcpd->rev->base_seq;
565 if(tcpd->fwd->win_scale!=-1){
566 (*win)<<=tcpd->fwd->win_scale;
572 /* when this function returns, it will (if createflag) populate the ta pointer.
575 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag, struct tcp_analysis *tcpd)
580 tcpd->ta=se_tree_lookup32(tcpd->acked_table, frame);
581 if((!tcpd->ta) && createflag){
582 tcpd->ta=se_alloc0(sizeof(struct tcp_acked));
583 se_tree_insert32(tcpd->acked_table, frame, (void *)tcpd->ta);
588 /* fwd contains a list of all segments processed but not yet ACKed in the
589 * same direction as the current segment.
590 * rev contains a list of all segments received but not yet ACKed in the
591 * opposite direction to the current segment.
593 * New segments are always added to the head of the fwd/rev lists.
597 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint32 window, struct tcp_analysis *tcpd)
599 tcp_unacked_t *ual=NULL;
603 printf("analyze_sequence numbers frame:%u direction:%s\n",pinfo->fd->num,direction>=0?"FWD":"REW");
604 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);
605 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);
612 /* if this is the first segment for this list we need to store the
615 * Start relative seq and ack numbers at 1 if this
616 * is not a SYN packet. This makes the relative
617 * seq/ack numbers to be displayed correctly in the
618 * event that the SYN or SYN/ACK packet is not seen
619 * (this solves bug 1542)
621 if(tcpd->fwd->base_seq==0){
622 tcpd->fwd->base_seq = (flags & TH_SYN) ? seq : seq-1;
625 /* Only store reverse sequence if this isn't the SYN
626 * There's no guarantee that the ACK field of a SYN
627 * contains zeros; get the ISN from the first segment
628 * with the ACK bit set instead (usually the SYN/ACK).
630 if( (tcpd->rev->base_seq==0) && (flags & TH_ACK) ){
631 tcpd->rev->base_seq = (flags & TH_SYN) ? ack : ack-1;
636 * it is a zero window probe if
637 * the sequnece number is the next expected one
638 * the window in the other direction is 0
639 * the segment is exactly 1 byte
643 && seq==tcpd->fwd->nextseq
644 && tcpd->rev->window==0 ){
646 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
648 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
654 * a zero window packet has window == 0 but none of the SYN/FIN/RST set
658 && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ){
660 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
662 tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
667 * If this segment is beyond the last seen nextseq we must
668 * have missed some previous segment
670 * We only check for this if we have actually seen segments prior to this
672 * RST packets are not checked for this.
674 if( tcpd->fwd->nextseq
675 && GT_SEQ(seq, tcpd->fwd->nextseq)
676 && (flags&(TH_RST))==0 ){
678 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
680 tcpd->ta->flags|=TCP_A_LOST_PACKET;
685 * a keepalive contains 0 or 1 bytes of data and starts one byte prior
686 * to what should be the next sequence number.
687 * SYN/FIN/RST segments are never keepalives
690 if( (seglen==0||seglen==1)
691 && seq==(tcpd->fwd->nextseq-1)
692 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
694 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
696 tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
700 * A window update is a 0 byte segment with the same SEQ/ACK numbers as
701 * the previous seen segment and with a new window value
705 && window!=tcpd->fwd->window
706 && seq==tcpd->fwd->nextseq
707 && ack==tcpd->fwd->lastack
708 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
710 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
712 tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
717 * If we know the window scaling
718 * and if this segment contains data ang goes all the way to the
719 * edge of the advertized window
720 * then we mark it as WINDOW FULL
721 * SYN/RST/FIN packets are never WINDOW FULL
725 && tcpd->fwd->win_scale!=-1
726 && tcpd->rev->win_scale!=-1
727 && (seq+seglen)==(tcpd->rev->lastack+(tcpd->rev->window<<tcpd->rev->win_scale))
728 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
730 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
732 tcpd->ta->flags|=TCP_A_WINDOW_FULL;
737 * It is a keepalive ack if it repeats the previous ACK and if
738 * the last segment in the reverse direction was a keepalive
743 && window==tcpd->fwd->window
744 && seq==tcpd->fwd->nextseq
745 && ack==tcpd->fwd->lastack
746 && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
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_KEEP_ALIVE_ACK;
756 /* ZERO WINDOW PROBE ACK
757 * It is a zerowindowprobe ack if it repeats the previous ACK and if
758 * the last segment in the reverse direction was a zerowindowprobe
759 * It also repeats the previous zero window indication
764 && window==tcpd->fwd->window
765 && seq==tcpd->fwd->nextseq
766 && ack==tcpd->fwd->lastack
767 && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
768 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
770 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
772 tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
778 * It is a duplicate ack if window/seq/ack is the same as the previous
779 * segment and if the segment length is 0
783 && window==tcpd->fwd->window
784 && seq==tcpd->fwd->nextseq
785 && ack==tcpd->fwd->lastack
786 && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ){
787 tcpd->fwd->dupacknum++;
789 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
791 tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
792 tcpd->ta->dupack_num=tcpd->fwd->dupacknum;
793 tcpd->ta->dupack_frame=tcpd->fwd->lastnondupack;
799 /* If this was NOT a dupack we must reset the dupack counters */
800 if( (!tcpd->ta) || !(tcpd->ta->flags&TCP_A_DUPLICATE_ACK) ){
801 tcpd->fwd->lastnondupack=pinfo->fd->num;
802 tcpd->fwd->dupacknum=0;
807 * If this segment acks beyond the nextseqnum in the other direction
808 * then that means we have missed packets going in the
811 * We only check this if we have actually seen some seq numbers
812 * in the other direction.
814 if( tcpd->rev->nextseq
815 && GT_SEQ(ack, tcpd->rev->nextseq )
816 && (flags&(TH_ACK))!=0 ){
819 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
821 tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
822 /* update nextseq in the other direction so we dont get
823 * this indication again.
825 tcpd->rev->nextseq=ack;
829 /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
830 * If the segments contains data and if it does not advance
831 * sequence number it must be either of these three.
832 * Only test for this if we know what the seq number should be
833 * (tcpd->fwd->nextseq)
835 * Note that a simple KeepAlive is not a retransmission
838 && tcpd->fwd->nextseq
839 && (LT_SEQ(seq, tcpd->fwd->nextseq)) ){
842 if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ){
843 goto finished_checking_retransmission_type;
846 /* If there were >=2 duplicate ACKs in the reverse direction
847 * (there might be duplicate acks missing from the trace)
848 * and if this sequence number matches those ACKs
849 * and if the packet occurs within 20ms of the last
851 * then this is a fast retransmission
853 t=(pinfo->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
854 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;
855 if( tcpd->rev->dupacknum>=2
856 && tcpd->rev->lastack==seq
859 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
861 tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
862 goto finished_checking_retransmission_type;
865 /* If the segment came <3ms since the segment with the highest
866 * seen sequence number, then it is an OUT-OF-ORDER segment.
867 * (3ms is an arbitrary number)
869 t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
870 t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
873 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
875 tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
876 goto finished_checking_retransmission_type;
879 /* Then it has to be a generic retransmission */
881 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
883 tcpd->ta->flags|=TCP_A_RETRANSMISSION;
884 nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
885 tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
887 finished_checking_retransmission_type:
890 /* add this new sequence number to the fwd list */
891 TCP_UNACKED_NEW(ual);
892 ual->next=tcpd->fwd->segments;
893 tcpd->fwd->segments=ual;
894 ual->frame=pinfo->fd->num;
896 ual->ts=pinfo->fd->abs_ts;
898 /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
899 ual->nextseq=seq+seglen;
900 if( flags&(TH_SYN|TH_FIN) ){
904 /* Store the highest number seen so far for nextseq so we can detect
905 * when we receive segments that arrive with a "hole"
906 * If we dont have anything since before, just store what we got.
907 * ZeroWindowProbes are special and dont really advance the nextseq
909 if(GT_SEQ(ual->nextseq, tcpd->fwd->nextseq) || !tcpd->fwd->nextseq) {
910 if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ){
911 tcpd->fwd->nextseq=ual->nextseq;
912 tcpd->fwd->nextseqframe=pinfo->fd->num;
913 tcpd->fwd->nextseqtime.secs=pinfo->fd->abs_ts.secs;
914 tcpd->fwd->nextseqtime.nsecs=pinfo->fd->abs_ts.nsecs;
919 /* remember what the ack/window is so we can track window updates and retransmissions */
920 tcpd->fwd->window=window;
921 tcpd->fwd->lastack=ack;
922 tcpd->fwd->lastacktime.secs=pinfo->fd->abs_ts.secs;
923 tcpd->fwd->lastacktime.nsecs=pinfo->fd->abs_ts.nsecs;
926 /* if there were any flags set for this segment we need to remember them
927 * we only remember the flags for the very last segment though.
930 tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
932 tcpd->fwd->lastsegmentflags=0;
936 /* remove all segments this ACKs and we dont need to keep around any more
939 /* first we remove all such segments at the head of the list */
940 while((ual=tcpd->rev->segments)){
941 tcp_unacked_t *tmpual;
942 if(ack==ual->nextseq){
943 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
944 tcpd->ta->frame_acked=ual->frame;
945 nstime_delta(&tcpd->ta->ts, &pinfo->fd->abs_ts, &ual->ts);
947 if(GT_SEQ(ual->nextseq,ack)){
951 /*qqq do the ACKs segment x delta y */
954 tmpual=tcpd->rev->segments->next;
956 if (tcpd->rev->scps_capable) {
957 /* Track largest segment successfully sent for SNACK analysis */
958 if ((ual->nextseq - ual->seq) > tcpd->fwd->maxsizeacked) {
959 tcpd->fwd->maxsizeacked = (ual->nextseq - ual->seq);
963 TCP_UNACKED_FREE(ual);
964 tcpd->rev->segments=tmpual;
966 /* now we remove all such segments that are NOT at the head of the list */
967 ual=tcpd->rev->segments;
968 while(ual && ual->next){
969 tcp_unacked_t *tmpual;
970 if(GT_SEQ(ual->next->nextseq,ack)){
975 /*qqq do the ACKs segment x delta y */
978 tmpual=ual->next->next;
980 if (tcpd->rev->scps_capable) {
981 /* Track largest segment successfully sent for SNACK analysis*/
982 if ((ual->next->nextseq - ual->next->seq) > tcpd->fwd->maxsizeacked){
983 tcpd->fwd->maxsizeacked = (ual->next->nextseq - ual->next->seq);
987 TCP_UNACKED_FREE(ual->next);
992 /* how many bytes of data are there in flight after this frame
995 ual=tcpd->fwd->segments;
996 if (tcp_track_bytes_in_flight && seglen!=0 && ual) {
997 guint32 first_seq, last_seq, in_flight;
999 first_seq = ual->seq - tcpd->fwd->base_seq;
1000 last_seq = ual->nextseq - tcpd->fwd->base_seq;
1002 if ((ual->nextseq-tcpd->fwd->base_seq)>last_seq) {
1003 last_seq = ual->nextseq-tcpd->fwd->base_seq;
1005 if ((ual->seq-tcpd->fwd->base_seq)<first_seq) {
1006 first_seq = ual->seq-tcpd->fwd->base_seq;
1010 in_flight = last_seq-first_seq;
1012 if (in_flight>0 && in_flight<2000000000) {
1014 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
1016 tcpd->ta->bytes_in_flight = in_flight;
1023 * Prints results of the sequence number analysis concerning tcp segments
1024 * retransmitted or out-of-order
1027 tcp_sequence_number_analysis_print_retransmission(packet_info * pinfo,
1029 proto_tree * flags_tree,
1030 struct tcp_acked *ta
1033 proto_item * flags_item;
1035 /* TCP Rentransmission */
1036 if (ta->flags & TCP_A_RETRANSMISSION) {
1037 flags_item=proto_tree_add_none_format(flags_tree,
1038 hf_tcp_analysis_retransmission,
1040 "This frame is a (suspected) "
1043 PROTO_ITEM_SET_GENERATED(flags_item);
1044 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1045 "Retransmission (suspected)");
1047 if (check_col(pinfo->cinfo, COL_INFO)) {
1048 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
1050 if (ta->rto_ts.secs || ta->rto_ts.nsecs) {
1051 flags_item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
1052 tvb, 0, 0, &ta->rto_ts);
1053 PROTO_ITEM_SET_GENERATED(flags_item);
1054 flags_item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame,
1055 tvb, 0, 0, ta->rto_frame);
1056 PROTO_ITEM_SET_GENERATED(flags_item);
1059 /* TCP Fast Rentransmission */
1060 if (ta->flags & TCP_A_FAST_RETRANSMISSION) {
1061 flags_item=proto_tree_add_none_format(flags_tree,
1062 hf_tcp_analysis_fast_retransmission,
1064 "This frame is a (suspected) fast"
1067 PROTO_ITEM_SET_GENERATED(flags_item);
1068 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1069 "Fast retransmission (suspected)");
1070 flags_item=proto_tree_add_none_format(flags_tree,
1071 hf_tcp_analysis_retransmission,
1073 "This frame is a (suspected) "
1076 PROTO_ITEM_SET_GENERATED(flags_item);
1077 if (check_col(pinfo->cinfo, COL_INFO)) {
1078 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1079 "[TCP Fast Retransmission] ");
1082 /* TCP Out-Of-Order */
1083 if (ta->flags & TCP_A_OUT_OF_ORDER) {
1084 flags_item=proto_tree_add_none_format(flags_tree,
1085 hf_tcp_analysis_out_of_order,
1087 "This frame is a (suspected) "
1088 "out-of-order segment"
1090 PROTO_ITEM_SET_GENERATED(flags_item);
1091 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1092 "Out-Of-Order segment");
1093 if (check_col(pinfo->cinfo, COL_INFO)) {
1094 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
1099 /* Prints results of the sequence number analysis concerning reused ports */
1101 tcp_sequence_number_analysis_print_reused(packet_info * pinfo,
1103 proto_tree * flags_tree,
1104 struct tcp_acked *ta
1107 proto_item * flags_item;
1109 /* TCP Ports Reused */
1110 if (ta->flags & TCP_A_REUSED_PORTS) {
1111 flags_item=proto_tree_add_none_format(flags_tree,
1112 hf_tcp_analysis_reused_ports,
1114 "A new tcp session is started with the same "
1115 "ports as an earlier session in this trace"
1117 PROTO_ITEM_SET_GENERATED(flags_item);
1118 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1119 "TCP Port numbers reused for new session");
1120 if(check_col(pinfo->cinfo, COL_INFO)){
1121 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1122 "[TCP Port numbers reused] ");
1127 /* Prints results of the sequence number analysis concerning lost tcp segments */
1129 tcp_sequence_number_analysis_print_lost(packet_info * pinfo,
1131 proto_tree * flags_tree,
1132 struct tcp_acked *ta
1135 proto_item * flags_item;
1137 /* TCP Lost Segment */
1138 if (ta->flags & TCP_A_LOST_PACKET) {
1139 flags_item=proto_tree_add_none_format(flags_tree,
1140 hf_tcp_analysis_lost_packet,
1142 "A segment before this frame was "
1145 PROTO_ITEM_SET_GENERATED(flags_item);
1146 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1147 "Previous segment lost (common at capture start)");
1148 if(check_col(pinfo->cinfo, COL_INFO)){
1149 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1150 "[TCP Previous segment lost] ");
1153 /* TCP Ack lost segment */
1154 if (ta->flags & TCP_A_ACK_LOST_PACKET) {
1155 flags_item=proto_tree_add_none_format(flags_tree,
1156 hf_tcp_analysis_ack_lost_packet,
1158 "This frame ACKs a segment we have "
1161 PROTO_ITEM_SET_GENERATED(flags_item);
1162 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1163 "ACKed lost segment (common at capture start)");
1164 if(check_col(pinfo->cinfo, COL_INFO)){
1165 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1166 "[TCP ACKed lost segment] ");
1171 /* Prints results of the sequence number analysis concerning tcp window */
1173 tcp_sequence_number_analysis_print_window(packet_info * pinfo,
1175 proto_tree * flags_tree,
1176 struct tcp_acked *ta
1179 proto_item * flags_item;
1181 /* TCP Window Update */
1182 if (ta->flags & TCP_A_WINDOW_UPDATE) {
1183 flags_item=proto_tree_add_none_format(flags_tree,
1184 hf_tcp_analysis_window_update,
1186 "This is a tcp window update"
1188 PROTO_ITEM_SET_GENERATED(flags_item);
1189 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_CHAT,
1191 if (check_col(pinfo->cinfo, COL_INFO)) {
1192 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
1195 /* TCP Full Window */
1196 if (ta->flags & TCP_A_WINDOW_FULL) {
1197 flags_item=proto_tree_add_none_format(flags_tree,
1198 hf_tcp_analysis_window_full,
1200 "The transmission window is now "
1203 PROTO_ITEM_SET_GENERATED(flags_item);
1204 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1206 if (check_col(pinfo->cinfo, COL_INFO)) {
1207 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
1212 /* Prints results of the sequence number analysis concerning tcp keepalive */
1214 tcp_sequence_number_analysis_print_keepalive(packet_info * pinfo,
1216 proto_tree * flags_tree,
1217 struct tcp_acked *ta
1220 proto_item * flags_item;
1223 if (ta->flags & TCP_A_KEEP_ALIVE){
1224 flags_item=proto_tree_add_none_format(flags_tree,
1225 hf_tcp_analysis_keep_alive,
1227 "This is a TCP keep-alive segment"
1229 PROTO_ITEM_SET_GENERATED(flags_item);
1230 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1232 if (check_col(pinfo->cinfo, COL_INFO)) {
1233 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
1236 /* TCP Ack Keep Alive */
1237 if (ta->flags & TCP_A_KEEP_ALIVE_ACK) {
1238 flags_item=proto_tree_add_none_format(flags_tree,
1239 hf_tcp_analysis_keep_alive_ack,
1241 "This is an ACK to a TCP keep-alive "
1244 PROTO_ITEM_SET_GENERATED(flags_item);
1245 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1247 if (check_col(pinfo->cinfo, COL_INFO)) {
1248 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
1253 /* Prints results of the sequence number analysis concerning tcp duplicate ack */
1255 tcp_sequence_number_analysis_print_duplicate(packet_info * pinfo,
1257 proto_tree * flags_tree,
1258 struct tcp_acked *ta,
1262 proto_item * flags_item;
1264 /* TCP Duplicate ACK */
1265 if (ta->dupack_num) {
1266 if (ta->flags & TCP_A_DUPLICATE_ACK ) {
1267 flags_item=proto_tree_add_none_format(flags_tree,
1268 hf_tcp_analysis_duplicate_ack,
1270 "This is a TCP duplicate ack"
1272 PROTO_ITEM_SET_GENERATED(flags_item);
1273 if (check_col(pinfo->cinfo, COL_INFO)) {
1274 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1275 "[TCP Dup ACK %u#%u] ",
1281 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
1282 tvb, 0, 0, ta->dupack_num);
1283 PROTO_ITEM_SET_GENERATED(flags_item);
1284 flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
1285 tvb, 0, 0, ta->dupack_frame);
1286 PROTO_ITEM_SET_GENERATED(flags_item);
1287 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1288 "Duplicate ACK (#%u)",
1294 /* Prints results of the sequence number analysis concerning tcp zero window */
1296 tcp_sequence_number_analysis_print_zero_window(packet_info * pinfo,
1298 proto_tree * flags_tree,
1299 struct tcp_acked *ta
1302 proto_item * flags_item;
1304 /* TCP Zero Window Probe */
1305 if (ta->flags & TCP_A_ZERO_WINDOW_PROBE) {
1306 flags_item=proto_tree_add_none_format(flags_tree,
1307 hf_tcp_analysis_zero_window_probe,
1309 "This is a TCP zero-window-probe"
1311 PROTO_ITEM_SET_GENERATED(flags_item);
1312 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1313 "Zero window probe");
1314 if (check_col(pinfo->cinfo, COL_INFO)) {
1315 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
1318 /* TCP Zero Window */
1319 if (ta->flags&TCP_A_ZERO_WINDOW) {
1320 flags_item=proto_tree_add_none_format(flags_tree,
1321 hf_tcp_analysis_zero_window,
1323 "This is a ZeroWindow segment"
1325 PROTO_ITEM_SET_GENERATED(flags_item);
1326 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN,
1328 if (check_col(pinfo->cinfo, COL_INFO)) {
1329 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
1332 /* TCP Zero Window Probe Ack */
1333 if (ta->flags & TCP_A_ZERO_WINDOW_PROBE_ACK) {
1334 flags_item=proto_tree_add_none_format(flags_tree,
1335 hf_tcp_analysis_zero_window_probe_ack,
1337 "This is an ACK to a TCP zero-window-probe"
1339 PROTO_ITEM_SET_GENERATED(flags_item);
1340 expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE,
1341 "Zero window probe ACK");
1342 if (check_col(pinfo->cinfo, COL_INFO)) {
1343 col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1344 "[TCP ZeroWindowProbeAck] ");
1350 /* Prints results of the sequence number analysis concerning how many bytes of data are in flight */
1352 tcp_sequence_number_analysis_print_bytes_in_flight(packet_info * pinfo _U_,
1354 proto_tree * flags_tree _U_,
1355 struct tcp_acked *ta
1358 proto_item * flags_item;
1360 if (tcp_track_bytes_in_flight) {
1361 flags_item=proto_tree_add_uint(flags_tree,
1362 hf_tcp_analysis_bytes_in_flight,
1363 tvb, 0, 0, ta->bytes_in_flight);
1365 PROTO_ITEM_SET_GENERATED(flags_item);
1370 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd)
1372 struct tcp_acked *ta = NULL;
1375 proto_tree *flags_tree=NULL;
1381 tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE, tcpd);
1388 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
1389 PROTO_ITEM_SET_GENERATED(item);
1390 tree=proto_item_add_subtree(item, ett_tcp_analysis);
1392 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
1393 data we actually have */
1394 if(ta->frame_acked){
1395 item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
1396 tvb, 0, 0, ta->frame_acked);
1397 PROTO_ITEM_SET_GENERATED(item);
1399 /* only display RTT if we actually have something we are acking */
1400 if( ta->ts.secs || ta->ts.nsecs ){
1401 item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
1402 tvb, 0, 0, &ta->ts);
1403 PROTO_ITEM_SET_GENERATED(item);
1407 if(ta->bytes_in_flight) {
1408 /* print results for amount of data in flight */
1409 tcp_sequence_number_analysis_print_bytes_in_flight(pinfo, tvb, tree, ta);
1413 item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, 0, FALSE);
1414 PROTO_ITEM_SET_GENERATED(item);
1415 flags_tree=proto_item_add_subtree(item, ett_tcp_analysis);
1417 /* print results for reused tcp ports */
1418 tcp_sequence_number_analysis_print_reused(pinfo, tvb, flags_tree, ta);
1420 /* print results for retransmission and out-of-order segments */
1421 tcp_sequence_number_analysis_print_retransmission(pinfo, tvb, flags_tree, ta);
1423 /* print results for lost tcp segments */
1424 tcp_sequence_number_analysis_print_lost(pinfo, tvb, flags_tree, ta);
1426 /* print results for tcp window information */
1427 tcp_sequence_number_analysis_print_window(pinfo, tvb, flags_tree, ta);
1429 /* print results for tcp keep alive information */
1430 tcp_sequence_number_analysis_print_keepalive(pinfo, tvb, flags_tree, ta);
1432 /* print results for tcp duplicate acks */
1433 tcp_sequence_number_analysis_print_duplicate(pinfo, tvb, flags_tree, ta, tree);
1435 /* print results for tcp zero window */
1436 tcp_sequence_number_analysis_print_zero_window(pinfo, tvb, flags_tree, ta);
1443 print_tcp_fragment_tree(fragment_data *ipfd_head, proto_tree *tree, proto_tree *tcp_tree, packet_info *pinfo, tvbuff_t *next_tvb)
1445 proto_item *tcp_tree_item, *frag_tree_item;
1448 * The subdissector thought it was completely
1449 * desegmented (although the stuff at the
1450 * end may, in turn, require desegmentation),
1451 * so we show a tree with all segments.
1453 show_fragment_tree(ipfd_head, &tcp_segment_items,
1454 tree, pinfo, next_tvb, &frag_tree_item);
1456 * The toplevel fragment subtree is now
1457 * behind all desegmented data; move it
1458 * right behind the TCP tree.
1460 tcp_tree_item = proto_tree_get_parent(tcp_tree);
1461 if(frag_tree_item && tcp_tree_item) {
1462 proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1466 /* **************************************************************************
1467 * End of tcp sequence number analysis
1468 * **************************************************************************/
1471 /* Minimum TCP header length. */
1472 #define TCPH_MIN_LEN 20
1478 #define TCPOPT_NOP 1 /* Padding */
1479 #define TCPOPT_EOL 0 /* End of options */
1480 #define TCPOPT_MSS 2 /* Segment size negotiating */
1481 #define TCPOPT_WINDOW 3 /* Window scaling */
1482 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
1483 #define TCPOPT_SACK 5 /* SACK Block */
1484 #define TCPOPT_ECHO 6
1485 #define TCPOPT_ECHOREPLY 7
1486 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
1487 #define TCPOPT_CC 11
1488 #define TCPOPT_CCNEW 12
1489 #define TCPOPT_CCECHO 13
1490 #define TCPOPT_MD5 19 /* RFC2385 */
1491 #define TCPOPT_SCPS 20 /* SCPS Capabilities */
1492 #define TCPOPT_SNACK 21 /* SCPS SNACK */
1493 #define TCPOPT_RECBOUND 22 /* SCPS Record Boundary */
1494 #define TCPOPT_CORREXP 23 /* SCPS Corruption Experienced */
1495 #define TCPOPT_QS 27 /* RFC4782 */
1498 * TCP option lengths
1501 #define TCPOLEN_MSS 4
1502 #define TCPOLEN_WINDOW 3
1503 #define TCPOLEN_SACK_PERM 2
1504 #define TCPOLEN_SACK_MIN 2
1505 #define TCPOLEN_ECHO 6
1506 #define TCPOLEN_ECHOREPLY 6
1507 #define TCPOLEN_TIMESTAMP 10
1508 #define TCPOLEN_CC 6
1509 #define TCPOLEN_CCNEW 6
1510 #define TCPOLEN_CCECHO 6
1511 #define TCPOLEN_MD5 18
1512 #define TCPOLEN_SCPS 4
1513 #define TCPOLEN_SNACK 6
1514 #define TCPOLEN_RECBOUND 2
1515 #define TCPOLEN_CORREXP 2
1516 #define TCPOLEN_QS 8
1520 /* Desegmentation of TCP streams */
1521 /* table to hold defragmented TCP streams */
1522 static GHashTable *tcp_fragment_table = NULL;
1524 tcp_fragment_init(void)
1526 fragment_table_init(&tcp_fragment_table);
1529 /* functions to trace tcp segments */
1530 /* Enable desegmenting of TCP streams */
1531 static gboolean tcp_desegment = TRUE;
1534 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1535 guint32 seq, guint32 nxtseq,
1536 guint32 sport, guint32 dport,
1537 proto_tree *tree, proto_tree *tcp_tree,
1538 struct tcp_analysis *tcpd)
1540 struct tcpinfo *tcpinfo = pinfo->private_data;
1541 fragment_data *ipfd_head;
1542 int last_fragment_len;
1543 gboolean must_desegment;
1544 gboolean called_dissector;
1545 int another_pdu_follows;
1550 struct tcp_multisegment_pdu *msp;
1554 last_fragment_len=0;
1555 must_desegment = FALSE;
1556 called_dissector = FALSE;
1557 another_pdu_follows = 0;
1561 * Initialize these to assume no desegmentation.
1562 * If that's not the case, these will be set appropriately
1563 * by the subdissector.
1565 pinfo->desegment_offset = 0;
1566 pinfo->desegment_len = 0;
1569 * Initialize this to assume that this segment will just be
1570 * added to the middle of a desegmented chunk of data, so
1571 * that we should show it all as data.
1572 * If that's not the case, it will be set appropriately.
1574 deseg_offset = offset;
1576 /* find the most previous PDU starting before this sequence number */
1578 msp = se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
1580 if(msp && msp->seq<=seq && msp->nxtpdu>seq){
1583 if(!pinfo->fd->flags.visited){
1584 msp->last_frame=pinfo->fd->num;
1585 msp->last_frame_time=pinfo->fd->abs_ts;
1588 /* OK, this PDU was found, which means the segment continues
1589 a higher-level PDU and that we must desegment it.
1591 if(msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT){
1592 /* The dissector asked for the entire segment */
1593 len=tvb_length_remaining(tvb, offset);
1595 len=MIN(nxtseq, msp->nxtpdu) - seq;
1597 last_fragment_len = len;
1599 ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
1603 (LT_SEQ (nxtseq,msp->nxtpdu)) );
1605 if(msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT){
1606 msp->flags&=(~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT);
1608 /* If we consumed the entire segment there is no
1609 * other pdu starting anywhere inside this segment.
1610 * So update nxtpdu to point at least to the start
1611 * of the next segment.
1612 * (If the subdissector asks for even more data we
1613 * will advance nxtpdu even furhter later down in
1619 if( (msp->nxtpdu<nxtseq)
1620 && (msp->nxtpdu>=seq)
1622 another_pdu_follows=msp->nxtpdu-seq;
1625 /* This segment was not found in our table, so it doesn't
1626 contain a continuation of a higher-level PDU.
1627 Call the normal subdissector.
1629 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1630 sport, dport, 0, 0, FALSE, tcpd);
1631 called_dissector = TRUE;
1633 /* Did the subdissector ask us to desegment some more data
1634 before it could handle the packet?
1635 If so we have to create some structures in our table but
1636 this is something we only do the first time we see this
1639 if(pinfo->desegment_len) {
1640 if (!pinfo->fd->flags.visited)
1641 must_desegment = TRUE;
1644 * Set "deseg_offset" to the offset in "tvb"
1645 * of the first byte of data that the
1646 * subdissector didn't process.
1648 deseg_offset = offset + pinfo->desegment_offset;
1651 /* Either no desegmentation is necessary, or this is
1652 segment contains the beginning but not the end of
1653 a higher-level PDU and thus isn't completely
1660 /* is it completely desegmented? */
1663 * Yes, we think it is.
1664 * We only call subdissector for the last segment.
1665 * Note that the last segment may include more than what
1668 if(ipfd_head->reassembled_in==pinfo->fd->num){
1670 * OK, this is the last segment.
1671 * Let's call the subdissector with the desegmented
1677 /* create a new TVB structure for desegmented data */
1678 next_tvb = tvb_new_child_real_data(tvb, ipfd_head->data,
1679 ipfd_head->datalen, ipfd_head->datalen);
1682 /* add desegmented data to the data source list */
1683 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1686 * Supply the sequence number of the first of the
1687 * reassembled bytes.
1689 tcpinfo->seq = msp->seq;
1691 /* indicate that this is reassembled data */
1692 tcpinfo->is_reassembled = TRUE;
1694 /* call subdissector */
1695 process_tcp_payload(next_tvb, 0, pinfo, tree,
1696 tcp_tree, sport, dport, 0, 0, FALSE, tcpd);
1697 called_dissector = TRUE;
1700 * OK, did the subdissector think it was completely
1701 * desegmented, or does it think we need even more
1704 old_len=(int)(tvb_reported_length(next_tvb)-last_fragment_len);
1705 if(pinfo->desegment_len &&
1706 pinfo->desegment_offset<=old_len){
1708 * "desegment_len" isn't 0, so it needs more
1709 * data for something - and "desegment_offset"
1710 * is before "old_len", so it needs more data
1711 * to dissect the stuff we thought was
1712 * completely desegmented (as opposed to the
1713 * stuff at the beginning being completely
1714 * desegmented, but the stuff at the end
1715 * being a new higher-level PDU that also
1716 * needs desegmentation).
1718 fragment_set_partial_reassembly(pinfo,msp->first_frame,tcp_fragment_table);
1719 /* Update msp->nxtpdu to point to the new next
1722 if(pinfo->desegment_len==DESEGMENT_ONE_MORE_SEGMENT){
1723 /* We want reassembly of at least one
1724 * more segment so set the nxtpdu
1725 * boundary to one byte into the next
1727 * This means that the next segment
1728 * will complete reassembly even if it
1729 * is only one single byte in length.
1731 msp->nxtpdu=seq+tvb_reported_length_remaining(tvb, offset) + 1;
1732 msp->flags|=MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1734 msp->nxtpdu=seq + last_fragment_len + pinfo->desegment_len;
1736 /* Since we need at least some more data
1737 * there can be no pdu following in the
1738 * tail of this segment.
1740 another_pdu_follows=0;
1741 offset += last_fragment_len;
1742 seq += last_fragment_len;
1743 if (tvb_length_remaining(tvb, offset) > 0)
1747 * Show the stuff in this TCP segment as
1748 * just raw TCP segment data.
1750 nbytes = another_pdu_follows > 0
1751 ? another_pdu_follows
1752 : tvb_reported_length_remaining(tvb, offset);
1753 proto_tree_add_text(tcp_tree, tvb, offset, nbytes,
1754 "TCP segment data (%u byte%s)", nbytes,
1755 plurality(nbytes, "", "s"));
1757 print_tcp_fragment_tree(ipfd_head, tree, tcp_tree, pinfo, next_tvb);
1759 /* Did the subdissector ask us to desegment
1760 some more data? This means that the data
1761 at the beginning of this segment completed
1762 a higher-level PDU, but the data at the
1763 end of this segment started a higher-level
1764 PDU but didn't complete it.
1766 If so, we have to create some structures
1767 in our table, but this is something we
1768 only do the first time we see this packet.
1770 if(pinfo->desegment_len) {
1771 if (!pinfo->fd->flags.visited)
1772 must_desegment = TRUE;
1774 /* The stuff we couldn't dissect
1775 must have come from this segment,
1776 so it's all in "tvb".
1778 "pinfo->desegment_offset" is
1779 relative to the beginning of
1780 "next_tvb"; we want an offset
1781 relative to the beginning of "tvb".
1783 First, compute the offset relative
1784 to the *end* of "next_tvb" - i.e.,
1785 the number of bytes before the end
1786 of "next_tvb" at which the
1787 subdissector stopped. That's the
1788 length of "next_tvb" minus the
1789 offset, relative to the beginning
1790 of "next_tvb, at which the
1791 subdissector stopped.
1794 ipfd_head->datalen - pinfo->desegment_offset;
1796 /* "tvb" and "next_tvb" end at the
1797 same byte of data, so the offset
1798 relative to the end of "next_tvb"
1799 of the byte at which we stopped
1800 is also the offset relative to
1801 the end of "tvb" of the byte at
1804 Convert that back into an offset
1805 relative to the beginninng of
1806 "tvb", by taking the length of
1807 "tvb" and subtracting the offset
1808 relative to the end.
1810 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1816 if (must_desegment) {
1817 /* If the dissector requested "reassemble until FIN"
1818 * just set this flag for the flow and let reassembly
1819 * proceed at normal. We will check/pick up these
1820 * reassembled PDUs later down in dissect_tcp() when checking
1823 if(tcpd && pinfo->desegment_len==DESEGMENT_UNTIL_FIN) {
1824 tcpd->fwd->flags|=TCP_FLOW_REASSEMBLE_UNTIL_FIN;
1827 * The sequence number at which the stuff to be desegmented
1828 * starts is the sequence number of the byte at an offset
1829 * of "deseg_offset" into "tvb".
1831 * The sequence number of the byte at an offset of "offset"
1832 * is "seq", i.e. the starting sequence number of this
1833 * segment, so the sequence number of the byte at
1834 * "deseg_offset" is "seq + (deseg_offset - offset)".
1836 deseg_seq = seq + (deseg_offset - offset);
1838 if(tcpd && ((nxtseq - deseg_seq) <= 1024*1024)
1839 && (!pinfo->fd->flags.visited) ){
1840 if(pinfo->desegment_len==DESEGMENT_ONE_MORE_SEGMENT){
1841 /* The subdissector asked to reassemble using the
1842 * entire next segment.
1843 * Just ask reassembly for one more byte
1844 * but set this msp flag so we can pick it up
1847 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
1848 deseg_seq, nxtseq+1, tcpd->fwd->multisegment_pdus);
1849 msp->flags|=MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1851 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
1852 deseg_seq, nxtseq+pinfo->desegment_len, tcpd->fwd->multisegment_pdus);
1855 /* add this segment as the first one for this new pdu */
1856 fragment_add(tvb, deseg_offset, pinfo, msp->first_frame,
1860 LT_SEQ(nxtseq, msp->nxtpdu));
1864 if (!called_dissector || pinfo->desegment_len != 0) {
1865 if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
1866 !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
1868 * We know what frame this PDU is reassembled in;
1869 * let the user know.
1871 item=proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in,
1872 tvb, 0, 0, ipfd_head->reassembled_in);
1873 PROTO_ITEM_SET_GENERATED(item);
1877 * Either we didn't call the subdissector at all (i.e.,
1878 * this is a segment that contains the middle of a
1879 * higher-level PDU, but contains neither the beginning
1880 * nor the end), or the subdissector couldn't dissect it
1881 * all, as some data was missing (i.e., it set
1882 * "pinfo->desegment_len" to the amount of additional
1885 if (pinfo->desegment_offset == 0) {
1887 * It couldn't, in fact, dissect any of it (the
1888 * first byte it couldn't dissect is at an offset
1889 * of "pinfo->desegment_offset" from the beginning
1890 * of the payload, and that's 0).
1891 * Just mark this as TCP.
1893 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1894 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1896 if (check_col(pinfo->cinfo, COL_INFO)){
1897 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
1902 * Show what's left in the packet as just raw TCP segment
1904 * XXX - remember what protocol the last subdissector
1905 * was, and report it as a continuation of that, instead?
1907 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
1908 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
1909 "TCP segment data (%u byte%s)", nbytes,
1910 plurality(nbytes, "", "s"));
1912 pinfo->can_desegment=0;
1913 pinfo->desegment_offset = 0;
1914 pinfo->desegment_len = 0;
1916 if(another_pdu_follows){
1917 /* there was another pdu following this one. */
1918 pinfo->can_desegment=2;
1919 /* we also have to prevent the dissector from changing the
1920 * PROTOCOL and INFO colums since what follows may be an
1921 * incomplete PDU and we dont want it be changed back from
1922 * <Protocol> to <TCP>
1923 * XXX There is no good way to block the PROTOCOL column
1924 * from being changed yet so we set the entire row unwritable.
1926 col_set_fence(pinfo->cinfo, COL_INFO);
1927 col_set_writable(pinfo->cinfo, FALSE);
1928 offset += another_pdu_follows;
1929 seq += another_pdu_follows;
1935 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
1936 * consists of a fixed-length chunk of data that contains enough information
1937 * to determine the length of the PDU, followed by rest of the PDU.
1939 * The first three arguments are the arguments passed to the dissector
1940 * that calls this routine.
1942 * "proto_desegment" is the dissector's flag controlling whether it should
1943 * desegment PDUs that cross TCP segment boundaries.
1945 * "fixed_len" is the length of the fixed-length part of the PDU.
1947 * "get_pdu_len()" is a routine called to get the length of the PDU from
1948 * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset".
1950 * "dissect_pdu()" is the routine to dissect a PDU.
1953 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1954 gboolean proto_desegment, guint fixed_len,
1955 guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
1956 dissector_t dissect_pdu)
1958 volatile int offset = 0;
1960 guint length_remaining;
1964 proto_item *item=NULL;
1966 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1968 * We use "tvb_ensure_length_remaining()" to make sure there actually
1969 * *is* data remaining. The protocol we're handling could conceivably
1970 * consists of a sequence of fixed-length PDUs, and therefore the
1971 * "get_pdu_len" routine might not actually fetch anything from
1972 * the tvbuff, and thus might not cause an exception to be thrown if
1973 * we've run past the end of the tvbuff.
1975 * This means we're guaranteed that "length_remaining" is positive.
1977 length_remaining = tvb_ensure_length_remaining(tvb, offset);
1980 * Can we do reassembly?
1982 if (proto_desegment && pinfo->can_desegment) {
1984 * Yes - is the fixed-length part of the PDU split across segment
1987 if (length_remaining < fixed_len) {
1989 * Yes. Tell the TCP dissector where the data for this message
1990 * starts in the data it handed us, and how many more bytes we
1993 pinfo->desegment_offset = offset;
1994 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2000 * Get the length of the PDU.
2002 plen = (*get_pdu_len)(pinfo, tvb, offset);
2003 if (plen < fixed_len) {
2007 * 1) the length value extracted from the fixed-length portion
2008 * doesn't include the fixed-length portion's length, and
2009 * was so large that, when the fixed-length portion's
2010 * length was added to it, the total length overflowed;
2012 * 2) the length value extracted from the fixed-length portion
2013 * includes the fixed-length portion's length, and the value
2014 * was less than the fixed-length portion's length, i.e. it
2017 * Report this as a bounds error.
2019 show_reported_bounds_error(tvb, pinfo, tree);
2023 * Display the PDU length as a field
2025 item=proto_tree_add_uint(pinfo->tcp_tree, hf_tcp_pdu_size, tvb, offset, plen, plen);
2026 PROTO_ITEM_SET_GENERATED(item);
2030 /* give a hint to TCP where the next PDU starts
2031 * so that it can attempt to find it in case it starts
2032 * somewhere in the middle of a segment.
2034 if(!pinfo->fd->flags.visited && tcp_analyze_seq){
2035 guint remaining_bytes;
2036 remaining_bytes=tvb_reported_length_remaining(tvb, offset);
2037 if(plen>remaining_bytes){
2038 pinfo->want_pdu_tracking=2;
2039 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
2044 * Can we do reassembly?
2046 if (proto_desegment && pinfo->can_desegment) {
2048 * Yes - is the PDU split across segment boundaries?
2050 if (length_remaining < plen) {
2052 * Yes. Tell the TCP dissector where the data for this message
2053 * starts in the data it handed us, and how many more bytes we
2056 pinfo->desegment_offset = offset;
2057 pinfo->desegment_len = plen - length_remaining;
2063 * Construct a tvbuff containing the amount of the payload we have
2064 * available. Make its reported length the amount of data in the PDU.
2066 * XXX - if reassembly isn't enabled. the subdissector will throw a
2067 * BoundsError exception, rather than a ReportedBoundsError exception.
2068 * We really want a tvbuff where the length is "length", the reported
2069 * length is "plen", and the "if the snapshot length were infinite"
2070 * length is the minimum of the reported length of the tvbuff handed
2071 * to us and "plen", with a new type of exception thrown if the offset
2072 * is within the reported length but beyond that third length, with
2073 * that exception getting the "Unreassembled Packet" error.
2075 length = length_remaining;
2078 next_tvb = tvb_new_subset(tvb, offset, length, plen);
2083 * Catch the ReportedBoundsError exception; if this particular message
2084 * happens to get a ReportedBoundsError exception, that doesn't mean
2085 * that we should stop dissecting PDUs within this frame or chunk of
2088 * If it gets a BoundsError, we can stop, as there's nothing more to
2089 * see, so we just re-throw it.
2092 (*dissect_pdu)(next_tvb, pinfo, tree);
2094 CATCH(BoundsError) {
2097 CATCH(ReportedBoundsError) {
2098 show_reported_bounds_error(tvb, pinfo, tree);
2103 * Step to the next PDU.
2104 * Make sure we don't overflow.
2106 offset_before = offset;
2108 if (offset <= offset_before)
2114 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
2116 if (check_col(pinfo->cinfo, COL_INFO))
2117 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
2120 /* Supports the reporting the contents of a parsed SCPS capabilities vector */
2122 tcp_info_append_str(packet_info *pinfo, const char *abbrev, const char *val)
2124 if (check_col(pinfo->cinfo, COL_INFO))
2125 col_append_fstr(pinfo->cinfo, COL_INFO, " %s[%s]", abbrev, val);
2129 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
2130 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2132 proto_item *hidden_item;
2135 mss = tvb_get_ntohs(tvb, offset + 2);
2136 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_mss, tvb, offset,
2138 PROTO_ITEM_SET_HIDDEN(hidden_item);
2139 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
2140 optlen, mss, "%s: %u bytes", optp->name, mss);
2141 tcp_info_append_uint(pinfo, "MSS", mss);
2145 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
2146 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2148 proto_item *hidden_item;
2150 struct tcp_analysis *tcpd=NULL;
2152 tcpd=get_tcp_conversation_data(NULL,pinfo);
2154 ws = tvb_get_guint8(tvb, offset + 2);
2155 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_wscale, tvb,
2156 offset, optlen, TRUE);
2157 PROTO_ITEM_SET_HIDDEN(hidden_item);
2158 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
2159 offset, optlen, ws, "%s: %u (multiply by %u)",
2160 optp->name, ws, 1 << ws);
2161 tcp_info_append_uint(pinfo, "WS", ws);
2162 if(!pinfo->fd->flags.visited && tcp_analyze_seq && tcp_relative_seq){
2163 pdu_store_window_scale_option(ws, tcpd);
2168 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
2169 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2171 proto_tree *field_tree = NULL;
2172 proto_item *tf=NULL;
2173 proto_item *hidden_item;
2174 guint32 leftedge, rightedge;
2175 struct tcp_analysis *tcpd=NULL;
2178 if(tcp_analyze_seq && tcp_relative_seq){
2179 /* find(or create if needed) the conversation for this tcp session */
2180 tcpd=get_tcp_conversation_data(NULL,pinfo);
2183 base_ack=tcpd->rev->base_seq;
2187 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
2188 offset += 2; /* skip past type and length */
2189 optlen -= 2; /* subtract size of type and length */
2190 while (optlen > 0) {
2191 if (field_tree == NULL) {
2192 /* Haven't yet made a subtree out of this option. Do so. */
2193 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2194 hidden_item = proto_tree_add_boolean(field_tree, hf_tcp_option_sack, tvb,
2195 offset, optlen, TRUE);
2196 PROTO_ITEM_SET_HIDDEN(hidden_item);
2199 proto_tree_add_text(field_tree, tvb, offset, optlen,
2200 "(suboption would go past end of option)");
2203 leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
2204 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
2205 offset, 4, leftedge,
2206 "left edge = %u%s", leftedge,
2207 tcp_relative_seq ? " (relative)" : "");
2211 proto_tree_add_text(field_tree, tvb, offset, optlen,
2212 "(suboption would go past end of option)");
2215 /* XXX - check whether it goes past end of packet */
2216 rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
2218 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
2219 offset+4, 4, rightedge,
2220 "right edge = %u%s", rightedge,
2221 tcp_relative_seq ? " (relative)" : "");
2222 tcp_info_append_uint(pinfo, "SLE", leftedge);
2223 tcp_info_append_uint(pinfo, "SRE", rightedge);
2224 proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
2230 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
2231 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2233 proto_item *hidden_item;
2236 echo = tvb_get_ntohl(tvb, offset + 2);
2237 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_echo, tvb, offset,
2239 PROTO_ITEM_SET_HIDDEN(hidden_item);
2240 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2241 "%s: %u", optp->name, echo);
2242 tcp_info_append_uint(pinfo, "ECHO", echo);
2246 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
2247 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2249 proto_item *hidden_item;
2252 tsv = tvb_get_ntohl(tvb, offset + 2);
2253 tser = tvb_get_ntohl(tvb, offset + 6);
2254 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_time_stamp, tvb,
2255 offset, optlen, TRUE);
2256 PROTO_ITEM_SET_HIDDEN(hidden_item);
2257 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2258 "%s: TSval %u, TSecr %u", optp->name, tsv, tser);
2259 tcp_info_append_uint(pinfo, "TSV", tsv);
2260 tcp_info_append_uint(pinfo, "TSER", tser);
2264 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
2265 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2267 proto_item *hidden_item;
2270 cc = tvb_get_ntohl(tvb, offset + 2);
2271 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_cc, tvb, offset,
2273 PROTO_ITEM_SET_HIDDEN(hidden_item);
2274 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2275 "%s: %u", optp->name, cc);
2276 tcp_info_append_uint(pinfo, "CC", cc);
2280 dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
2281 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
2283 /* Quick-Start TCP option, as defined by RFC4782 */
2284 static const value_string qs_rates[] = {
2290 { 5, "1.28 Mbit/s"},
2291 { 6, "2.56 Mbit/s"},
2292 { 7, "5.12 Mbit/s"},
2293 { 8, "10.24 Mbit/s"},
2294 { 9, "20.48 Mbit/s"},
2295 {10, "40.96 Mbit/s"},
2296 {11, "81.92 Mbit/s"},
2297 {12, "163.84 Mbit/s"},
2298 {13, "327.68 Mbit/s"},
2299 {14, "655.36 Mbit/s"},
2300 {15, "1.31072 Gbit/s"},
2303 proto_item *hidden_item;
2305 guint8 rate = tvb_get_guint8(tvb, offset + 2) & 0x0f;
2307 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_qs, tvb, offset,
2309 PROTO_ITEM_SET_HIDDEN(hidden_item);
2310 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2311 "%s: Rate response, %s, TTL diff %u ", optp->name,
2312 val_to_str(rate, qs_rates, "Unknown"),
2313 tvb_get_guint8(tvb, offset + 3));
2314 if (check_col(pinfo->cinfo, COL_INFO))
2315 col_append_fstr(pinfo->cinfo, COL_INFO, " QSresp=%s", val_to_str(rate, qs_rates, "Unknown"));
2320 dissect_tcpopt_scps(const ip_tcp_opt *optp, tvbuff_t *tvb,
2321 int offset, guint optlen, packet_info *pinfo,
2322 proto_tree *opt_tree)
2324 struct tcp_analysis *tcpd=NULL;
2325 proto_tree *field_tree = NULL;
2328 proto_item *tf = NULL, *hidden_item;
2329 gchar flags[64] = "<None>";
2330 gchar *fstr[] = {"BETS", "SNACK1", "SNACK2", "COMP", "NLTS", "RESV1", "RESV2", "RESV3"};
2335 tcpd = get_tcp_conversation_data(NULL,pinfo);
2337 /* check direction and get ua lists */
2338 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2340 /* if the addresses are equal, match the ports instead */
2342 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
2346 flow =&(tcpd->flow1);
2348 flow =&(tcpd->flow2);
2350 /* If the option length == 4, this is a real SCPS capability option
2351 * See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS Transport Protocol
2352 * (SCPS-TP)" Section 3.2.3 for definition.
2355 capvector = tvb_get_guint8(tvb, offset + 2);
2358 /* Decode the capabilities vector for display */
2359 for (i = 0; i < 5; i++) {
2361 if (capvector & bpos) {
2363 g_strlcat(flags, ", ", 64);
2365 g_strlcat(flags, fstr[i], 64);
2369 /* If lossless header compression is offered, there will be a
2370 * single octet connectionId following the capabilities vector
2372 if (capvector & 0x10)
2373 connid = tvb_get_guint8(tvb, offset + 3);
2377 tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector, tvb,
2378 offset, optlen, capvector,
2380 optp->name, capvector, flags);
2381 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_scps,
2382 tvb, offset, optlen, TRUE);
2383 PROTO_ITEM_SET_HIDDEN(hidden_item);
2385 field_tree = proto_item_add_subtree(tf, ett_tcp_option_scps);
2387 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_bets, tvb,
2388 offset + 13, 1, capvector);
2389 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_snack1, tvb,
2390 offset + 13, 1, capvector);
2391 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_snack2, tvb,
2392 offset + 13, 1, capvector);
2393 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_compress, tvb,
2394 offset + 13, 1, capvector);
2395 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_nlts, tvb,
2396 offset + 13, 1, capvector);
2397 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_resv1, tvb,
2398 offset + 13, 1, capvector);
2399 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_resv2, tvb,
2400 offset + 13, 1, capvector);
2401 proto_tree_add_boolean(field_tree, hf_tcp_scpsoption_flags_resv3, tvb,
2402 offset + 13, 1, capvector);
2404 tcp_info_append_str(pinfo, "SCPS", flags);
2406 flow->scps_capable = 1;
2409 tcp_info_append_uint(pinfo, "Connection ID", connid);
2412 /* The option length != 4, so this is an infamous "extended capabilities
2413 * option. See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
2414 * Transport Protocol (SCPS-TP)" Section 3.2.5 for definition.
2416 * As the format of this option is only partially defined (it is
2417 * a community (or more likely vendor) defined format beyond that, so
2418 * at least for now, we only parse the standardized portion of the option.
2420 guint8 local_offset = 2;
2421 guint8 binding_space;
2422 guint8 extended_cap_length;
2424 if (flow->scps_capable != 1) {
2425 /* There was no SCPS capabilities option preceeding this */
2426 tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector,
2427 tvb, offset, optlen, 0, "%s: (%d %s)",
2428 "Illegal SCPS Extended Capabilities",
2433 tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector,
2434 tvb, offset, optlen, 0, "%s: (%d %s)",
2435 "SCPS Extended Capabilities",
2438 field_tree=proto_item_add_subtree(tf, ett_tcp_option_scps_extended);
2439 /* There may be multiple binding spaces included in a single option,
2440 * so we will semi-parse each of the stacked binding spaces - skipping
2441 * over the octets following the binding space identifier and length.
2444 while (optlen > local_offset) {
2445 proto_item *hidden_item;
2447 /* 1st octet is Extended Capability Binding Space */
2448 binding_space = tvb_get_guint8(tvb, (offset + local_offset));
2450 /* 2nd octet (upper 4-bits) has binding space length in 16-bit words.
2451 * As defined by the specification, this length is exclusive of the
2452 * octets containing the extended capability type and length
2455 extended_cap_length =
2456 (tvb_get_guint8(tvb, (offset + local_offset + 1)) >> 4);
2458 /* Convert the extended capabilities length into bytes for display */
2459 extended_cap_length = (extended_cap_length << 1);
2461 proto_tree_add_text(field_tree, tvb, offset + local_offset, 2,
2462 "\tBinding Space %u",
2464 hidden_item = proto_tree_add_uint(field_tree, hf_tcp_option_scps_binding,
2465 tvb, (offset + local_offset), 1,
2468 PROTO_ITEM_SET_HIDDEN(hidden_item);
2470 /* Step past the binding space and length octets */
2473 proto_tree_add_text(field_tree, tvb, offset + local_offset,
2474 extended_cap_length,
2475 "\tBinding Space Data (%u bytes)",
2476 extended_cap_length);
2478 tcp_info_append_uint(pinfo, "EXCAP", binding_space);
2480 /* Step past the Extended capability data
2481 * Treat the extended capability data area as opaque;
2482 * If one desires to parse the extended capability data
2483 * (say, in a vendor aware build of wireshark), it would
2486 local_offset += extended_cap_length;
2492 /* This is called for SYN+ACK packets and the purpose is to verify that
2493 * the SCPS capabilities option has been successfully negotiated for the flow.
2494 * If the SCPS capabilities option was offered by only one party, the
2495 * proactively set scps_capable attribute of the flow (set upon seeing
2496 * the first instance of the SCPS option) is revoked.
2499 verify_scps(packet_info *pinfo, proto_item *tf_syn, struct tcp_analysis *tcpd)
2504 if ((!(tcpd->flow1.scps_capable)) || (!(tcpd->flow2.scps_capable))) {
2505 tcpd->flow1.scps_capable = 0;
2506 tcpd->flow2.scps_capable = 0;
2509 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_NOTE,
2510 "Connection establish request (SYN-ACK): SCPS Capabilities Negotiated");
2515 /* See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
2516 * Transport Protocol (SCPS-TP)" Section 3.5 for definition of the SNACK option
2519 dissect_tcpopt_snack(const ip_tcp_opt *optp, tvbuff_t *tvb,
2520 int offset, guint optlen, packet_info *pinfo,
2521 proto_tree *opt_tree)
2523 struct tcp_analysis *tcpd=NULL;
2524 guint16 relative_hole_offset;
2525 guint16 relative_hole_size;
2526 guint16 base_mss = 0;
2530 char null_modifier[] = "\0";
2531 char relative_modifier[] = "(relative)";
2532 char *modifier = null_modifier;
2533 proto_item *hidden_item;
2535 tcpd = get_tcp_conversation_data(NULL,pinfo);
2537 /* The SNACK option reports missing data with a granualarity of segments. */
2538 relative_hole_offset = tvb_get_ntohs(tvb, offset + 2);
2539 relative_hole_size = tvb_get_ntohs(tvb, offset + 4);
2541 hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_snack, tvb,
2542 offset, optlen, TRUE);
2543 PROTO_ITEM_SET_HIDDEN(hidden_item);
2545 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_offset,
2546 tvb, offset, optlen, relative_hole_offset);
2547 PROTO_ITEM_SET_HIDDEN(hidden_item);
2549 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_size,
2550 tvb, offset, optlen, relative_hole_size);
2551 PROTO_ITEM_SET_HIDDEN(hidden_item);
2552 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2553 "%s: Offset %u, Size %u", optp->name,
2554 relative_hole_offset, relative_hole_size);
2556 ack = tvb_get_ntohl(tvb, 8);
2558 if (tcp_relative_seq) {
2559 ack -= tcpd->rev->base_seq;
2560 modifier = relative_modifier;
2563 /* To aid analysis, we can use a simple but generally effective heuristic
2564 * to report the most likely boundaries of the missing data. If the
2565 * flow is scps_capable, we track the maximum sized segment that was
2566 * acknowledged by the receiver and use that as the reporting granularity.
2567 * This may be different from the negotiated MTU due to PMTUD or flows
2568 * that do not send max-sized segments.
2570 base_mss = tcpd->fwd->maxsizeacked;
2573 proto_item *hidden_item;
2574 /* Scale the reported offset and hole size by the largest segment acked */
2575 hole_start = ack + (base_mss * relative_hole_offset);
2576 hole_end = hole_start + (base_mss * relative_hole_size);
2578 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_le,
2579 tvb, offset, optlen, hole_start);
2580 PROTO_ITEM_SET_HIDDEN(hidden_item);
2582 hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_re,
2583 tvb, offset, optlen, hole_end);
2584 PROTO_ITEM_SET_HIDDEN(hidden_item);
2585 proto_tree_add_text(opt_tree, tvb, offset, optlen,
2586 "\tMissing Sequence %u - %u %s",
2587 hole_start, hole_end, modifier);
2589 tcp_info_append_uint(pinfo, "SNLE", hole_start);
2590 tcp_info_append_uint(pinfo, "SNRE", hole_end);
2592 expert_add_info_format(pinfo, NULL, PI_SEQUENCE, PI_NOTE,
2593 "SNACK Sequence %u - %u %s",
2594 hole_start, hole_end, modifier);
2598 static const ip_tcp_opt tcpopts[] = {
2617 "Maximum segment size",
2621 dissect_tcpopt_maxseg
2629 dissect_tcpopt_wscale
2642 &ett_tcp_option_sack,
2669 dissect_tcpopt_timestamp
2697 "TCP MD5 signature",
2705 "SCPS capabilities",
2706 &ett_tcp_option_scps,
2713 "Selective Negative Acknowledgement",
2717 dissect_tcpopt_snack
2721 "SCPS record boundary",
2729 "SCPS corruption experienced",
2745 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
2747 /* Determine if there is a sub-dissector and call it; return TRUE
2748 if there was a sub-dissector, FALSE otherwise.
2750 This has been separated into a stand alone routine to other protocol
2751 dissectors can call to it, e.g., SOCKS. */
2753 static gboolean try_heuristic_first = FALSE;
2756 /* this function can be called with tcpd==NULL as from the msproxy dissector */
2758 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
2759 proto_tree *tree, int src_port, int dst_port,
2760 struct tcp_analysis *tcpd)
2763 int low_port, high_port;
2764 int save_desegment_offset;
2765 guint32 save_desegment_len;
2767 /* dont call subdissectors for keepalive or zerowindowprobes
2768 * even though they do contain payload "data"
2769 * keeaplives just contain garbage and zwp contain too little data (1 byte)
2772 if(tcpd && tcpd->ta){
2773 if(tcpd->ta->flags&(TCP_A_ZERO_WINDOW_PROBE|TCP_A_KEEP_ALIVE)){
2778 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
2780 /* determine if this packet is part of a conversation and call dissector */
2781 /* for the conversation if available */
2783 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
2784 src_port, dst_port, next_tvb, pinfo, tree)){
2785 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2789 if (try_heuristic_first) {
2790 /* do lookup with the heuristic subdissector table */
2791 save_desegment_offset = pinfo->desegment_offset;
2792 save_desegment_len = pinfo->desegment_len;
2793 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2794 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2798 * They rejected the packet; make sure they didn't also request
2799 * desegmentation (we could just override the request, but
2800 * rejecting a packet *and* requesting desegmentation is a sign
2801 * of the dissector's code needing clearer thought, so we fail
2802 * so that the problem is made more obvious).
2804 DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
2805 save_desegment_len == pinfo->desegment_len);
2808 /* Do lookups with the subdissector table.
2809 We try the port number with the lower value first, followed by the
2810 port number with the higher value. This means that, for packets
2811 where a dissector is registered for *both* port numbers:
2813 1) we pick the same dissector for traffic going in both directions;
2815 2) we prefer the port number that's more likely to be the right
2816 one (as that prefers well-known ports to reserved ports);
2818 although there is, of course, no guarantee that any such strategy
2819 will always pick the right port number.
2821 XXX - we ignore port numbers of 0, as some dissectors use a port
2822 number of 0 to disable the port. */
2823 if (src_port > dst_port) {
2824 low_port = dst_port;
2825 high_port = src_port;
2827 low_port = src_port;
2828 high_port = dst_port;
2830 if (low_port != 0 &&
2831 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree)){
2832 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2835 if (high_port != 0 &&
2836 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree)){
2837 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2841 if (!try_heuristic_first) {
2842 /* do lookup with the heuristic subdissector table */
2843 save_desegment_offset = pinfo->desegment_offset;
2844 save_desegment_len = pinfo->desegment_len;
2845 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree)){
2846 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2850 * They rejected the packet; make sure they didn't also request
2851 * desegmentation (we could just override the request, but
2852 * rejecting a packet *and* requesting desegmentation is a sign
2853 * of the dissector's code needing clearer thought, so we fail
2854 * so that the problem is made more obvious).
2856 DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
2857 save_desegment_len == pinfo->desegment_len);
2860 /* Oh, well, we don't know this; dissect it as data. */
2861 call_dissector(data_handle,next_tvb, pinfo, tree);
2863 pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
2868 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
2869 proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
2870 guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
2871 struct tcp_analysis *tcpd)
2873 pinfo->want_pdu_tracking=0;
2877 /*qqq see if it is an unaligned PDU */
2878 if(tcpd && tcp_analyze_seq && (!tcp_desegment)){
2880 offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
2881 seq, nxtseq, tcpd->fwd->multisegment_pdus);
2885 /* if offset is -1 this means that this segment is known
2886 * to be fully inside a previously detected pdu
2887 * so we dont even need to try to dissect it either.
2890 decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
2893 * We succeeded in handing off to a subdissector.
2895 * Is this a TCP segment or a reassembled chunk of
2899 /* if !visited, check want_pdu_tracking and
2900 store it in table */
2901 if(tcpd && (!pinfo->fd->flags.visited) &&
2902 tcp_analyze_seq && pinfo->want_pdu_tracking){
2904 pdu_store_sequencenumber_of_next_pdu(
2907 nxtseq+pinfo->bytes_until_next_pdu,
2908 tcpd->fwd->multisegment_pdus);
2915 /* We got an exception. At this point the dissection is
2916 * completely aborted and execution will be transfered back
2917 * to (probably) the frame dissector.
2918 * Here we have to place whatever we want the dissector
2919 * to do before aborting the tcp dissection.
2922 * Is this a TCP segment or a reassembled chunk of TCP
2927 * It's from a TCP segment.
2929 * if !visited, check want_pdu_tracking and store it
2932 if(tcpd && (!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking){
2934 pdu_store_sequencenumber_of_next_pdu(pinfo,
2936 nxtseq+pinfo->bytes_until_next_pdu,
2937 tcpd->fwd->multisegment_pdus);
2947 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
2948 guint32 nxtseq, guint32 sport, guint32 dport,
2949 proto_tree *tree, proto_tree *tcp_tree,
2950 struct tcp_analysis *tcpd)
2952 gboolean save_fragmented;
2954 /* Can we desegment this segment? */
2955 if (pinfo->can_desegment) {
2957 desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
2960 /* No - just call the subdissector.
2961 Mark this as fragmented, so if somebody throws an exception,
2962 we don't report it as a malformed frame. */
2963 save_fragmented = pinfo->fragmented;
2964 pinfo->fragmented = TRUE;
2965 process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
2966 seq, nxtseq, TRUE, tcpd);
2967 pinfo->fragmented = save_fragmented;
2972 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2974 guint8 th_off_x2; /* combines th_off and th_x2 */
2977 proto_tree *tcp_tree = NULL, *field_tree = NULL;
2978 proto_item *ti = NULL, *tf, *hidden_item;
2980 emem_strbuf_t *flags_strbuf = ep_strbuf_new_label("<None>");
2981 const gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR"};
2989 guint16 computed_cksum;
2990 guint16 real_window;
2991 guint length_remaining;
2992 gboolean desegment_ok;
2993 struct tcpinfo tcpinfo;
2994 struct tcpheader *tcph;
2995 proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
2996 conversation_t *conv=NULL;
2997 struct tcp_analysis *tcpd=NULL;
2998 struct tcp_per_packet_data_t *tcppd=NULL;
3000 proto_tree *checksum_tree;
3004 tcph=ep_alloc(sizeof(struct tcpheader));
3005 SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
3006 SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
3008 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
3010 /* Clear out the Info column. */
3011 col_clear(pinfo->cinfo, COL_INFO);
3013 tcph->th_sport = tvb_get_ntohs(tvb, offset);
3014 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
3015 if (check_col(pinfo->cinfo, COL_INFO)) {
3016 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
3017 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
3020 if (tcp_summary_in_tree) {
3021 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
3022 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
3023 get_tcp_port(tcph->th_sport), tcph->th_sport,
3024 get_tcp_port(tcph->th_dport), tcph->th_dport);
3027 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
3029 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
3030 pinfo->tcp_tree=tcp_tree;
3032 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
3033 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
3034 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
3035 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
3036 hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
3037 PROTO_ITEM_SET_HIDDEN(hidden_item);
3038 hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
3039 PROTO_ITEM_SET_HIDDEN(hidden_item);
3041 /* If we're dissecting the headers of a TCP packet in an ICMP packet
3042 * then go ahead and put the sequence numbers in the tree now (because
3043 * they won't be put in later because the ICMP packet only contains up
3044 * to the sequence number).
3045 * We should only need to do this for IPv4 since IPv6 will hopefully
3046 * carry enough TCP payload for this dissector to put the sequence
3047 * numbers in via the regular code path.
3049 if (pinfo->layer_names != NULL && pinfo->layer_names->str != NULL) {
3050 /* use strstr because g_strrstr is only present in glib2.0 and
3051 * g_str_has_suffix in glib2.2
3053 if (strstr(pinfo->layer_names->str, "icmp:ip") != NULL)
3054 proto_tree_add_item(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, FALSE);
3058 /* Set the source and destination port numbers as soon as we get them,
3059 so that they're available to the "Follow TCP Stream" code even if
3060 we throw an exception dissecting the rest of the TCP header. */
3061 pinfo->ptype = PT_TCP;
3062 pinfo->srcport = tcph->th_sport;
3063 pinfo->destport = tcph->th_dport;
3065 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
3066 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
3067 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
3068 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
3069 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
3070 real_window = tcph->th_win;
3071 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
3073 /* find(or create if needed) the conversation for this tcp session */
3074 conv=get_tcp_conversation(pinfo);
3075 tcpd=get_tcp_conversation_data(conv,pinfo);
3077 item = proto_tree_add_uint(tcp_tree, hf_tcp_stream, tvb, offset, 0, conv->index);
3078 PROTO_ITEM_SET_GENERATED(item);
3080 /* If this is a SYN packet, then check if it's seq-nr is different
3081 * from the base_seq of the retrieved conversation. If this is the
3082 * case, create a new conversation with the same addresses and ports
3083 * and set the TA_PORTS_REUSED flag. If the seq-nr is the same as
3084 * the base_seq, then do nothing so it will be marked as a retrans-
3087 if(tcpd && ((tcph->th_flags&(TH_SYN|TH_ACK))==TH_SYN) &&
3088 (tcpd->fwd->base_seq!=0) &&
3089 (tcph->th_seq!=tcpd->fwd->base_seq) ) {
3090 if (!(pinfo->fd->flags.visited)) {
3091 conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
3092 tcpd=get_tcp_conversation_data(conv,pinfo);
3095 tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
3096 tcpd->ta->flags|=TCP_A_REUSED_PORTS;
3100 /* Do we need to calculate timestamps relative to the tcp-stream? */
3101 if (tcp_calculate_ts) {
3102 tcppd = p_get_proto_data(pinfo->fd, proto_tcp);
3105 * Calculate the timestamps relative to this conversation (but only on the
3106 * first run when frames are accessed sequentially)
3108 if (!(pinfo->fd->flags.visited))
3109 tcp_calculate_timestamps(pinfo, tcpd, tcppd);
3111 /* Fill the conversation timestamp columns */
3112 if (tcpd && check_col(pinfo->cinfo, COL_REL_CONV_TIME)) {
3113 nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first);
3114 col_set_time(pinfo->cinfo, COL_REL_CONV_TIME, &ts, "tcp.time_relative");
3117 if (check_col(pinfo->cinfo, COL_DELTA_CONV_TIME)) {
3119 col_set_time(pinfo->cinfo, COL_DELTA_CONV_TIME, &tcppd->ts_del, "tcp.time_delta");
3125 * If we've been handed an IP fragment, we don't know how big the TCP
3126 * segment is, so don't do anything that requires that we know that.
3128 * The same applies if we're part of an error packet. (XXX - if the
3129 * ICMP and ICMPv6 dissectors could set a "this is how big the IP
3130 * header says it is" length in the tvbuff, we could use that; such
3131 * a length might also be useful for handling packets where the IP
3132 * length is bigger than the actual data available in the frame; the
3133 * dissectors should trust that length, and then throw a
3134 * ReportedBoundsError exception when they go past the end of the frame.)
3136 * We also can't determine the segment length if the reported length
3137 * of the TCP packet is less than the TCP header length.
3139 reported_len = tvb_reported_length(tvb);
3141 if (!pinfo->fragmented && !pinfo->in_error_pkt) {
3142 if (reported_len < tcph->th_hlen) {
3144 pi = proto_tree_add_text(tcp_tree, tvb, offset, 0,
3145 "Short segment. Segment/fragment does not contain a full TCP header"
3146 " (might be NMAP or someone else deliberately sending unusual packets)");
3147 PROTO_ITEM_SET_GENERATED(pi);
3148 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_WARN, "Short segment");
3149 tcph->th_have_seglen = FALSE;
3151 /* Compute the length of data in this segment. */
3152 tcph->th_seglen = reported_len - tcph->th_hlen;
3153 tcph->th_have_seglen = TRUE;
3155 if (tree) { /* Add the seglen as an invisible field */
3157 hidden_item = proto_tree_add_uint(ti, hf_tcp_len, tvb, offset+12, 1, tcph->th_seglen);
3158 PROTO_ITEM_SET_HIDDEN(hidden_item);
3163 /* handle TCP seq# analysis parse all new segments we see */
3164 if(tcp_analyze_seq){
3165 if(!(pinfo->fd->flags.visited)){
3166 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
3168 if(tcp_relative_seq){
3169 tcp_get_relative_seq_ack(&(tcph->th_seq), &(tcph->th_ack), &(tcph->th_win), tcpd);
3173 /* Compute the sequence number of next octet after this segment. */
3174 nxtseq = tcph->th_seq + tcph->th_seglen;
3177 tcph->th_have_seglen = FALSE;
3179 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
3180 gboolean first_flag = TRUE;
3181 for (i = 0; i < 8; i++) {
3183 if (tcph->th_flags & bpos) {
3185 ep_strbuf_truncate(flags_strbuf, 0);
3187 ep_strbuf_append_printf(flags_strbuf, "%s%s", first_flag ? "" : ", ", fstr[i]);
3193 if (check_col(pinfo->cinfo, COL_INFO)) {
3194 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u", flags_strbuf->str, tcph->th_seq);
3195 if (tcph->th_flags&TH_ACK) {
3196 col_append_fstr(pinfo->cinfo, COL_INFO, " Ack=%u", tcph->th_ack);
3198 if (tcph->th_flags&TH_SYN) { /* SYNs are never scaled */
3199 col_append_fstr(pinfo->cinfo, COL_INFO, " Win=%u", real_window);
3201 col_append_fstr(pinfo->cinfo, COL_INFO, " Win=%u", tcph->th_win);
3206 if (tcp_summary_in_tree) {
3207 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
3209 if(tcp_relative_seq){
3210 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);
3212 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
3216 if (tcph->th_hlen < TCPH_MIN_LEN) {
3217 /* Give up at this point; we put the source and destination port in
3218 the tree, before fetching the header length, so that they'll
3219 show up if this is in the failing packet in an ICMP error packet,
3220 but it's now time to give up if the header length is bogus. */
3221 if (check_col(pinfo->cinfo, COL_INFO))
3222 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
3223 tcph->th_hlen, TCPH_MIN_LEN);
3225 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
3226 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
3233 if (tcp_summary_in_tree) {
3234 if(tcph->th_flags&TH_ACK){
3235 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
3237 if (tcph->th_have_seglen)
3238 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
3240 proto_item_set_len(ti, tcph->th_hlen);
3241 if (tcph->th_have_seglen) {
3242 if (nxtseq != tcph->th_seq) {
3243 if(tcp_relative_seq){
3244 tf=proto_tree_add_uint_format(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "Next sequence number: %u (relative sequence number)", nxtseq);
3246 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
3248 PROTO_ITEM_SET_GENERATED(tf);
3251 if (tcph->th_flags & TH_ACK) {
3252 if(tcp_relative_seq){
3253 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);
3255 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
3258 /* Verify that the ACK field is zero */
3259 if(tvb_get_ntohl(tvb, offset+8) != 0){
3260 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");
3263 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
3264 "Header length: %u bytes", tcph->th_hlen);
3265 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
3266 tcph->th_flags, "Flags: 0x%02x (%s)", tcph->th_flags, flags_strbuf->str);
3267 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
3268 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
3269 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
3270 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
3271 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
3272 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
3273 tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
3274 tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
3275 tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
3277 && (tcph->th_win!=real_window)
3278 && !(tcph->th_flags&TH_SYN) ){ /* SYNs are never scaled */
3279 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);
3281 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, real_window);
3285 if(tcph->th_flags & TH_SYN) {
3286 if(tcph->th_flags & TH_ACK)
3287 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): server port %s",
3288 get_tcp_port(tcph->th_sport));
3290 expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): server port %s",
3291 get_tcp_port(tcph->th_dport));
3293 if(tcph->th_flags & TH_FIN)
3294 /* XXX - find a way to know the server port and output only that one */
3295 expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN)");
3296 if(tcph->th_flags & TH_RST)
3297 /* XXX - find a way to know the server port and output only that one */
3298 expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST)");
3300 /* Supply the sequence number of the first byte and of the first byte
3301 after the segment. */
3302 tcpinfo.seq = tcph->th_seq;
3303 tcpinfo.nxtseq = nxtseq;
3304 tcpinfo.lastackseq = tcph->th_ack;
3306 /* Assume we'll pass un-reassembled data to subdissectors. */
3307 tcpinfo.is_reassembled = FALSE;
3309 pinfo->private_data = &tcpinfo;
3312 * Assume, initially, that we can't desegment.
3314 pinfo->can_desegment = 0;
3315 th_sum = tvb_get_ntohs(tvb, offset + 16);
3316 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
3317 /* The packet isn't part of an un-reassembled fragmented datagram
3318 and isn't truncated. This means we have all the data, and thus
3319 can checksum it and, unless it's being returned in an error
3320 packet, are willing to allow subdissectors to request reassembly
3323 if (tcp_check_checksum) {
3324 /* We haven't turned checksum checking off; checksum it. */
3326 /* Set up the fields of the pseudo-header. */
3327 cksum_vec[0].ptr = pinfo->src.data;
3328 cksum_vec[0].len = pinfo->src.len;
3329 cksum_vec[1].ptr = pinfo->dst.data;
3330 cksum_vec[1].len = pinfo->dst.len;
3331 cksum_vec[2].ptr = (const guint8 *)phdr;
3332 switch (pinfo->src.type) {
3335 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
3336 cksum_vec[2].len = 4;
3340 phdr[0] = g_htonl(reported_len);
3341 phdr[1] = g_htonl(IP_PROTO_TCP);
3342 cksum_vec[2].len = 8;
3346 /* TCP runs only atop IPv4 and IPv6.... */
3347 DISSECTOR_ASSERT_NOT_REACHED();
3350 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
3351 cksum_vec[3].len = reported_len;
3352 computed_cksum = in_cksum(cksum_vec, 4);
3353 if (computed_cksum == 0 && th_sum == 0xffff) {
3354 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3355 offset + 16, 2, th_sum,
3356 "Checksum: 0x%04x [should be 0x0000 (see RFC 1624)]", th_sum);
3358 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3359 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3360 offset + 16, 2, FALSE);
3361 PROTO_ITEM_SET_GENERATED(item);
3362 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3363 offset + 16, 2, FALSE);
3364 PROTO_ITEM_SET_GENERATED(item);
3365 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_WARN, "TCP Checksum 0xffff instead of 0x0000 (see RFC 1624)");
3367 if (check_col(pinfo->cinfo, COL_INFO))
3368 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM 0xFFFF]");
3370 /* Checksum is treated as valid on most systems, so we're willing to desegment it. */
3371 desegment_ok = TRUE;
3372 } else if (computed_cksum == 0) {
3373 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3374 offset + 16, 2, th_sum, "Checksum: 0x%04x [correct]", th_sum);
3376 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3377 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3378 offset + 16, 2, TRUE);
3379 PROTO_ITEM_SET_GENERATED(item);
3380 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3381 offset + 16, 2, FALSE);
3382 PROTO_ITEM_SET_GENERATED(item);
3384 /* Checksum is valid, so we're willing to desegment it. */
3385 desegment_ok = TRUE;
3386 } else if (th_sum == 0) {
3387 /* checksum is probably fine but checksum offload is used */
3388 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3389 offset + 16, 2, th_sum, "Checksum: 0x%04x [Checksum Offloaded]", th_sum);
3391 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3392 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3393 offset + 16, 2, FALSE);
3394 PROTO_ITEM_SET_GENERATED(item);
3395 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3396 offset + 16, 2, FALSE);
3397 PROTO_ITEM_SET_GENERATED(item);
3399 /* Checksum is (probably) valid, so we're willing to desegment it. */
3400 desegment_ok = TRUE;
3402 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3403 offset + 16, 2, th_sum,
3404 "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by \"TCP checksum offload\"?)]", th_sum,
3405 in_cksum_shouldbe(th_sum, computed_cksum));
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, TRUE);
3413 PROTO_ITEM_SET_GENERATED(item);
3414 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
3416 if (check_col(pinfo->cinfo, COL_INFO))
3417 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
3419 /* Checksum is invalid, so we're not willing to desegment it. */
3420 desegment_ok = FALSE;
3421 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
3424 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3425 offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
3427 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3428 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3429 offset + 16, 2, FALSE);
3430 PROTO_ITEM_SET_GENERATED(item);
3431 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3432 offset + 16, 2, FALSE);
3433 PROTO_ITEM_SET_GENERATED(item);
3435 /* We didn't check the checksum, and don't care if it's valid,
3436 so we're willing to desegment it. */
3437 desegment_ok = TRUE;
3440 /* We don't have all the packet data, so we can't checksum it... */
3441 item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
3442 offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
3444 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
3445 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
3446 offset + 16, 2, FALSE);
3447 PROTO_ITEM_SET_GENERATED(item);
3448 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
3449 offset + 16, 2, FALSE);
3450 PROTO_ITEM_SET_GENERATED(item);
3452 /* ...and aren't willing to desegment it. */
3453 desegment_ok = FALSE;
3457 /* We're willing to desegment this. Is desegmentation enabled? */
3458 if (tcp_desegment) {
3459 /* Yes - is this segment being returned in an error packet? */
3460 if (!pinfo->in_error_pkt) {
3461 /* No - indicate that we will desegment.
3462 We do NOT want to desegment segments returned in error
3463 packets, as they're not part of a TCP connection. */
3464 pinfo->can_desegment = 2;
3469 if (tcph->th_flags & TH_URG) {
3470 th_urp = tvb_get_ntohs(tvb, offset + 18);
3471 /* Export the urgent pointer, for the benefit of protocols such as
3473 tcpinfo.urgent = TRUE;
3474 tcpinfo.urgent_pointer = th_urp;
3475 if (check_col(pinfo->cinfo, COL_INFO))
3476 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
3477 if (tcp_tree != NULL)
3478 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
3480 tcpinfo.urgent = FALSE;
3482 if (tcph->th_have_seglen) {
3483 if (check_col(pinfo->cinfo, COL_INFO))
3484 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
3487 /* Decode TCP options, if any. */
3488 if (tcph->th_hlen > TCPH_MIN_LEN) {
3489 /* There's more than just the fixed-length header. Decode the
3491 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
3492 tvb_ensure_bytes_exist(tvb, offset + 20, optlen);
3493 if (tcp_tree != NULL) {
3494 guint8 *p_options = ep_tvb_memdup(tvb, offset + 20, optlen);
3495 tf = proto_tree_add_bytes_format(tcp_tree, hf_tcp_options, tvb, offset + 20,
3496 optlen, p_options, "Options: (%u bytes)", optlen);
3497 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
3500 dissect_ip_tcp_options(tvb, offset + 20, optlen,
3501 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
3504 if(!pinfo->fd->flags.visited){
3505 if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
3506 /* If there was window scaling in the SYN packet but none in the SYN+ACK
3507 * then we should just forget about the windowscaling completely.
3509 if(tcp_analyze_seq && tcp_relative_seq){
3510 verify_tcp_window_scaling(tcpd);
3512 /* If the SYN or the SYN+ACK offered SCPS capabilities,
3513 * validate the flow's bidirectional scps capabilities.
3514 * The or protects against broken implementations offering
3515 * SCPS capabilities on SYN+ACK even if it wasn't offered with the SYN
3517 if(tcpd && ((tcpd->rev->scps_capable) || (tcpd->fwd->scps_capable))) {
3518 verify_scps(pinfo, tf_syn, tcpd);
3523 /* Skip over header + options */
3524 offset += tcph->th_hlen;
3526 /* Check the packet length to see if there's more data
3527 (it could be an ACK-only packet) */
3528 length_remaining = tvb_length_remaining(tvb, offset);
3530 if (tcph->th_have_seglen) {
3531 if( data_out_file ) {
3532 reassemble_tcp( tcph->th_seq, /* sequence number */
3533 tcph->th_ack, /* acknowledgement number */
3534 tcph->th_seglen, /* data length */
3535 (gchar*)tvb_get_ptr(tvb, offset, length_remaining), /* data */
3536 length_remaining, /* captured data length */
3537 ( tcph->th_flags & TH_SYN ), /* is syn set? */
3545 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
3546 if(tcp_analyze_seq){
3547 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd);
3550 /* handle conversation timestamps */
3551 if(tcp_calculate_ts){
3552 tcp_print_timestamps(pinfo, tvb, tcp_tree, tcpd, tcppd);
3555 tap_queue_packet(tcp_tap, pinfo, tcph);
3558 /* A FIN packet might complete reassembly so we need to explicitly
3559 * check for this here.
3561 if(tcpd && (tcph->th_flags & TH_FIN)
3562 && (tcpd->fwd->flags&TCP_FLOW_REASSEMBLE_UNTIL_FIN) ){
3563 struct tcp_multisegment_pdu *msp;
3565 /* find the most previous PDU starting before this sequence number */
3566 msp=se_tree_lookup32_le(tcpd->fwd->multisegment_pdus, tcph->th_seq-1);
3568 fragment_data *ipfd_head;
3570 ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
3572 tcph->th_seq - msp->seq,
3578 /* create a new TVB structure for desegmented data
3579 * datalen-1 to strip the dummy FIN byte off
3581 next_tvb = tvb_new_child_real_data(tvb, ipfd_head->data, ipfd_head->datalen, ipfd_head->datalen);
3583 /* add desegmented data to the data source list */
3584 add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
3586 /* call the payload dissector
3587 * but make sure we don't offer desegmentation any more
3589 pinfo->can_desegment = 0;
3591 process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, tcph->th_sport, tcph->th_dport, tcph->th_seq, nxtseq, FALSE, tcpd);
3593 print_tcp_fragment_tree(ipfd_head, tree, tcp_tree, pinfo, next_tvb);
3600 if (tcpd && (tcpd->fwd || tcpd->rev) && (tcpd->fwd->command || tcpd->rev->command)) {
3601 ti = proto_tree_add_text(tcp_tree, tvb, offset, 0, "Process Information");
3602 PROTO_ITEM_SET_GENERATED(ti);
3603 field_tree = proto_item_add_subtree(ti, ett_tcp_process_info);
3604 if (tcpd->fwd->command) {
3605 proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_dst_uid, tvb, 0, 0,
3606 tcpd->fwd->process_uid, "%u", tcpd->fwd->process_uid);
3607 proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_dst_pid, tvb, 0, 0,
3608 tcpd->fwd->process_pid, "%u", tcpd->fwd->process_pid);
3609 proto_tree_add_string_format_value(field_tree, hf_tcp_proc_dst_uname, tvb, 0, 0,
3610 tcpd->fwd->username, "%s", tcpd->fwd->username);
3611 proto_tree_add_string_format_value(field_tree, hf_tcp_proc_dst_cmd, tvb, 0, 0,
3612 tcpd->fwd->command, "%s", tcpd->fwd->command);
3614 if (tcpd->rev->command) {
3615 proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_src_uid, tvb, 0, 0,
3616 tcpd->rev->process_uid, "%u", tcpd->rev->process_uid);
3617 proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_src_pid, tvb, 0, 0,
3618 tcpd->rev->process_pid, "%u", tcpd->rev->process_pid);
3619 proto_tree_add_string_format_value(field_tree, hf_tcp_proc_src_uname, tvb, 0, 0,
3620 tcpd->rev->username, "%s", tcpd->rev->username);
3621 proto_tree_add_string_format_value(field_tree, hf_tcp_proc_src_cmd, tvb, 0, 0,
3622 tcpd->rev->command, "%s", tcpd->rev->command);
3627 * XXX - what, if any, of this should we do if this is included in an
3628 * error packet? It might be nice to see the details of the packet
3629 * that caused the ICMP error, but it might not be nice to have the
3630 * dissector update state based on it.
3631 * Also, we probably don't want to run TCP taps on those packets.
3633 if (length_remaining != 0) {
3634 if (tcph->th_flags & TH_RST) {
3638 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
3640 * A TCP SHOULD allow a received RST segment to include data.
3643 * It has been suggested that a RST segment could contain
3644 * ASCII text that encoded and explained the cause of the
3645 * RST. No standard has yet been established for such
3648 * so for segments with RST we just display the data as text.
3650 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
3652 tvb_format_text(tvb, offset, length_remaining));
3654 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
3655 tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd);
3661 proto_register_tcp(void)
3663 static hf_register_info hf[] = {
3666 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
3670 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
3674 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
3678 { "Stream index", "tcp.stream", FT_UINT32, BASE_DEC, NULL, 0x0,
3682 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
3686 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
3690 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
3694 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
3698 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
3701 { &hf_tcp_flags_cwr,
3702 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_CWR,
3705 { &hf_tcp_flags_ecn,
3706 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_ECN,
3709 { &hf_tcp_flags_urg,
3710 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_URG,
3713 { &hf_tcp_flags_ack,
3714 { "Acknowledgement", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_ACK,
3717 { &hf_tcp_flags_push,
3718 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_PUSH,
3721 { &hf_tcp_flags_reset,
3722 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_RST,
3725 { &hf_tcp_flags_syn,
3726 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_SYN,
3729 { &hf_tcp_flags_fin,
3730 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&tfs_set_notset), TH_FIN,
3733 /* 32 bits so we can present some values adjusted to window scaling */
3734 { &hf_tcp_window_size,
3735 { "Window size", "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
3739 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
3740 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
3742 { &hf_tcp_checksum_good,
3743 { "Good Checksum", "tcp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3744 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
3746 { &hf_tcp_checksum_bad,
3747 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3748 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
3750 { &hf_tcp_analysis_flags,
3751 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
3752 "This frame has some of the TCP analysis flags set", HFILL }},
3754 { &hf_tcp_analysis_retransmission,
3755 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
3756 "This frame is a suspected TCP retransmission", HFILL }},
3758 { &hf_tcp_analysis_fast_retransmission,
3759 { "Fast Retransmission", "tcp.analysis.fast_retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
3760 "This frame is a suspected TCP fast retransmission", HFILL }},
3762 { &hf_tcp_analysis_out_of_order,
3763 { "Out Of Order", "tcp.analysis.out_of_order", FT_NONE, BASE_NONE, NULL, 0x0,
3764 "This frame is a suspected Out-Of-Order segment", HFILL }},
3766 { &hf_tcp_analysis_reused_ports,
3767 { "TCP Port numbers reused", "tcp.analysis.reused_ports", FT_NONE, BASE_NONE, NULL, 0x0,
3768 "A new tcp session has started with previously used port numbers", HFILL }},
3770 { &hf_tcp_analysis_lost_packet,
3771 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
3772 "A segment before this one was lost from the capture", HFILL }},
3774 { &hf_tcp_analysis_ack_lost_packet,
3775 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
3776 "This frame ACKs a lost segment", HFILL }},
3778 { &hf_tcp_analysis_window_update,
3779 { "Window update", "tcp.analysis.window_update", FT_NONE, BASE_NONE, NULL, 0x0,
3780 "This frame is a tcp window update", HFILL }},
3782 { &hf_tcp_analysis_window_full,
3783 { "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
3784 "This segment has caused the allowed window to become 100% full", HFILL }},
3786 { &hf_tcp_analysis_keep_alive,
3787 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
3788 "This is a keep-alive segment", HFILL }},
3790 { &hf_tcp_analysis_keep_alive_ack,
3791 { "Keep Alive ACK", "tcp.analysis.keep_alive_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3792 "This is an ACK to a keep-alive segment", HFILL }},
3794 { &hf_tcp_analysis_duplicate_ack,
3795 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3796 "This is a duplicate ACK", HFILL }},
3798 { &hf_tcp_analysis_duplicate_ack_num,
3799 { "Duplicate ACK #", "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
3800 "This is duplicate ACK number #", HFILL }},
3802 { &hf_tcp_analysis_duplicate_ack_frame,
3803 { "Duplicate to the ACK in frame", "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3804 "This is a duplicate to the ACK in frame #", HFILL }},
3806 { &hf_tcp_continuation_to,
3807 { "This is a continuation to the PDU in frame", "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3808 "This is a continuation to the PDU in frame #", HFILL }},
3810 { &hf_tcp_analysis_zero_window_probe,
3811 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
3812 "This is a zero-window-probe", HFILL }},
3814 { &hf_tcp_analysis_zero_window_probe_ack,
3815 { "Zero Window Probe Ack", "tcp.analysis.zero_window_probe_ack", FT_NONE, BASE_NONE, NULL, 0x0,
3816 "This is an ACK to a zero-window-probe", HFILL }},
3818 { &hf_tcp_analysis_zero_window,
3819 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
3820 "This is a zero-window", HFILL }},
3823 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
3826 { &hf_tcp_analysis_acks_frame,
3827 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3828 "Which previous segment is this an ACK for", HFILL}},
3830 { &hf_tcp_analysis_bytes_in_flight,
3831 { "Number of bytes in flight", "tcp.analysis.bytes_in_flight", FT_UINT32, BASE_DEC, NULL, 0x0,
3832 "How many bytes are now in flight for this connection", HFILL}},
3834 { &hf_tcp_analysis_ack_rtt,
3835 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3836 "How long time it took to ACK the segment (RTT)", HFILL}},
3838 { &hf_tcp_analysis_rto,
3839 { "The RTO for this segment was", "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3840 "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
3842 { &hf_tcp_analysis_rto_frame,
3843 { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3844 "This is the frame we measure the RTO from", HFILL }},
3846 { &hf_tcp_urgent_pointer,
3847 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
3850 { &hf_tcp_segment_overlap,
3851 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3852 "Segment overlaps with other segments", HFILL }},
3854 { &hf_tcp_segment_overlap_conflict,
3855 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3856 "Overlapping segments contained conflicting data", HFILL }},
3858 { &hf_tcp_segment_multiple_tails,
3859 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3860 "Several tails were found when reassembling the pdu", HFILL }},
3862 { &hf_tcp_segment_too_long_fragment,
3863 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3864 "Segment contained data past end of the pdu", HFILL }},
3866 { &hf_tcp_segment_error,
3867 { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3868 "Reassembling error due to illegal segments", HFILL }},
3871 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3875 { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
3876 "TCP Segments", HFILL }},
3878 { &hf_tcp_reassembled_in,
3879 { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3880 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
3883 { "TCP Options", "tcp.options", FT_BYTES,
3884 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3886 { &hf_tcp_option_mss,
3887 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
3888 BASE_NONE, NULL, 0x0, NULL, HFILL }},
3890 { &hf_tcp_option_mss_val,
3891 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
3892 BASE_DEC, NULL, 0x0, NULL, HFILL}},
3894 { &hf_tcp_option_wscale,
3895 { "TCP Window Scale Option", "tcp.options.wscale",
3897 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
3899 { &hf_tcp_option_wscale_val,
3900 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
3901 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
3904 { &hf_tcp_option_sack_perm,
3905 { "TCP Sack Perm Option", "tcp.options.sack_perm",
3907 BASE_NONE, NULL, 0x0, NULL, HFILL}},
3909 { &hf_tcp_option_sack,
3910 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
3911 BASE_NONE, NULL, 0x0, NULL, HFILL}},
3913 { &hf_tcp_option_sack_sle,
3914 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
3915 BASE_DEC, NULL, 0x0, NULL, HFILL}},
3917 { &hf_tcp_option_sack_sre,
3918 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
3919 BASE_DEC, NULL, 0x0, NULL, HFILL}},
3921 { &hf_tcp_option_echo,
3922 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
3923 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
3925 { &hf_tcp_option_echo_reply,
3926 { "TCP Echo Reply Option", "tcp.options.echo_reply",
3928 BASE_NONE, NULL, 0x0, NULL, HFILL}},
3930 { &hf_tcp_option_time_stamp,
3931 { "TCP Time Stamp Option", "tcp.options.time_stamp",
3933 BASE_NONE, NULL, 0x0, NULL, HFILL}},
3935 { &hf_tcp_option_cc,
3936 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
3937 NULL, 0x0, NULL, HFILL}},
3939 { &hf_tcp_option_ccnew,
3940 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
3941 BASE_NONE, NULL, 0x0, NULL, HFILL}},
3943 { &hf_tcp_option_ccecho,
3944 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
3945 BASE_NONE, NULL, 0x0, NULL, HFILL}},
3947 { &hf_tcp_option_md5,
3948 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
3949 NULL, 0x0, NULL, HFILL}},
3951 { &hf_tcp_option_qs,
3952 { "TCP QS Option", "tcp.options.qs", FT_BOOLEAN, BASE_NONE,
3953 NULL, 0x0, NULL, HFILL}},
3955 { &hf_tcp_option_scps,
3956 { "TCP SCPS Capabilities Option", "tcp.options.scps",
3957 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3960 { &hf_tcp_option_scps_vector,
3961 { "TCP SCPS Capabilities Vector", "tcp.options.scps.vector",
3962 FT_UINT8, BASE_DEC, NULL, 0x0,
3965 { &hf_tcp_option_scps_binding,
3966 { "TCP SCPS Extended Binding Spacce",
3967 "tcp.options.scps.binding",
3968 FT_UINT8, BASE_DEC, NULL, 0x0,
3969 "TCP SCPS Extended Binding Space", HFILL}},
3971 { &hf_tcp_option_snack,
3972 { "TCP Selective Negative Acknowledgement Option",
3973 "tcp.options.snack",
3974 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3977 { &hf_tcp_option_snack_offset,
3978 { "TCP SNACK Offset", "tcp.options.snack.offset",
3979 FT_UINT16, BASE_DEC, NULL, 0x0,
3982 { &hf_tcp_option_snack_size,
3983 { "TCP SNACK Size", "tcp.options.snack.size",
3984 FT_UINT16, BASE_DEC, NULL, 0x0,
3987 { &hf_tcp_option_snack_le,
3988 { "TCP SNACK Left Edge", "tcp.options.snack.le",
3989 FT_UINT16, BASE_DEC, NULL, 0x0,
3992 { &hf_tcp_option_snack_re,
3993 { "TCP SNACK Right Edge", "tcp.options.snack.re",
3994 FT_UINT16, BASE_DEC, NULL, 0x0,
3997 { &hf_tcp_scpsoption_flags_bets,
3998 { "Partial Reliability Capable (BETS)",
3999 "tcp.options.scpsflags.bets", FT_BOOLEAN, 8,
4000 TFS(&tfs_set_notset), 0x80, NULL, HFILL }},
4002 { &hf_tcp_scpsoption_flags_snack1,
4003 { "Short Form SNACK Capable (SNACK1)",
4004 "tcp.options.scpsflags.snack1", FT_BOOLEAN, 8,
4005 TFS(&tfs_set_notset), 0x40, NULL, HFILL }},
4007 { &hf_tcp_scpsoption_flags_snack2,
4008 { "Long Form SNACK Capable (SNACK2)",
4009 "tcp.options.scpsflags.snack2", FT_BOOLEAN, 8,
4010 TFS(&tfs_set_notset), 0x20, NULL, HFILL }},
4012 { &hf_tcp_scpsoption_flags_compress,
4013 { "Lossless Header Compression (COMP)",
4014 "tcp.options.scpsflags.compress", FT_BOOLEAN, 8,
4015 TFS(&tfs_set_notset), 0x10, NULL, HFILL }},
4017 { &hf_tcp_scpsoption_flags_nlts,
4018 { "Network Layer Timestamp (NLTS)",
4019 "tcp.options.scpsflags.nlts", FT_BOOLEAN, 8,
4020 TFS(&tfs_set_notset), 0x8, NULL, HFILL }},
4022 { &hf_tcp_scpsoption_flags_resv1,
4024 "tcp.options.scpsflags.reserved1", FT_BOOLEAN, 8,
4025 TFS(&tfs_set_notset), 0x4, NULL, HFILL }},
4027 { &hf_tcp_scpsoption_flags_resv2,
4029 "tcp.options.scpsflags.reserved2", FT_BOOLEAN, 8,
4030 TFS(&tfs_set_notset), 0x2, NULL, HFILL }},
4032 { &hf_tcp_scpsoption_flags_resv3,
4034 "tcp.options.scpsflags.reserved3", FT_BOOLEAN, 8,
4035 TFS(&tfs_set_notset), 0x1, NULL, HFILL }},
4038 { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4039 "How long time has passed until the last frame of this PDU", HFILL}},
4042 { "PDU Size", "tcp.pdu.size", FT_UINT32, BASE_DEC, NULL, 0x0,
4043 "The size of this PDU", HFILL}},
4045 { &hf_tcp_pdu_last_frame,
4046 { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4047 "This is the last frame of the PDU starting in this segment", HFILL }},
4049 { &hf_tcp_ts_relative,
4050 { "Time since first frame in this TCP stream", "tcp.time_relative", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4051 "Time relative to first frame in this TCP stream", HFILL}},
4054 { "Time since previous frame in this TCP stream", "tcp.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4055 "Time delta from previous frame in this TCP stream", HFILL}},
4057 { &hf_tcp_proc_src_uid,
4058 { "Source process user ID", "tcp.proc.srcuid", FT_UINT32, BASE_DEC, NULL, 0x0,
4061 { &hf_tcp_proc_src_pid,
4062 { "Source process ID", "tcp.proc.srcpid", FT_UINT32, BASE_DEC, NULL, 0x0,
4065 { &hf_tcp_proc_src_uname,
4066 { "Source process user name", "tcp.proc.srcuname", FT_STRING, BASE_NONE, NULL, 0x0,
4069 { &hf_tcp_proc_src_cmd,
4070 { "Source process name", "tcp.proc.srccmd", FT_STRING, BASE_NONE, NULL, 0x0,
4071 "Source process command name", HFILL}},
4073 { &hf_tcp_proc_dst_uid,
4074 { "Destination process user ID", "tcp.proc.dstuid", FT_UINT32, BASE_DEC, NULL, 0x0,
4077 { &hf_tcp_proc_dst_pid,
4078 { "Destination process ID", "tcp.proc.dstpid", FT_UINT32, BASE_DEC, NULL, 0x0,
4081 { &hf_tcp_proc_dst_uname,
4082 { "Destination process user name", "tcp.proc.dstuname", FT_STRING, BASE_NONE, NULL, 0x0,
4085 { &hf_tcp_proc_dst_cmd,
4086 { "Destination process name", "tcp.proc.dstcmd", FT_STRING, BASE_NONE, NULL, 0x0,
4087 "Destination process command name", HFILL}}
4090 static gint *ett[] = {
4094 &ett_tcp_option_sack,
4095 &ett_tcp_option_scps,
4096 &ett_tcp_option_scps_extended,
4097 &ett_tcp_analysis_faults,
4099 &ett_tcp_timestamps,
4103 &ett_tcp_process_info
4105 module_t *tcp_module;
4107 proto_tcp = proto_register_protocol("Transmission Control Protocol",
4109 proto_register_field_array(proto_tcp, hf, array_length(hf));
4110 proto_register_subtree_array(ett, array_length(ett));
4112 /* subdissector code */
4113 subdissector_table = register_dissector_table("tcp.port",
4114 "TCP port", FT_UINT16, BASE_DEC);
4115 register_heur_dissector_list("tcp", &heur_subdissector_list);
4117 /* Register configuration preferences */
4118 tcp_module = prefs_register_protocol(proto_tcp, NULL);
4119 prefs_register_bool_preference(tcp_module, "summary_in_tree",
4120 "Show TCP summary in protocol tree",
4121 "Whether the TCP summary line should be shown in the protocol tree",
4122 &tcp_summary_in_tree);
4123 prefs_register_bool_preference(tcp_module, "check_checksum",
4124 "Validate the TCP checksum if possible",
4125 "Whether to validate the TCP checksum",
4126 &tcp_check_checksum);
4127 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
4128 "Allow subdissector to reassemble TCP streams",
4129 "Whether subdissector can request TCP streams to be reassembled",
4131 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
4132 "Analyze TCP sequence numbers",
4133 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
4135 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
4136 "Relative sequence numbers and window scaling",
4137 "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
4138 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
4139 "This option will also try to track and adjust the window field according to any TCP window scaling options seen.",
4141 prefs_register_bool_preference(tcp_module, "track_bytes_in_flight",
4142 "Track number of bytes in flight",
4143 "Make the TCP dissector track the number on un-ACKed bytes of data are in flight per packet. "
4144 "To use this option you must also enable \"Analyze TCP sequence numbers\". "
4145 "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",
4146 &tcp_track_bytes_in_flight);
4147 prefs_register_bool_preference(tcp_module, "calculate_timestamps",
4148 "Calculate conversation timestamps",
4149 "Calculate timestamps relative to the first frame and the previous frame in the tcp conversation",
4151 prefs_register_bool_preference(tcp_module, "try_heuristic_first",
4152 "Try heuristic sub-dissectors first",
4153 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
4154 &try_heuristic_first);
4156 register_init_routine(tcp_fragment_init);
4160 proto_reg_handoff_tcp(void)
4162 dissector_handle_t tcp_handle;
4164 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
4165 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
4166 data_handle = find_dissector("data");
4167 tcp_tap = register_tap("tcp");
4176 * indent-tabs-mode: t
4179 * ex: set shiftwidth=4 tabstop=4 noexpandtab
4180 * :indentSize=4:tabSize=4:noTabs=false: