2 * Routines for TCP packet disassembly
4 * $Id: packet-tcp.c,v 1.187 2003/03/26 08:00:24 sahlberg Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <epan/resolv.h>
38 #include "packet-tcp.h"
39 #include "packet-ip.h"
40 #include "packet-frame.h"
41 #include <epan/conversation.h>
42 #include <epan/strutil.h>
43 #include "reassemble.h"
46 static int tcp_tap = -1;
48 /* Place TCP summary in proto tree */
49 static gboolean tcp_summary_in_tree = TRUE;
52 * Flag to control whether to check the TCP checksum.
54 * In at least some Solaris network traces, there are packets with bad
55 * TCP checksums, but the traffic appears to indicate that the packets
56 * *were* received; the packets were probably sent by the host on which
57 * the capture was being done, on a network interface to which
58 * checksumming was offloaded, so that DLPI supplied an un-checksummed
59 * packet to the capture program but a checksummed packet got put onto
62 static gboolean tcp_check_checksum = TRUE;
64 extern FILE* data_out_file;
66 static int proto_tcp = -1;
67 static int hf_tcp_srcport = -1;
68 static int hf_tcp_dstport = -1;
69 static int hf_tcp_port = -1;
70 static int hf_tcp_seq = -1;
71 static int hf_tcp_nxtseq = -1;
72 static int hf_tcp_ack = -1;
73 static int hf_tcp_hdr_len = -1;
74 static int hf_tcp_flags = -1;
75 static int hf_tcp_flags_cwr = -1;
76 static int hf_tcp_flags_ecn = -1;
77 static int hf_tcp_flags_urg = -1;
78 static int hf_tcp_flags_ack = -1;
79 static int hf_tcp_flags_push = -1;
80 static int hf_tcp_flags_reset = -1;
81 static int hf_tcp_flags_syn = -1;
82 static int hf_tcp_flags_fin = -1;
83 static int hf_tcp_window_size = -1;
84 static int hf_tcp_checksum = -1;
85 static int hf_tcp_checksum_bad = -1;
86 static int hf_tcp_len = -1;
87 static int hf_tcp_urgent_pointer = -1;
88 static int hf_tcp_analysis_flags = -1;
89 static int hf_tcp_analysis_acks_frame = -1;
90 static int hf_tcp_analysis_ack_rtt = -1;
91 static int hf_tcp_analysis_retransmission = -1;
92 static int hf_tcp_analysis_lost_packet = -1;
93 static int hf_tcp_analysis_ack_lost_packet = -1;
94 static int hf_tcp_analysis_keep_alive = -1;
95 static int hf_tcp_analysis_duplicate_ack = -1;
96 static int hf_tcp_analysis_zero_window = -1;
97 static int hf_tcp_analysis_zero_window_probe = -1;
98 static int hf_tcp_analysis_zero_window_violation = -1;
99 static int hf_tcp_segments = -1;
100 static int hf_tcp_segment = -1;
101 static int hf_tcp_segment_overlap = -1;
102 static int hf_tcp_segment_overlap_conflict = -1;
103 static int hf_tcp_segment_multiple_tails = -1;
104 static int hf_tcp_segment_too_long_fragment = -1;
105 static int hf_tcp_segment_error = -1;
106 static int hf_tcp_option_mss = -1;
107 static int hf_tcp_option_mss_val = -1;
108 static int hf_tcp_option_wscale = -1;
109 static int hf_tcp_option_wscale_val = -1;
110 static int hf_tcp_option_sack_perm = -1;
111 static int hf_tcp_option_sack = -1;
112 static int hf_tcp_option_sack_sle = -1;
113 static int hf_tcp_option_sack_sre = -1;
114 static int hf_tcp_option_echo = -1;
115 static int hf_tcp_option_echo_reply = -1;
116 static int hf_tcp_option_time_stamp = -1;
117 static int hf_tcp_option_cc = -1;
118 static int hf_tcp_option_ccnew = -1;
119 static int hf_tcp_option_ccecho = -1;
120 static int hf_tcp_option_md5 = -1;
122 static gint ett_tcp = -1;
123 static gint ett_tcp_flags = -1;
124 static gint ett_tcp_options = -1;
125 static gint ett_tcp_option_sack = -1;
126 static gint ett_tcp_analysis = -1;
127 static gint ett_tcp_analysis_faults = -1;
128 static gint ett_tcp_segments = -1;
129 static gint ett_tcp_segment = -1;
132 /* not all of the hf_fields below make sense for TCP but we have to provide
133 them anyways to comply with the api (which was aimed for ip fragment
135 static const fragment_items tcp_segment_items = {
140 &hf_tcp_segment_overlap,
141 &hf_tcp_segment_overlap_conflict,
142 &hf_tcp_segment_multiple_tails,
143 &hf_tcp_segment_too_long_fragment,
144 &hf_tcp_segment_error,
148 static dissector_table_t subdissector_table;
149 static heur_dissector_list_t heur_subdissector_list;
150 static dissector_handle_t data_handle;
152 /* TCP structs and definitions */
155 /* **************************************************************************
156 * stuff to analyze TCP sequencenumbers for retransmissions, missing segments,
157 * RTT and reltive sequence numbers.
158 * **************************************************************************/
159 static gboolean tcp_analyze_seq = FALSE;
160 static gboolean tcp_relative_seq = FALSE;
162 static GMemChunk *tcp_unacked_chunk = NULL;
163 static int tcp_unacked_count = 500; /* one for each packet until it is acked*/
165 struct tcp_unacked *next;
171 /* these are used for detection of duplicate acks and nothing else */
176 /* this is to keep track of zero window and zero window probe */
180 /* Idea for gt: either x > y, or y is much bigger (assume wrap) */
181 #define GT_SEQ(x, y) ((gint32)((y) - (x)) < 0)
182 #define LT_SEQ(x, y) ((gint32)((x) - (y)) < 0)
183 #define GE_SEQ(x, y) ((gint32)((y) - (x)) <= 0)
184 #define LE_SEQ(x, y) ((gint32)((x) - (y)) <= 0)
185 #define EQ_SEQ(x, y) ((x) == (y))
187 static GMemChunk *tcp_acked_chunk = NULL;
188 static int tcp_acked_count = 5000; /* one for almost every other segment in the capture */
189 #define TCP_A_RETRANSMISSION 0x01
190 #define TCP_A_LOST_PACKET 0x02
191 #define TCP_A_ACK_LOST_PACKET 0x04
192 #define TCP_A_KEEP_ALIVE 0x08
193 #define TCP_A_DUPLICATE_ACK 0x10
194 #define TCP_A_ZERO_WINDOW 0x20
195 #define TCP_A_ZERO_WINDOW_PROBE 0x40
196 #define TCP_A_ZERO_WINDOW_VIOLATION 0x80
202 static GHashTable *tcp_analyze_acked_table = NULL;
204 static GMemChunk *tcp_rel_seq_chunk = NULL;
205 static int tcp_rel_seq_count = 10000; /* one for each segment in the capture */
210 static GHashTable *tcp_rel_seq_table = NULL;
212 static GMemChunk *tcp_analysis_chunk = NULL;
213 static int tcp_analysis_count = 20; /* one for each conversation */
214 struct tcp_analysis {
215 /* These two structs are managed based on comparing the source
216 * and destination addresses and, if they're equal, comparing
217 * the source and destination ports.
219 * If the source is greater than the destination, then stuff
220 * sent from src is in ual1.
222 * If the source is less than the destination, then stuff
223 * sent from src is in ual2.
225 * XXX - if the addresses and ports are equal, we don't guarantee
228 struct tcp_unacked *ual1; /* UnAcked List 1*/
230 struct tcp_unacked *ual2; /* UnAcked List 2*/
235 tcp_get_relative_seq_ack(guint32 frame, guint32 *seq, guint32 *ack)
237 struct tcp_rel_seq *trs;
239 trs=g_hash_table_lookup(tcp_rel_seq_table, (void *)frame);
244 (*seq) -= trs->seq_base;
245 (*ack) -= trs->ack_base;
248 static struct tcp_acked *
249 tcp_analyze_get_acked_struct(guint32 frame, gboolean createflag)
251 struct tcp_acked *ta;
253 ta=g_hash_table_lookup(tcp_analyze_acked_table, (void *)frame);
254 if((!ta) && createflag){
255 ta=g_mem_chunk_alloc(tcp_acked_chunk);
260 g_hash_table_insert(tcp_analyze_acked_table, (void *)frame, ta);
266 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint8 flags, guint16 window)
268 conversation_t *conv=NULL;
269 struct tcp_analysis *tcpd=NULL;
271 struct tcp_unacked *ual1=NULL;
272 struct tcp_unacked *ual2=NULL;
273 struct tcp_unacked *ual=NULL;
277 /* Have we seen this conversation before? */
278 if( (conv=find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0)) == NULL){
279 /* No this is a new conversation. */
280 conv=conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
283 /* check if we have any data for this conversation */
284 tcpd=conversation_get_proto_data(conv, proto_tcp);
286 /* No no such data yet. Allocate and init it */
287 tcpd=g_mem_chunk_alloc(tcp_analysis_chunk);
292 conversation_add_proto_data(conv, proto_tcp, tcpd);
295 /* check direction and get ua lists */
296 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
297 /* if the addresses are equal, match the ports instead */
299 direction= (pinfo->srcport > pinfo->destport)*2-1;
304 base_seq=tcpd->base_seq1;
305 base_ack=tcpd->base_seq2;
309 base_seq=tcpd->base_seq2;
310 base_ack=tcpd->base_seq1;
321 /* To handle FIN, just add 1 to the length.
322 else the ACK following the FIN-ACK will look like it was
323 outside the window. */
328 /* handle the sequence numbers */
329 /* if this was a SYN packet, then remove existing list and
330 * put SEQ+1 first the list */
332 for(ual=ual1;ual1;ual1=ual){
334 g_mem_chunk_free(tcp_unacked_chunk, ual1);
336 ual1=g_mem_chunk_alloc(tcp_unacked_chunk);
338 ual1->frame=pinfo->fd->num;
344 ual1->ts.secs=pinfo->fd->abs_secs;
345 ual1->ts.nsecs=pinfo->fd->abs_usecs*1000;
352 /* if this is the first segment we see then just add it */
354 ual1=g_mem_chunk_alloc(tcp_unacked_chunk);
356 ual1->frame=pinfo->fd->num;
361 ual1->nextseq=seq+seglen;
362 ual1->ts.secs=pinfo->fd->abs_secs;
363 ual1->ts.nsecs=pinfo->fd->abs_usecs*1000;
369 /* if we get past here we know that ual1 points to a segment */
372 /* if seq is beyond ual1->nextseq we have lost a segment */
373 if (GT_SEQ(seq, ual1->nextseq)) {
374 struct tcp_acked *ta;
376 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
377 ta->flags|=TCP_A_LOST_PACKET;
379 /* just add the segment to the beginning of the list */
380 ual=g_mem_chunk_alloc(tcp_unacked_chunk);
382 ual->frame=pinfo->fd->num;
387 ual->nextseq=seq+seglen;
388 ual->ts.secs=pinfo->fd->abs_secs;
389 ual->ts.nsecs=pinfo->fd->abs_usecs*1000;
395 /* keep-alives are empty semgents with a sequence number -1 of what
398 if( (!seglen) && EQ_SEQ(seq, (ual1->nextseq-1)) ){
399 struct tcp_acked *ta;
401 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
402 ta->flags|=TCP_A_KEEP_ALIVE;
407 /* if this is an empty segment, just skip it all */
412 /* check if the sequence number is lower than expected, i.e. retransmission */
413 if( LT_SEQ(seq, ual1->nextseq )){
414 struct tcp_acked *ta;
416 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
417 ta->flags|=TCP_A_RETRANSMISSION;
419 /* did this segment contain any more data we havent seen yet?
420 * if so we can just increase nextseq
422 if(GT_SEQ((seq+seglen), ual1->nextseq)){
423 ual1->nextseq=seq+seglen;
424 ual1->frame=pinfo->fd->num;
425 ual1->ts.secs=pinfo->fd->abs_secs;
426 ual1->ts.nsecs=pinfo->fd->abs_usecs*1000;
431 /* just add the segment to the beginning of the list */
432 ual=g_mem_chunk_alloc(tcp_unacked_chunk);
434 ual->frame=pinfo->fd->num;
439 ual->nextseq=seq+seglen;
440 ual->ts.secs=pinfo->fd->abs_secs;
441 ual->ts.nsecs=pinfo->fd->abs_usecs*1000;
448 /* handle the ack numbers */
450 /* if we dont have the ack flag its not much we can do */
451 if( !(flags&TH_ACK)){
455 /* if we havent seen anything yet in the other direction we dont
456 * know what this one acks */
461 /* if we dont have any real segments in the other direction not
462 * acked yet (as we see from the magic frame==0 entry)
463 * then there is no point in continuing
469 /* if we get here we know ual2 is valid */
471 /* if we are acking beyong what we have seen in the other direction
472 * we must have lost packets. Not much point in keeping the segments
473 * in the other direction either.
475 if( GT_SEQ(ack, ual2->nextseq )){
476 struct tcp_acked *ta;
478 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
479 ta->flags|=TCP_A_ACK_LOST_PACKET;
480 for(ual=ual2;ual2;ual2=ual){
482 g_mem_chunk_free(tcp_unacked_chunk, ual2);
488 /* does this ACK ack all semgents we have seen in the other direction?*/
489 if( EQ_SEQ(ack, ual2->nextseq )){
490 struct tcp_acked *ta;
492 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
493 ta->frame_acked=ual2->frame;
494 ta->ts.secs=pinfo->fd->abs_secs-ual2->ts.secs;
495 ta->ts.nsecs=pinfo->fd->abs_usecs*1000-ual2->ts.nsecs;
497 ta->ts.nsecs+=1000000000;
501 /* its all been ACKed so we dont need to keep them anymore */
502 for(ual=ual2;ual2;ual2=ual){
504 g_mem_chunk_free(tcp_unacked_chunk, ual2);
509 /* ok it only ACKs part of what we have seen. Find out how much
510 * update and remove the ACKed segments
512 for(ual=ual2;ual->next;ual=ual->next){
513 if( GE_SEQ(ack, ual->next->nextseq)){
518 struct tcp_unacked *tmpual=NULL;
519 struct tcp_unacked *ackedual=NULL;
520 struct tcp_acked *ta;
525 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
526 ta->frame_acked=ackedual->frame;
527 ta->ts.secs=pinfo->fd->abs_secs-ackedual->ts.secs;
528 ta->ts.nsecs=pinfo->fd->abs_usecs*1000-ackedual->ts.nsecs;
530 ta->ts.nsecs+=1000000000;
534 /* just delete all ACKed segments */
537 for(ual=tmpual;ual;ual=tmpual){
539 g_mem_chunk_free(tcp_unacked_chunk, ual);
545 /* we might have deleted the entire ual2 list, if this is an ACK,
546 make sure ual2 at least has a dummy entry for the current ACK */
547 if( (!ual2) && (flags&TH_ACK) ){
548 ual2=g_mem_chunk_alloc(tcp_unacked_chunk);
561 /* update the ACK counter and check for
563 /* go to the oldest segment in the list of segments
564 in the other direction */
565 /* XXX we should guarantee ual2 to always be non NULL here
566 so we can skip the ual/ual2 tests */
567 for(ual=ual2;ual&&ual->next;ual=ual->next)
570 /* we only consider this being a potential duplicate ack
571 if the segment length is 0 (ack only segment)
572 and if it acks something previous to oldest segment
573 in the other direction */
574 if((!seglen)&&LE_SEQ(ack,ual->seq)){
575 /* if this is the first ack to keep track of, it is not
577 if(ual->num_acks==0){
579 ual->ack_frame=pinfo->fd->num;
581 /* if this ack is different, store this one
582 instead and forget the previous one(s) */
583 } else if(ual->ack!=ack){
585 ual->ack_frame=pinfo->fd->num;
587 /* this has to be a duplicate ack */
592 /* ok we have found a potential duplicate ack */
594 struct tcp_acked *ta;
595 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
596 ta->flags|=TCP_A_DUPLICATE_ACK;
603 /* check for zero window probes
604 a zero window probe is when a TCP tries to write 1 byte segments
605 where the remote side has advertised a window of 0 bytes.
606 We only do this check if we actually have seen anything from the
607 other side of this connection.
609 We also assume ual still points to the last entry in the ual2
610 list from the section above.
612 At the same time, check for violations, i.e. attempts to write >1
613 byte to a zero-window.
615 /* XXX we should not need to do the ual->frame check here?
616 might be a bug somewhere. look for it later .
618 if(ual2&&(ual->frame)){
619 if((seglen==1)&&(ual->window==0)){
620 struct tcp_acked *ta;
621 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
622 ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
624 if((seglen>1)&&(ual->window==0)){
625 struct tcp_acked *ta;
626 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
627 ta->flags|=TCP_A_ZERO_WINDOW_VIOLATION;
631 /* check for zero window */
633 struct tcp_acked *ta;
634 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE);
635 ta->flags|=TCP_A_ZERO_WINDOW;
639 /* store the lists back in our struct */
642 * XXX - if direction == 0, that'll be true for packets
643 * from both sides of the connection, so this won't
646 * That'd be a connection from a given port on a machine
647 * to that same port on the same machine; does that ever
652 tcpd->base_seq1=base_seq;
656 tcpd->base_seq2=base_seq;
660 if(tcp_relative_seq){
661 struct tcp_rel_seq *trs;
662 /* remember relative seq/ack number base for this packet */
663 trs=g_mem_chunk_alloc(tcp_rel_seq_chunk);
664 trs->seq_base=base_seq;
665 trs->ack_base=base_ack;
666 g_hash_table_insert(tcp_rel_seq_table, (void *)pinfo->fd->num, trs);
671 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree)
673 struct tcp_acked *ta;
677 ta=tcp_analyze_get_acked_struct(pinfo->fd->num, FALSE);
682 item=proto_tree_add_text(parent_tree, tvb, 0, 0, "SEQ/ACK analysis");
683 tree=proto_item_add_subtree(item, ett_tcp_analysis);
685 /* encapsulate all proto_tree_add_xxx in ifs so we only print what
686 data we actually have */
688 proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
689 tvb, 0, 0, ta->frame_acked);
691 if( ta->ts.secs || ta->ts.nsecs ){
692 proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
697 proto_item *flags_item=NULL;
698 proto_tree *flags_tree=NULL;
700 flags_item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, -1, FALSE);
701 flags_tree=proto_item_add_subtree(flags_item, ett_tcp_analysis);
702 if( ta->flags&TCP_A_RETRANSMISSION ){
703 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
704 if(check_col(pinfo->cinfo, COL_INFO)){
705 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
708 if( ta->flags&TCP_A_LOST_PACKET ){
709 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_lost_packet, tvb, 0, 0, "A segment before this frame was lost");
710 if(check_col(pinfo->cinfo, COL_INFO)){
711 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] ");
714 if( ta->flags&TCP_A_ACK_LOST_PACKET ){
715 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_ack_lost_packet, tvb, 0, 0, "This frame ACKs a segment we have not seen (lost?)");
716 if(check_col(pinfo->cinfo, COL_INFO)){
717 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] ");
720 if( ta->flags&TCP_A_KEEP_ALIVE ){
721 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive, tvb, 0, 0, "This is a TCP keep-alive segment");
722 if(check_col(pinfo->cinfo, COL_INFO)){
723 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
726 if( ta->flags&TCP_A_DUPLICATE_ACK ){
727 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_duplicate_ack, tvb, 0, 0, "This is a TCP duplicate ack");
728 if(check_col(pinfo->cinfo, COL_INFO)){
729 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Duplicate ACK] ");
732 if( ta->flags&TCP_A_ZERO_WINDOW_PROBE ){
733 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_probe, tvb, 0, 0, "This is a TCP zero-window-probe");
734 if(check_col(pinfo->cinfo, COL_INFO)){
735 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
738 if( ta->flags&TCP_A_ZERO_WINDOW ){
739 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window, tvb, 0, 0, "This is a ZeroWindow segment");
740 if(check_col(pinfo->cinfo, COL_INFO)){
741 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
744 if( ta->flags&TCP_A_ZERO_WINDOW_VIOLATION ){
745 proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_violation, tvb, 0, 0, "This is a ZeroWindow violation, attempts to write >1 byte of data to a zero-window");
746 if(check_col(pinfo->cinfo, COL_INFO)){
747 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowViolation] ");
755 /* Do we still need to do this ...remove_all() even though we dont need
756 * to do anything special? The glib docs are not clear on this and
757 * its better safe than sorry
760 free_all_acked(gpointer key_arg _U_, gpointer value _U_, gpointer user_data _U_)
766 tcp_acked_hash(gconstpointer k)
768 guint32 frame = (guint32)k;
773 tcp_acked_equal(gconstpointer k1, gconstpointer k2)
775 guint32 frame1 = (guint32)k1;
776 guint32 frame2 = (guint32)k2;
778 return frame1==frame2;
782 tcp_analyze_seq_init(void)
784 /* first destroy the tables */
785 if( tcp_analyze_acked_table ){
786 g_hash_table_foreach_remove(tcp_analyze_acked_table,
787 free_all_acked, NULL);
788 g_hash_table_destroy(tcp_analyze_acked_table);
789 tcp_analyze_acked_table = NULL;
791 if( tcp_rel_seq_table ){
792 g_hash_table_foreach_remove(tcp_rel_seq_table,
793 free_all_acked, NULL);
794 g_hash_table_destroy(tcp_rel_seq_table);
795 tcp_rel_seq_table = NULL;
799 * Now destroy the chunk from which the conversation table
800 * structures were allocated.
802 if (tcp_analysis_chunk) {
803 g_mem_chunk_destroy(tcp_analysis_chunk);
804 tcp_analysis_chunk = NULL;
806 if (tcp_unacked_chunk) {
807 g_mem_chunk_destroy(tcp_unacked_chunk);
808 tcp_unacked_chunk = NULL;
810 if (tcp_acked_chunk) {
811 g_mem_chunk_destroy(tcp_acked_chunk);
812 tcp_acked_chunk = NULL;
814 if (tcp_rel_seq_chunk) {
815 g_mem_chunk_destroy(tcp_rel_seq_chunk);
816 tcp_rel_seq_chunk = NULL;
820 tcp_analyze_acked_table = g_hash_table_new(tcp_acked_hash,
822 tcp_rel_seq_table = g_hash_table_new(tcp_acked_hash,
824 tcp_analysis_chunk = g_mem_chunk_new("tcp_analysis_chunk",
825 sizeof(struct tcp_analysis),
826 tcp_analysis_count * sizeof(struct tcp_analysis),
828 tcp_unacked_chunk = g_mem_chunk_new("tcp_unacked_chunk",
829 sizeof(struct tcp_unacked),
830 tcp_unacked_count * sizeof(struct tcp_unacked),
832 tcp_acked_chunk = g_mem_chunk_new("tcp_acked_chunk",
833 sizeof(struct tcp_acked),
834 tcp_acked_count * sizeof(struct tcp_acked),
836 if(tcp_relative_seq){
837 tcp_rel_seq_chunk = g_mem_chunk_new("tcp_rel_seq_chunk",
838 sizeof(struct tcp_rel_seq),
839 tcp_rel_seq_count * sizeof(struct tcp_rel_seq),
846 /* **************************************************************************
847 * End of tcp sequence number analysis
848 * **************************************************************************/
853 /* Minimum TCP header length. */
854 #define TCPH_MIN_LEN 20
860 #define TCPOPT_NOP 1 /* Padding */
861 #define TCPOPT_EOL 0 /* End of options */
862 #define TCPOPT_MSS 2 /* Segment size negotiating */
863 #define TCPOPT_WINDOW 3 /* Window scaling */
864 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
865 #define TCPOPT_SACK 5 /* SACK Block */
866 #define TCPOPT_ECHO 6
867 #define TCPOPT_ECHOREPLY 7
868 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
870 #define TCPOPT_CCNEW 12
871 #define TCPOPT_CCECHO 13
872 #define TCPOPT_MD5 19 /* RFC2385 */
878 #define TCPOLEN_MSS 4
879 #define TCPOLEN_WINDOW 3
880 #define TCPOLEN_SACK_PERM 2
881 #define TCPOLEN_SACK_MIN 2
882 #define TCPOLEN_ECHO 6
883 #define TCPOLEN_ECHOREPLY 6
884 #define TCPOLEN_TIMESTAMP 10
886 #define TCPOLEN_CCNEW 6
887 #define TCPOLEN_CCECHO 6
888 #define TCPOLEN_MD5 18
892 /* Desegmentation of TCP streams */
893 /* table to hold defragmented TCP streams */
894 static GHashTable *tcp_fragment_table = NULL;
896 tcp_fragment_init(void)
898 fragment_table_init(&tcp_fragment_table);
901 /* functions to trace tcp segments */
902 /* Enable desegmenting of TCP streams */
903 static gboolean tcp_desegment = FALSE;
905 static GHashTable *tcp_segment_table = NULL;
906 static GMemChunk *tcp_segment_key_chunk = NULL;
907 static int tcp_segment_init_count = 200;
908 static GMemChunk *tcp_segment_address_chunk = NULL;
909 static int tcp_segment_address_init_count = 500;
911 typedef struct _tcp_segment_key {
912 /* for own bookkeeping inside packet-tcp.c */
925 free_all_segments(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
927 tcp_segment_key *key = key_arg;
929 if((key->src)&&(key->src->data)){
930 g_free((gpointer)key->src->data);
934 if((key->dst)&&(key->dst->data)){
935 g_free((gpointer)key->dst->data);
943 tcp_segment_hash(gconstpointer k)
945 const tcp_segment_key *key = (const tcp_segment_key *)k;
947 return key->seq+key->sport;
951 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
953 const tcp_segment_key *key1 = (const tcp_segment_key *)k1;
954 const tcp_segment_key *key2 = (const tcp_segment_key *)k2;
956 return ( ( (key1->seq==key2->seq)
957 &&(ADDRESSES_EQUAL(key1->src, key2->src))
958 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
959 &&(key1->sport==key2->sport)
960 &&(key1->dport==key2->dport)
965 tcp_desegment_init(void)
968 * Free this before freeing any memory chunks; those
969 * chunks contain data we'll look at in "free_all_segments()".
971 if(tcp_segment_table){
972 g_hash_table_foreach_remove(tcp_segment_table,
973 free_all_segments, NULL);
974 g_hash_table_destroy(tcp_segment_table);
975 tcp_segment_table = NULL;
978 if(tcp_segment_key_chunk){
979 g_mem_chunk_destroy(tcp_segment_key_chunk);
980 tcp_segment_key_chunk = NULL;
982 if(tcp_segment_address_chunk){
983 g_mem_chunk_destroy(tcp_segment_address_chunk);
984 tcp_segment_address_chunk = NULL;
987 /* dont allocate any hash table or memory chunks unless the user
988 really uses this option
994 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
997 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
998 sizeof(tcp_segment_key),
999 tcp_segment_init_count*sizeof(tcp_segment_key),
1002 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
1004 tcp_segment_address_init_count*sizeof(address),
1009 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1010 guint32 seq, guint32 nxtseq,
1011 guint32 sport, guint32 dport,
1012 proto_tree *tree, proto_tree *tcp_tree)
1014 struct tcpinfo *tcpinfo = pinfo->private_data;
1015 fragment_data *ipfd_head=NULL;
1016 tcp_segment_key old_tsk, *tsk;
1017 gboolean must_desegment = FALSE;
1018 gboolean called_dissector = FALSE;
1024 * Initialize these to assume no desegmentation.
1025 * If that's not the case, these will be set appropriately
1026 * by the subdissector.
1028 pinfo->desegment_offset = 0;
1029 pinfo->desegment_len = 0;
1032 * Initialize this to assume that this segment will just be
1033 * added to the middle of a desegmented chunk of data, so
1034 * that we should show it all as data.
1035 * If that's not the case, it will be set appropriately.
1037 deseg_offset = offset;
1039 /* First we must check if this TCP segment should be desegmented.
1040 This is only to check if we should desegment this packet,
1041 so we dont spend time doing COPY_ADDRESS/g_free.
1042 We just "borrow" some address structures from pinfo instead. Cheaper.
1044 old_tsk.src = &pinfo->src;
1045 old_tsk.dst = &pinfo->dst;
1046 old_tsk.sport = sport;
1047 old_tsk.dport = dport;
1049 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1052 /* OK, this segment was found, which means it continues
1053 a higher-level PDU. This means we must desegment it.
1054 Add it to the defragmentation lists.
1056 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->first_frame,
1058 seq - tsk->start_seq,
1060 (LT_SEQ (nxtseq,tsk->start_seq + tsk->tot_len)) );
1063 /* fragment_add() returned NULL, This means that
1064 desegmentation is not completed yet.
1065 (its like defragmentation but we know we will
1066 always add the segments in order).
1067 XXX - no, we don't; there is no guarantee that
1068 TCP segments are in order on the wire.
1070 we must add next segment to our table so we will
1073 tcp_segment_key *new_tsk;
1075 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1076 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1077 new_tsk->seq=nxtseq;
1078 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1081 /* This segment was not found in our table, so it doesn't
1082 contain a continuation of a higher-level PDU.
1083 Call the normal subdissector.
1085 decode_tcp_ports(tvb, offset, pinfo, tree,
1087 called_dissector = TRUE;
1089 /* Did the subdissector ask us to desegment some more data
1090 before it could handle the packet?
1091 If so we have to create some structures in our table but
1092 this is something we only do the first time we see this
1095 if(pinfo->desegment_len) {
1096 if (!pinfo->fd->flags.visited)
1097 must_desegment = TRUE;
1100 * Set "deseg_offset" to the offset in "tvb"
1101 * of the first byte of data that the
1102 * subdissector didn't process.
1104 deseg_offset = offset + pinfo->desegment_offset;
1107 /* Either no desegmentation is necessary, or this is
1108 segment contains the beginning but not the end of
1109 a higher-level PDU and thus isn't completely
1115 /* is it completely desegmented? */
1117 fragment_data *ipfd;
1120 * Yes, we think it is.
1121 * We only call subdissector for the last segment.
1122 * Note that the last segment may include more than what
1125 if(GE_SEQ(nxtseq, tsk->start_seq + tsk->tot_len)){
1127 * OK, this is the last segment.
1128 * Let's call the subdissector with the desegmented
1134 /* create a new TVB structure for desegmented data */
1135 next_tvb = tvb_new_real_data(ipfd_head->data,
1136 ipfd_head->datalen, ipfd_head->datalen);
1138 /* add this tvb as a child to the original one */
1139 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
1141 /* add desegmented data to the data source list */
1142 add_new_data_source(pinfo, next_tvb, "Desegmented");
1145 * Supply the sequence number of the first of the
1146 * reassembled bytes.
1148 tcpinfo->seq = tsk->start_seq;
1150 /* indicate that this is reassembled data */
1151 tcpinfo->is_reassembled = TRUE;
1153 /* call subdissector */
1154 decode_tcp_ports(next_tvb, 0, pinfo, tree,
1156 called_dissector = TRUE;
1159 * OK, did the subdissector think it was completely
1160 * desegmented, or does it think we need even more
1163 old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
1164 if(pinfo->desegment_len &&
1165 pinfo->desegment_offset<=old_len){
1166 tcp_segment_key *new_tsk;
1169 * "desegment_len" isn't 0, so it needs more
1170 * data for something - and "desegment_offset"
1171 * is before "old_len", so it needs more data
1172 * to dissect the stuff we thought was
1173 * completely desegmented (as opposed to the
1174 * stuff at the beginning being completely
1175 * desegmented, but the stuff at the end
1176 * being a new higher-level PDU that also
1177 * needs desegmentation).
1179 fragment_set_partial_reassembly(pinfo,tsk->first_frame,tcp_fragment_table);
1180 tsk->tot_len = tvb_reported_length(next_tvb) + pinfo->desegment_len;
1183 * Update tsk structure.
1184 * Can ask ->next->next because at least there's a hdr and one
1185 * entry in fragment_add()
1187 for(ipfd=ipfd_head->next; ipfd->next; ipfd=ipfd->next){
1188 old_tsk.seq = tsk->start_seq + ipfd->offset;
1189 new_tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
1190 new_tsk->tot_len = tsk->tot_len;
1193 /* this is the next segment in the sequence we want */
1194 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1195 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1196 new_tsk->seq = nxtseq;
1197 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1200 * Show the stuff in this TCP segment as
1201 * just raw TCP segment data.
1204 tvb_reported_length_remaining(tvb, offset);
1205 proto_tree_add_text(tcp_tree, tvb, offset, -1,
1206 "TCP segment data (%u byte%s)", nbytes,
1207 plurality(nbytes, "", "s"));
1210 * The subdissector thought it was completely
1211 * desegmented (although the stuff at the
1212 * end may, in turn, require desegmentation),
1213 * so we show a tree with all segments.
1215 show_fragment_tree(ipfd_head, &tcp_segment_items,
1216 tcp_tree, pinfo, next_tvb);
1218 /* Did the subdissector ask us to desegment
1219 some more data? This means that the data
1220 at the beginning of this segment completed
1221 a higher-level PDU, but the data at the
1222 end of this segment started a higher-level
1223 PDU but didn't complete it.
1225 If so, we have to create some structures
1226 in our table, but this is something we
1227 only do the first time we see this packet.
1229 if(pinfo->desegment_len) {
1230 if (!pinfo->fd->flags.visited)
1231 must_desegment = TRUE;
1233 /* The stuff we couldn't dissect
1234 must have come from this segment,
1235 so it's all in "tvb".
1237 "pinfo->desegment_offset" is
1238 relative to the beginning of
1239 "next_tvb"; we want an offset
1240 relative to the beginning of "tvb".
1242 First, compute the offset relative
1243 to the *end* of "next_tvb" - i.e.,
1244 the number of bytes before the end
1245 of "next_tvb" at which the
1246 subdissector stopped. That's the
1247 length of "next_tvb" minus the
1248 offset, relative to the beginning
1249 of "next_tvb, at which the
1250 subdissector stopped.
1253 ipfd_head->datalen - pinfo->desegment_offset;
1255 /* "tvb" and "next_tvb" end at the
1256 same byte of data, so the offset
1257 relative to the end of "next_tvb"
1258 of the byte at which we stopped
1259 is also the offset relative to
1260 the end of "tvb" of the byte at
1263 Convert that back into an offset
1264 relative to the beginninng of
1265 "tvb", by taking the length of
1266 "tvb" and subtracting the offset
1267 relative to the end.
1269 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
1275 if (must_desegment) {
1276 tcp_segment_key *tsk, *new_tsk;
1279 * The sequence number at which the stuff to be desegmented
1280 * starts is the sequence number of the byte at an offset
1281 * of "deseg_offset" into "tvb".
1283 * The sequence number of the byte at an offset of "offset"
1284 * is "seq", i.e. the starting sequence number of this
1285 * segment, so the sequence number of the byte at
1286 * "deseg_offset" is "seq + (deseg_offset - offset)".
1288 deseg_seq = seq + (deseg_offset - offset);
1291 * XXX - how do we detect out-of-order transmissions?
1292 * We can't just check for "nxtseq" being greater than
1293 * "tsk->start_seq"; for now, we check for the difference
1294 * being less than a megabyte, but this is a really
1295 * gross hack - we really need to handle out-of-order
1296 * transmissions correctly.
1298 if ((nxtseq - deseg_seq) <= 1024*1024) {
1299 /* OK, subdissector wants us to desegment
1300 some data before it can process it. Add
1301 what remains of this packet and set
1302 up next packet/sequence number as well.
1304 We must remember this segment
1306 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1307 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
1308 COPY_ADDRESS(tsk->src, &pinfo->src);
1309 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
1310 COPY_ADDRESS(tsk->dst, &pinfo->dst);
1311 tsk->seq = deseg_seq;
1312 tsk->start_seq = tsk->seq;
1313 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
1314 tsk->first_frame = pinfo->fd->num;
1317 g_hash_table_insert(tcp_segment_table, tsk, tsk);
1319 /* Add portion of segment unprocessed by the subdissector
1320 to defragmentation lists */
1321 fragment_add(tvb, deseg_offset, pinfo, tsk->first_frame,
1323 tsk->seq - tsk->start_seq,
1324 nxtseq - tsk->start_seq,
1325 LT_SEQ (nxtseq, tsk->start_seq + tsk->tot_len));
1327 /* this is the next segment in the sequence we want */
1328 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
1329 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
1330 new_tsk->seq = nxtseq;
1331 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
1335 if (!called_dissector || pinfo->desegment_len != 0) {
1337 * Either we didn't call the subdissector at all (i.e.,
1338 * this is a segment that contains the middle of a
1339 * higher-level PDU, but contains neither the beginning
1340 * nor the end), or the subdissector couldn't dissect it
1341 * all, as some data was missing (i.e., it set
1342 * "pinfo->desegment_len" to the amount of additional
1345 if (pinfo->desegment_offset == 0) {
1347 * It couldn't, in fact, dissect any of it (the
1348 * first byte it couldn't dissect is at an offset
1349 * of "pinfo->desegment_offset" from the beginning
1350 * of the payload, and that's 0).
1351 * Just mark this as TCP.
1353 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1354 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1356 if (check_col(pinfo->cinfo, COL_INFO)){
1357 col_set_str(pinfo->cinfo, COL_INFO, "[Desegmented TCP]");
1362 * Show what's left in the packet as just raw TCP segment
1364 * XXX - remember what protocol the last subdissector
1365 * was, and report it as a continuation of that, instead?
1367 nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
1368 proto_tree_add_text(tcp_tree, tvb, deseg_offset, -1,
1369 "TCP segment data (%u byte%s)", nbytes,
1370 plurality(nbytes, "", "s"));
1372 pinfo->can_desegment=0;
1373 pinfo->desegment_offset = 0;
1374 pinfo->desegment_len = 0;
1378 * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
1379 * consists of a fixed-length chunk of data that contains enough information
1380 * to determine the length of the PDU, followed by rest of the PDU.
1382 * The first three arguments are the arguments passed to the dissector
1383 * that calls this routine.
1385 * "proto_desegment" is the dissector's flag controlling whether it should
1386 * desegment PDUs that cross TCP segment boundaries.
1388 * "fixed_len" is the length of the fixed-length part of the PDU.
1390 * "get_pdu_len()" is a routine called to get the length of the PDU from
1391 * the fixed-length part of the PDU; it's passed "tvb" and "offset".
1393 * "dissect_pdu()" is the routine to dissect a PDU.
1396 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1397 gboolean proto_desegment, guint fixed_len,
1398 guint (*get_pdu_len)(tvbuff_t *, int),
1399 void (*dissect_pdu)(tvbuff_t *, packet_info *, proto_tree *))
1401 volatile int offset = 0;
1403 guint length_remaining;
1408 while (tvb_reported_length_remaining(tvb, offset) != 0) {
1410 * We use "tvb_ensure_length_remaining()" to make sure there actually
1411 * *is* data remaining. The protocol we're handling could conceivably
1412 * consists of a sequence of fixed-length PDUs, and therefore the
1413 * "get_pdu_len" routine might not actually fetch anything from
1414 * the tvbuff, and thus might not cause an exception to be thrown if
1415 * we've run past the end of the tvbuff.
1417 * This means we're guaranteed that "length_remaining" is positive.
1419 length_remaining = tvb_ensure_length_remaining(tvb, offset);
1422 * Can we do reassembly?
1424 if (proto_desegment && pinfo->can_desegment) {
1426 * Yes - is the fixed-length part of the PDU split across segment
1429 if (length_remaining < fixed_len) {
1431 * Yes. Tell the TCP dissector where the data for this message
1432 * starts in the data it handed us, and how many more bytes we
1435 pinfo->desegment_offset = offset;
1436 pinfo->desegment_len = fixed_len - length_remaining;
1442 * Get the length of the PDU.
1444 plen = (*get_pdu_len)(tvb, offset);
1445 if (plen < fixed_len) {
1447 * The PDU length from the fixed-length portion probably didn't
1448 * include the fixed-length portion's length, and was probably so
1449 * large that the total length overflowed.
1451 * Report this as an error.
1453 show_reported_bounds_error(tvb, pinfo, tree);
1458 * Can we do reassembly?
1460 if (proto_desegment && pinfo->can_desegment) {
1462 * Yes - is the PDU split across segment boundaries?
1464 if (length_remaining < plen) {
1466 * Yes. Tell the TCP dissector where the data for this message
1467 * starts in the data it handed us, and how many more bytes we
1470 pinfo->desegment_offset = offset;
1471 pinfo->desegment_len = plen - length_remaining;
1477 * Construct a tvbuff containing the amount of the payload we have
1478 * available. Make its reported length the amount of data in the PDU.
1480 * XXX - if reassembly isn't enabled. the subdissector will throw a
1481 * BoundsError exception, rather than a ReportedBoundsError exception.
1482 * We really want a tvbuff where the length is "length", the reported
1483 * length is "plen", and the "if the snapshot length were infinite"
1484 * length is the minimum of the reported length of the tvbuff handed
1485 * to us and "plen", with a new type of exception thrown if the offset
1486 * is within the reported length but beyond that third length, with
1487 * that exception getting the "Unreassembled Packet" error.
1489 length = length_remaining;
1492 next_tvb = tvb_new_subset(tvb, offset, length, plen);
1497 * Catch the ReportedBoundsError exception; if this particular message
1498 * happens to get a ReportedBoundsError exception, that doesn't mean
1499 * that we should stop dissecting PDUs within this frame or chunk of
1502 * If it gets a BoundsError, we can stop, as there's nothing more to
1503 * see, so we just re-throw it.
1506 (*dissect_pdu)(next_tvb, pinfo, tree);
1508 CATCH(BoundsError) {
1511 CATCH(ReportedBoundsError) {
1512 show_reported_bounds_error(tvb, pinfo, tree);
1517 * Step to the next PDU.
1518 * Make sure we don't overflow.
1520 offset_before = offset;
1522 if (offset <= offset_before)
1528 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
1530 if (check_col(pinfo->cinfo, COL_INFO))
1531 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
1535 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
1536 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1540 mss = tvb_get_ntohs(tvb, offset + 2);
1541 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_mss, tvb, offset,
1543 proto_tree_add_uint_format(opt_tree, hf_tcp_option_mss_val, tvb, offset,
1544 optlen, mss, "%s: %u bytes", optp->name, mss);
1545 tcp_info_append_uint(pinfo, "MSS", mss);
1549 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
1550 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1554 ws = tvb_get_guint8(tvb, offset + 2);
1555 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_wscale, tvb,
1556 offset, optlen, TRUE);
1557 proto_tree_add_uint_format(opt_tree, hf_tcp_option_wscale_val, tvb,
1558 offset, optlen, ws, "%s: %u (multiply by %u)",
1559 optp->name, ws, 1 << ws);
1560 tcp_info_append_uint(pinfo, "WS", ws);
1564 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
1565 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1567 proto_tree *field_tree = NULL;
1569 guint leftedge, rightedge;
1571 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
1572 offset += 2; /* skip past type and length */
1573 optlen -= 2; /* subtract size of type and length */
1574 while (optlen > 0) {
1575 if (field_tree == NULL) {
1576 /* Haven't yet made a subtree out of this option. Do so. */
1577 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1578 proto_tree_add_boolean_hidden(field_tree, hf_tcp_option_sack, tvb,
1579 offset, optlen, TRUE);
1582 proto_tree_add_text(field_tree, tvb, offset, optlen,
1583 "(suboption would go past end of option)");
1586 leftedge = tvb_get_ntohl(tvb, offset);
1587 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
1588 offset, 4, leftedge,
1589 "left edge = %u", leftedge);
1592 proto_tree_add_text(field_tree, tvb, offset, optlen,
1593 "(suboption would go past end of option)");
1596 /* XXX - check whether it goes past end of packet */
1597 rightedge = tvb_get_ntohl(tvb, offset + 4);
1599 proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
1600 offset+4, 4, rightedge,
1601 "right edge = %u", rightedge);
1602 tcp_info_append_uint(pinfo, "SLE", leftedge);
1603 tcp_info_append_uint(pinfo, "SRE", rightedge);
1609 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
1610 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1614 echo = tvb_get_ntohl(tvb, offset + 2);
1615 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_echo, tvb, offset,
1617 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1618 "%s: %u", optp->name, echo);
1619 tcp_info_append_uint(pinfo, "ECHO", echo);
1623 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
1624 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1628 tsv = tvb_get_ntohl(tvb, offset + 2);
1629 tser = tvb_get_ntohl(tvb, offset + 6);
1630 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_time_stamp, tvb,
1631 offset, optlen, TRUE);
1632 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1633 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
1634 tcp_info_append_uint(pinfo, "TSV", tsv);
1635 tcp_info_append_uint(pinfo, "TSER", tser);
1639 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
1640 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
1644 cc = tvb_get_ntohl(tvb, offset + 2);
1645 proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_cc, tvb, offset,
1647 proto_tree_add_text(opt_tree, tvb, offset, optlen,
1648 "%s: %u", optp->name, cc);
1649 tcp_info_append_uint(pinfo, "CC", cc);
1652 static const ip_tcp_opt tcpopts[] = {
1671 "Maximum segment size",
1675 dissect_tcpopt_maxseg
1683 dissect_tcpopt_wscale
1696 &ett_tcp_option_sack,
1723 dissect_tcpopt_timestamp
1751 "TCP MD5 signature",
1759 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
1761 /* Determine if there is a sub-dissector and call it. This has been */
1762 /* separated into a stand alone routine to other protocol dissectors */
1763 /* can call to it, ie. socks */
1766 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
1767 proto_tree *tree, int src_port, int dst_port)
1770 int low_port, high_port;
1772 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1774 /* determine if this packet is part of a conversation and call dissector */
1775 /* for the conversation if available */
1777 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
1778 src_port, dst_port, next_tvb, pinfo, tree))
1781 /* Do lookups with the subdissector table.
1782 We try the port number with the lower value first, followed by the
1783 port number with the higher value. This means that, for packets
1784 where a dissector is registered for *both* port numbers:
1786 1) we pick the same dissector for traffic going in both directions;
1788 2) we prefer the port number that's more likely to be the right
1789 one (as that prefers well-known ports to reserved ports);
1791 although there is, of course, no guarantee that any such strategy
1792 will always pick the right port number.
1794 XXX - we ignore port numbers of 0, as some dissectors use a port
1795 number of 0 to disable the port. */
1796 if (src_port > dst_port) {
1797 low_port = dst_port;
1798 high_port = src_port;
1800 low_port = src_port;
1801 high_port = dst_port;
1803 if (low_port != 0 &&
1804 dissector_try_port(subdissector_table, low_port, next_tvb, pinfo, tree))
1806 if (high_port != 0 &&
1807 dissector_try_port(subdissector_table, high_port, next_tvb, pinfo, tree))
1810 /* do lookup with the heuristic subdissector table */
1811 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
1814 /* Oh, well, we don't know this; dissect it as data. */
1815 call_dissector(data_handle,next_tvb, pinfo, tree);
1820 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1822 guint8 th_off_x2; /* combines th_off and th_x2 */
1825 proto_tree *tcp_tree = NULL, *field_tree = NULL;
1826 proto_item *ti = NULL, *tf;
1828 gchar flags[64] = "<None>";
1829 gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
1837 guint16 computed_cksum;
1838 guint length_remaining;
1839 gboolean desegment_ok;
1840 struct tcpinfo tcpinfo;
1841 gboolean save_fragmented;
1842 static struct tcpheader tcphstruct[4], *tcph;
1843 static int tcph_count=0;
1849 tcph=&tcphstruct[tcph_count];
1850 /* XXX add to ipv6 so this works for that protocol as well */
1851 tcph->ip_header=pinfo->private_data;
1853 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1854 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
1856 /* Clear out the Info column. */
1857 if (check_col(pinfo->cinfo, COL_INFO))
1858 col_clear(pinfo->cinfo, COL_INFO);
1860 tcph->th_sport = tvb_get_ntohs(tvb, offset);
1861 tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
1862 if (check_col(pinfo->cinfo, COL_INFO)) {
1863 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
1864 get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
1867 if (tcp_summary_in_tree) {
1868 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
1869 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
1870 get_tcp_port(tcph->th_sport), tcph->th_sport,
1871 get_tcp_port(tcph->th_dport), tcph->th_dport);
1874 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
1876 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
1877 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
1878 "Source port: %s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
1879 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
1880 "Destination port: %s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
1881 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
1882 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
1885 /* Set the source and destination port numbers as soon as we get them,
1886 so that they're available to the "Follow TCP Stream" code even if
1887 we throw an exception dissecting the rest of the TCP header. */
1888 pinfo->ptype = PT_TCP;
1889 pinfo->srcport = tcph->th_sport;
1890 pinfo->destport = tcph->th_dport;
1892 tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
1893 tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
1894 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
1895 tcph->th_flags = tvb_get_guint8(tvb, offset + 13);
1896 tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
1897 tcph->th_hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
1899 reported_len = tvb_reported_length(tvb);
1901 /* Compute the length of data in this segment. */
1902 tcph->th_seglen = reported_len - tcph->th_hlen;
1904 if (tree) { /* Add the seglen as an invisible field */
1906 proto_tree_add_uint_hidden(ti, hf_tcp_len, tvb, offset, 4, tcph->th_seglen);
1910 /* handle TCP seq# analysis parse all new segments we see */
1911 if(tcp_analyze_seq){
1912 if(!(pinfo->fd->flags.visited)){
1913 tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win);
1915 if(tcp_relative_seq){
1916 tcp_get_relative_seq_ack(pinfo->fd->num, &(tcph->th_seq), &(tcph->th_ack));
1921 /* Compute the sequence number of next octet after this segment. */
1922 nxtseq = tcph->th_seq + tcph->th_seglen;
1924 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
1925 for (i = 0; i < 8; i++) {
1927 if (tcph->th_flags & bpos) {
1929 strcpy(&flags[fpos], ", ");
1932 strcpy(&flags[fpos], fstr[i]);
1939 if (check_col(pinfo->cinfo, COL_INFO)) {
1940 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
1941 flags, tcph->th_seq, tcph->th_ack, tcph->th_win);
1945 if (tcp_summary_in_tree)
1946 proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
1947 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
1950 if (tcph->th_hlen < TCPH_MIN_LEN) {
1951 /* Give up at this point; we put the source and destination port in
1952 the tree, before fetching the header length, so that they'll
1953 show up if this is in the failing packet in an ICMP error packet,
1954 but it's now time to give up if the header length is bogus. */
1955 if (check_col(pinfo->cinfo, COL_INFO))
1956 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
1957 tcph->th_hlen, TCPH_MIN_LEN);
1959 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
1960 "Header length: %u bytes (bogus, must be at least %u)", tcph->th_hlen,
1967 if (tcp_summary_in_tree)
1968 proto_item_append_text(ti, ", Ack: %u, Len: %u", tcph->th_ack, tcph->th_seglen);
1969 proto_item_set_len(ti, tcph->th_hlen);
1970 if (nxtseq != tcph->th_seq)
1971 proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
1972 if (tcph->th_flags & TH_ACK)
1973 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
1974 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
1975 "Header length: %u bytes", tcph->th_hlen);
1976 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
1977 tcph->th_flags, "Flags: 0x%04x (%s)", tcph->th_flags, flags);
1978 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
1979 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
1980 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
1981 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
1982 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
1983 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
1984 proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
1985 proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
1986 proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
1987 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
1990 /* Supply the sequence number of the first byte. */
1991 tcpinfo.seq = tcph->th_seq;
1993 /* Assume we'll pass un-reassembled data to subdissectors. */
1994 tcpinfo.is_reassembled = FALSE;
1996 pinfo->private_data = &tcpinfo;
1999 * Assume, initially, that we can't desegment.
2001 pinfo->can_desegment = 0;
2002 th_sum = tvb_get_ntohs(tvb, offset + 16);
2003 if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
2004 /* The packet isn't part of an un-reassembled fragmented datagram
2005 and isn't truncated. This means we have all the data, and thus
2006 can checksum it and, unless it's being returned in an error
2007 packet, are willing to allow subdissectors to request reassembly
2010 if (tcp_check_checksum) {
2011 /* We haven't turned checksum checking off; checksum it. */
2013 /* Set up the fields of the pseudo-header. */
2014 cksum_vec[0].ptr = pinfo->src.data;
2015 cksum_vec[0].len = pinfo->src.len;
2016 cksum_vec[1].ptr = pinfo->dst.data;
2017 cksum_vec[1].len = pinfo->dst.len;
2018 cksum_vec[2].ptr = (const guint8 *)&phdr;
2019 switch (pinfo->src.type) {
2022 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
2023 cksum_vec[2].len = 4;
2027 phdr[0] = g_htonl(reported_len);
2028 phdr[1] = g_htonl(IP_PROTO_TCP);
2029 cksum_vec[2].len = 8;
2033 /* TCP runs only atop IPv4 and IPv6.... */
2034 g_assert_not_reached();
2037 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
2038 cksum_vec[3].len = reported_len;
2039 computed_cksum = in_cksum(&cksum_vec[0], 4);
2040 if (computed_cksum == 0) {
2041 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2042 offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
2044 /* Checksum is valid, so we're willing to desegment it. */
2045 desegment_ok = TRUE;
2047 proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
2048 offset + 16, 2, TRUE);
2049 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2050 offset + 16, 2, th_sum,
2051 "Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
2052 in_cksum_shouldbe(th_sum, computed_cksum));
2054 /* Checksum is invalid, so we're not willing to desegment it. */
2055 desegment_ok = FALSE;
2056 pinfo->noreassembly_reason = " (incorrect TCP checksum)";
2059 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2060 offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
2062 /* We didn't check the checksum, and don't care if it's valid,
2063 so we're willing to desegment it. */
2064 desegment_ok = TRUE;
2067 /* We don't have all the packet data, so we can't checksum it... */
2068 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
2069 offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
2071 /* ...and aren't willing to desegment it. */
2072 desegment_ok = FALSE;
2076 /* We're willing to desegment this. Is desegmentation enabled? */
2077 if (tcp_desegment) {
2078 /* Yes - is this segment being returned in an error packet? */
2079 if (!pinfo->in_error_pkt) {
2080 /* No - indicate that we will desegment.
2081 We do NOT want to desegment segments returned in error
2082 packets, as they're not part of a TCP connection. */
2083 pinfo->can_desegment = 2;
2088 if (tcph->th_flags & TH_URG) {
2089 th_urp = tvb_get_ntohs(tvb, offset + 18);
2090 /* Export the urgent pointer, for the benefit of protocols such as
2092 tcpinfo.urgent = TRUE;
2093 tcpinfo.urgent_pointer = th_urp;
2094 if (check_col(pinfo->cinfo, COL_INFO))
2095 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
2096 if (tcp_tree != NULL)
2097 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
2099 tcpinfo.urgent = FALSE;
2101 if (check_col(pinfo->cinfo, COL_INFO))
2102 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
2104 /* Decode TCP options, if any. */
2105 if (tree && tcph->th_hlen > TCPH_MIN_LEN) {
2106 /* There's more than just the fixed-length header. Decode the
2108 optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
2109 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
2110 "Options: (%u bytes)", optlen);
2111 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
2112 dissect_ip_tcp_options(tvb, offset + 20, optlen,
2113 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
2116 /* Skip over header + options */
2117 offset += tcph->th_hlen;
2119 /* Check the packet length to see if there's more data
2120 (it could be an ACK-only packet) */
2121 length_remaining = tvb_length_remaining(tvb, offset);
2123 if( data_out_file ) {
2124 reassemble_tcp( tcph->th_seq, /* sequence number */
2125 tcph->th_seglen, /* data length */
2126 tvb_get_ptr(tvb, offset, length_remaining), /* data */
2127 length_remaining, /* captured data length */
2128 ( tcph->th_flags & TH_SYN ), /* is syn set? */
2135 if (length_remaining != 0) {
2136 if (tcph->th_flags & TH_RST) {
2140 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
2142 * A TCP SHOULD allow a received RST segment to include data.
2145 * It has been suggested that a RST segment could contain
2146 * ASCII text that encoded and explained the cause of the
2147 * RST. No standard has yet been established for such
2150 * so for segments with RST we just display the data as text.
2152 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
2154 tvb_format_text(tvb, offset, length_remaining));
2156 /* Can we desegment this segment? */
2157 if (pinfo->can_desegment) {
2159 desegment_tcp(tvb, pinfo, offset, tcph->th_seq, nxtseq, tcph->th_sport, tcph->th_dport, tree, tcp_tree);
2161 /* No - just call the subdissector.
2162 Mark this as fragmented, so if somebody throws an exception,
2163 we don't report it as a malformed frame. */
2164 save_fragmented = pinfo->fragmented;
2165 pinfo->fragmented = TRUE;
2166 decode_tcp_ports(tvb, offset, pinfo, tree, tcph->th_sport, tcph->th_dport);
2167 pinfo->fragmented = save_fragmented;
2172 /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
2173 if(tcp_analyze_seq){
2174 tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree);
2176 tap_queue_packet(tcp_tap, pinfo, tcph);
2180 proto_register_tcp(void)
2182 static hf_register_info hf[] = {
2185 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
2189 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
2193 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
2197 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
2201 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
2205 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
2209 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
2213 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2216 { &hf_tcp_flags_cwr,
2217 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
2220 { &hf_tcp_flags_ecn,
2221 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
2224 { &hf_tcp_flags_urg,
2225 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
2228 { &hf_tcp_flags_ack,
2229 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
2232 { &hf_tcp_flags_push,
2233 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
2236 { &hf_tcp_flags_reset,
2237 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
2240 { &hf_tcp_flags_syn,
2241 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
2244 { &hf_tcp_flags_fin,
2245 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
2248 { &hf_tcp_window_size,
2249 { "Window size", "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
2253 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
2256 { &hf_tcp_checksum_bad,
2257 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2260 { &hf_tcp_analysis_flags,
2261 { "TCP Analysis Flags", "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
2262 "This frame has some of the TCP analysis flags set", HFILL }},
2264 { &hf_tcp_analysis_retransmission,
2265 { "Retransmission", "tcp.analysis.retransmission", FT_NONE, BASE_NONE, NULL, 0x0,
2266 "This frame is a suspected TCP retransmission", HFILL }},
2268 { &hf_tcp_analysis_lost_packet,
2269 { "Previous Segment Lost", "tcp.analysis.lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2270 "A segment before this one was lost from the capture", HFILL }},
2272 { &hf_tcp_analysis_ack_lost_packet,
2273 { "ACKed Lost Packet", "tcp.analysis.ack_lost_segment", FT_NONE, BASE_NONE, NULL, 0x0,
2274 "This frame ACKs a lost segment", HFILL }},
2276 { &hf_tcp_analysis_keep_alive,
2277 { "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
2278 "This is a keep-alive segment", HFILL }},
2280 { &hf_tcp_analysis_duplicate_ack,
2281 { "Duplicate ACK", "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
2282 "This is a duplicate ACK", HFILL }},
2284 { &hf_tcp_analysis_zero_window_violation,
2285 { "Zero Window Violation", "tcp.analysis.zero_window_violation", FT_NONE, BASE_NONE, NULL, 0x0,
2286 "This is a zero-window violation, an attempt to write >1 byte to a zero-window", HFILL }},
2288 { &hf_tcp_analysis_zero_window_probe,
2289 { "Zero Window Probe", "tcp.analysis.zero_window_probe", FT_NONE, BASE_NONE, NULL, 0x0,
2290 "This is a zero-window-probe", HFILL }},
2292 { &hf_tcp_analysis_zero_window,
2293 { "Zero Window", "tcp.analysis.zero_window", FT_NONE, BASE_NONE, NULL, 0x0,
2294 "This is a Zero-Window", HFILL }},
2297 { "TCP Segment Len", "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
2300 { &hf_tcp_analysis_acks_frame,
2301 { "This is an ACK to the segment in frame", "tcp.analysis.acks_frame", FT_UINT32, BASE_DEC, NULL, 0x0,
2302 "Which previous segment is this an ACK for", HFILL}},
2304 { &hf_tcp_analysis_ack_rtt,
2305 { "The RTT to ACK the segment was", "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2306 "How long time it took to ACK the segment (RTT)", HFILL}},
2308 { &hf_tcp_urgent_pointer,
2309 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
2312 { &hf_tcp_segment_overlap,
2313 { "Segment overlap", "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2314 "Segment overlaps with other segments", HFILL }},
2316 { &hf_tcp_segment_overlap_conflict,
2317 { "Conflicting data in segment overlap", "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2318 "Overlapping segments contained conflicting data", HFILL }},
2320 { &hf_tcp_segment_multiple_tails,
2321 { "Multiple tail segments found", "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2322 "Several tails were found when desegmenting the pdu", HFILL }},
2324 { &hf_tcp_segment_too_long_fragment,
2325 { "Segment too long", "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2326 "Segment contained data past end of the pdu", HFILL }},
2328 { &hf_tcp_segment_error,
2329 { "Desegmentation error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2330 "Desegmentation error due to illegal segments", HFILL }},
2333 { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2334 "TCP Segment", HFILL }},
2337 { "TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
2338 "TCP Segments", HFILL }},
2339 { &hf_tcp_option_mss,
2340 { "TCP MSS Option", "tcp.options.mss", FT_BOOLEAN,
2341 BASE_NONE, NULL, 0x0, "TCP MSS Option", HFILL }},
2342 { &hf_tcp_option_mss_val,
2343 { "TCP MSS Option Value", "tcp.options.mss_val", FT_UINT16,
2344 BASE_DEC, NULL, 0x0, "TCP MSS Option Value", HFILL}},
2345 { &hf_tcp_option_wscale,
2346 { "TCP Window Scale Option", "tcp.options.wscale",
2348 BASE_NONE, NULL, 0x0, "TCP Window Option", HFILL}},
2349 { &hf_tcp_option_wscale_val,
2350 { "TCP Windows Scale Option Value", "tcp.options.wscale_val",
2351 FT_UINT8, BASE_DEC, NULL, 0x0, "TCP Window Scale Value",
2353 { &hf_tcp_option_sack_perm,
2354 { "TCP Sack Perm Option", "tcp.options.sack_perm",
2356 BASE_NONE, NULL, 0x0, "TCP Sack Perm Option", HFILL}},
2357 { &hf_tcp_option_sack,
2358 { "TCP Sack Option", "tcp.options.sack", FT_BOOLEAN,
2359 BASE_NONE, NULL, 0x0, "TCP Sack Option", HFILL}},
2360 { &hf_tcp_option_sack_sle,
2361 {"TCP Sack Left Edge", "tcp.options.sack_le", FT_UINT32,
2362 BASE_DEC, NULL, 0x0, "TCP Sack Left Edge", HFILL}},
2363 { &hf_tcp_option_sack_sre,
2364 {"TCP Sack Right Edge", "tcp.options.sack_re", FT_UINT32,
2365 BASE_DEC, NULL, 0x0, "TCP Sack Right Edge", HFILL}},
2366 { &hf_tcp_option_echo,
2367 { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
2368 BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
2369 { &hf_tcp_option_echo_reply,
2370 { "TCP Echo Reply Option", "tcp.options.echo_reply",
2372 BASE_NONE, NULL, 0x0, "TCP Echo Reply Option", HFILL}},
2373 { &hf_tcp_option_time_stamp,
2374 { "TCP Time Stamp Option", "tcp.options.time_stamp",
2376 BASE_NONE, NULL, 0x0, "TCP Time Stamp Option", HFILL}},
2377 { &hf_tcp_option_cc,
2378 { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
2379 NULL, 0x0, "TCP CC Option", HFILL}},
2380 { &hf_tcp_option_ccnew,
2381 { "TCP CC New Option", "tcp.options.ccnew", FT_BOOLEAN,
2382 BASE_NONE, NULL, 0x0, "TCP CC New Option", HFILL}},
2383 { &hf_tcp_option_ccecho,
2384 { "TCP CC Echo Option", "tcp.options.ccecho", FT_BOOLEAN,
2385 BASE_NONE, NULL, 0x0, "TCP CC Echo Option", HFILL}},
2386 { &hf_tcp_option_md5,
2387 { "TCP MD5 Option", "tcp.options.md5", FT_BOOLEAN, BASE_NONE,
2388 NULL, 0x0, "TCP MD5 Option", HFILL}},
2390 static gint *ett[] = {
2394 &ett_tcp_option_sack,
2395 &ett_tcp_analysis_faults,
2400 module_t *tcp_module;
2402 proto_tcp = proto_register_protocol("Transmission Control Protocol",
2404 proto_register_field_array(proto_tcp, hf, array_length(hf));
2405 proto_register_subtree_array(ett, array_length(ett));
2407 /* subdissector code */
2408 subdissector_table = register_dissector_table("tcp.port",
2409 "TCP port", FT_UINT16, BASE_DEC);
2410 register_heur_dissector_list("tcp", &heur_subdissector_list);
2412 /* Register configuration preferences */
2413 tcp_module = prefs_register_protocol(proto_tcp, NULL);
2414 prefs_register_bool_preference(tcp_module, "summary_in_tree",
2415 "Show TCP summary in protocol tree",
2416 "Whether the TCP summary line should be shown in the protocol tree",
2417 &tcp_summary_in_tree);
2418 prefs_register_bool_preference(tcp_module, "check_checksum",
2419 "Check the validity of the TCP checksum when possible",
2420 "Whether to check the validity of the TCP checksum",
2421 &tcp_check_checksum);
2422 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
2423 "Allow subdissector to desegment TCP streams",
2424 "Whether subdissector can request TCP streams to be desegmented",
2426 prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
2427 "Analyze TCP sequence numbers",
2428 "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
2430 prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
2431 "Use relative sequence numbers",
2432 "Make the TCP dissector use relative sequence numbers instead of absolute ones. To use this option you must also enable \"Analyze TCP sequence numbers\".",
2435 register_init_routine(tcp_analyze_seq_init);
2436 register_init_routine(tcp_desegment_init);
2437 register_init_routine(tcp_fragment_init);
2441 proto_reg_handoff_tcp(void)
2443 dissector_handle_t tcp_handle;
2445 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
2446 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
2447 data_handle = find_dissector("data");
2448 tcp_tap = register_tap("tcp");