Support for the new restart TLV, from Hannes Gredler.
[obnox/wireshark/wip.git] / packet-tcp.c
1 /* packet-tcp.c
2  * Routines for TCP packet disassembly
3  *
4  * $Id: packet-tcp.c,v 1.130 2002/02/03 23:28:38 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  * 
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.
14  * 
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.
19  * 
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
31 #endif
32
33 #ifdef HAVE_NETINET_IN_H
34 # include <netinet/in.h>
35 #endif
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <glib.h>
40 #include "in_cksum.h"
41
42 #ifdef NEED_SNPRINTF_H
43 # include "snprintf.h"
44 #endif
45
46 #include <epan/resolv.h>
47 #include "ipproto.h"
48 #include "follow.h"
49 #include "prefs.h"
50 #include "packet-tcp.h"
51 #include "packet-ip.h"
52 #include <epan/conversation.h>
53 #include <epan/strutil.h>
54 #include "reassemble.h"
55
56 /* Place TCP summary in proto tree */
57 static gboolean tcp_summary_in_tree = TRUE;
58
59 /*
60  * Don't check the TCP checksum (I've seen packets with bad TCP checksums
61  * in Solaris network traces, but the traffic appears to indicate that
62  * the packet *was* received; I suspect the packets were sent by the host
63  * on which the capture was being done, on a network interface to which
64  * checksumming was offloaded, so that DLPI supplied an un-checksummed
65  * packet to the capture program but a checksummed packet got put onto
66  * the wire).
67  */
68 static gboolean tcp_check_checksum = TRUE;
69
70 extern FILE* data_out_file;
71
72 static int proto_tcp = -1;
73 static int hf_tcp_srcport = -1;
74 static int hf_tcp_dstport = -1;
75 static int hf_tcp_port = -1;
76 static int hf_tcp_seq = -1;
77 static int hf_tcp_nxtseq = -1;
78 static int hf_tcp_ack = -1;
79 static int hf_tcp_hdr_len = -1;
80 static int hf_tcp_flags = -1;
81 static int hf_tcp_flags_cwr = -1;
82 static int hf_tcp_flags_ecn = -1;
83 static int hf_tcp_flags_urg = -1;
84 static int hf_tcp_flags_ack = -1;
85 static int hf_tcp_flags_push = -1;
86 static int hf_tcp_flags_reset = -1;
87 static int hf_tcp_flags_syn = -1;
88 static int hf_tcp_flags_fin = -1;
89 static int hf_tcp_window_size = -1;
90 static int hf_tcp_checksum = -1;
91 static int hf_tcp_checksum_bad = -1;
92 static int hf_tcp_urgent_pointer = -1;
93
94 static gint ett_tcp = -1;
95 static gint ett_tcp_flags = -1;
96 static gint ett_tcp_options = -1;
97 static gint ett_tcp_option_sack = -1;
98 static gint ett_tcp_segments = -1;
99
100 static dissector_table_t subdissector_table;
101 static heur_dissector_list_t heur_subdissector_list;
102 static dissector_handle_t data_handle;
103
104 /* TCP structs and definitions */
105
106 #define TH_FIN  0x01
107 #define TH_SYN  0x02
108 #define TH_RST  0x04
109 #define TH_PUSH 0x08
110 #define TH_ACK  0x10
111 #define TH_URG  0x20
112 #define TH_ECN  0x40
113 #define TH_CWR  0x80
114
115 /* Minimum TCP header length. */
116 #define TCPH_MIN_LEN    20
117
118 /*
119  *      TCP option
120  */
121  
122 #define TCPOPT_NOP              1       /* Padding */
123 #define TCPOPT_EOL              0       /* End of options */
124 #define TCPOPT_MSS              2       /* Segment size negotiating */
125 #define TCPOPT_WINDOW           3       /* Window scaling */
126 #define TCPOPT_SACK_PERM        4       /* SACK Permitted */
127 #define TCPOPT_SACK             5       /* SACK Block */
128 #define TCPOPT_ECHO             6
129 #define TCPOPT_ECHOREPLY        7
130 #define TCPOPT_TIMESTAMP        8       /* Better RTT estimations/PAWS */
131 #define TCPOPT_CC               11
132 #define TCPOPT_CCNEW            12
133 #define TCPOPT_CCECHO           13
134 #define TCPOPT_MD5              19      /* RFC2385 */
135
136 /*
137  *     TCP option lengths
138  */
139
140 #define TCPOLEN_MSS            4
141 #define TCPOLEN_WINDOW         3
142 #define TCPOLEN_SACK_PERM      2
143 #define TCPOLEN_SACK_MIN       2
144 #define TCPOLEN_ECHO           6
145 #define TCPOLEN_ECHOREPLY      6
146 #define TCPOLEN_TIMESTAMP      10
147 #define TCPOLEN_CC             6
148 #define TCPOLEN_CCNEW          6
149 #define TCPOLEN_CCECHO         6
150 #define TCPOLEN_MD5            18
151
152
153
154 /* Desegmentation of TCP streams */
155 /* table to hold defragmented TCP streams */
156 static GHashTable *tcp_fragment_table = NULL;
157 static void
158 tcp_fragment_init(void)
159 {
160         fragment_table_init(&tcp_fragment_table);
161 }
162
163 /* functions to trace tcp segments */
164 /* Enable desegmenting of TCP streams */
165 static gboolean tcp_desegment = FALSE;
166
167 static GHashTable *tcp_segment_table = NULL;
168 static GMemChunk *tcp_segment_key_chunk = NULL;
169 static int tcp_segment_init_count = 200;
170 static GMemChunk *tcp_segment_address_chunk = NULL;
171 static int tcp_segment_address_init_count = 500;
172
173 typedef struct _tcp_segment_key {
174         /* for ouwn bookkeeping inside packet-tcp.c */
175         address *src;
176         address *dst;
177         guint32 seq;
178         /* xxx */
179         guint32 start_seq;
180         guint32 tot_len;
181         guint32 first_frame;
182 } tcp_segment_key;
183
184 static gboolean
185 free_all_segments(gpointer key_arg, gpointer value, gpointer user_data)
186 {
187         tcp_segment_key *key = key_arg;
188
189         if((key->src)&&(key->src->data)){
190                 g_free((gpointer)key->src->data);
191                 key->src->data=NULL;
192         }
193
194         if((key->dst)&&(key->dst->data)){
195                 g_free((gpointer)key->dst->data);
196                 key->dst->data=NULL;
197         }
198
199         return TRUE;
200 }
201
202 static guint
203 tcp_segment_hash(gconstpointer k)
204 {
205         tcp_segment_key *key = (tcp_segment_key *)k;
206
207         return key->seq;
208 }
209
210 static gint
211 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
212 {
213         tcp_segment_key *key1 = (tcp_segment_key *)k1;
214         tcp_segment_key *key2 = (tcp_segment_key *)k2;
215
216         return ( ( (key1->seq==key2->seq)
217                  &&(ADDRESSES_EQUAL(key1->src, key2->src))
218                  &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
219                  ) ? TRUE:FALSE);
220 }
221
222 static void
223 tcp_desegment_init(void)
224 {
225
226         /* dont allocate any memory chunks unless the user really
227            uses this option
228         */
229         if(!tcp_desegment){
230                 return;
231         }
232
233         if(tcp_segment_table){
234                 g_hash_table_foreach_remove(tcp_segment_table,
235                         free_all_segments, NULL);
236         } else {
237                 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
238                         tcp_segment_equal);
239         }
240
241         if(tcp_segment_key_chunk){
242                 g_mem_chunk_destroy(tcp_segment_key_chunk);
243         }
244         tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
245                 sizeof(tcp_segment_key),
246                 tcp_segment_init_count*sizeof(tcp_segment_key),
247                 G_ALLOC_ONLY);
248
249         if(tcp_segment_address_chunk){
250                 g_mem_chunk_destroy(tcp_segment_address_chunk);
251         }
252         tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
253                 sizeof(address),
254                 tcp_segment_address_init_count*sizeof(address),
255                 G_ALLOC_ONLY);
256 }
257
258 static void
259 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
260                 guint32 seq, guint32 nxtseq,
261                 guint32 sport, guint32 dport,
262                 proto_tree *tree, proto_tree *tcp_tree)
263 {
264         struct tcpinfo *tcpinfo = pinfo->private_data;
265         fragment_data *ipfd_head;
266         tcp_segment_key old_tsk, *tsk;
267         gboolean must_desegment = FALSE;
268         gboolean called_dissector = FALSE;
269         int deseg_offset;
270         guint32 deseg_seq;
271
272         /*
273          * Initialize these to assume no desegmentation.
274          * If that's not the case, these will be set appropriately
275          * by the subdissector.
276          */
277         pinfo->desegment_offset = 0;
278         pinfo->desegment_len = 0;
279
280         /*
281          * Initialize this to assume that this segment will just be
282          * added to the middle of a desegmented chunk of data, so
283          * that we should show it all as data.
284          * If that's not the case, it will be set appropriately.
285          */
286         deseg_offset = offset;
287
288         /* First we must check if this TCP segment should be desegmented.
289            This is only to check if we should desegment this packet,
290            so we dont spend time doing COPY_ADDRESS/g_free.
291            We just "borrow" some address structures from pinfo instead. Cheaper.
292         */
293         old_tsk.src = &pinfo->src;
294         old_tsk.dst = &pinfo->dst;
295         old_tsk.seq = seq;
296         tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
297
298         if(tsk){
299                 /* OK, this segment was found, which means it continues
300                    a higher-level PDU. This means we must desegment it.
301                    Add it to the defragmentation lists.
302                 */
303                 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->start_seq,
304                         tcp_fragment_table,
305                         seq - tsk->start_seq,
306                         nxtseq - seq,
307                         (nxtseq < (tsk->start_seq + tsk->tot_len)) );
308
309                 if(!ipfd_head){
310                         /* fragment_add() returned NULL, This means that 
311                            desegmentation is not completed yet.
312                            (its like defragmentation but we know we will
313                             always add the segments in order).
314                            XXX - no, we don't; there is no guarantee that
315                            TCP segments are in order on the wire.
316
317                            we must add next segment to our table so we will
318                            find it later.
319                         */
320                         tcp_segment_key *new_tsk;
321
322                         new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
323                         memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
324                         new_tsk->seq=nxtseq;
325                         g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
326                 }
327         } else {
328                 /* This segment was not found in our table, so it doesn't
329                    contain a continuation of a higher-level PDU.
330                    Call the normal subdissector.
331                 */
332                 decode_tcp_ports(tvb, offset, pinfo, tree, 
333                                 sport, dport);
334                 called_dissector = TRUE;
335
336                 /* Did the subdissector ask us to desegment some more data
337                    before it could handle the packet? 
338                    If so we have to create some structures in our table but
339                    this is something we only do the first time we see this 
340                    packet.
341                 */
342                 if(pinfo->desegment_len) {
343                         if (!pinfo->fd->flags.visited)
344                                 must_desegment = TRUE;
345
346                         /*
347                          * Set "deseg_offset" to the offset in "tvb"
348                          * of the first byte of data that the
349                          * subdissector didn't process.
350                          */
351                         deseg_offset = offset + pinfo->desegment_offset;
352                 }
353
354                 /* Either no desegmentation is necessary, or this is
355                    segment contains the beginning but not the end of
356                    a higher-level PDU and thus isn't completely
357                    desegmented.
358                 */
359                 ipfd_head = NULL;
360         }
361
362         /* is it completely desegmented? */
363         if(ipfd_head){
364                 fragment_data *ipfd;
365                 proto_tree *st = NULL;
366                 proto_item *si = NULL;
367
368                 /*
369                  * Yes, we think it is.
370                  * We only call subdissector for the last segment.
371                  * Note that the last segment may include more than what
372                  * we needed.
373                  */
374                 if(nxtseq >= (tsk->start_seq + tsk->tot_len)){
375                         /*
376                          * OK, this is the last segment.
377                          * Let's call the subdissector with the desegmented
378                          * data.
379                          */
380                         tvbuff_t *next_tvb;
381                         int old_len;
382
383                         /* create a new TVB structure for desegmented data */
384                         next_tvb = tvb_new_real_data(ipfd_head->data,
385                                         ipfd_head->datalen, ipfd_head->datalen,
386                                         "Desegmented");
387
388                         /* add this tvb as a child to the original one */
389                         tvb_set_child_real_data_tvbuff(tvb, next_tvb);
390
391                         /* add desegmented data to the data source list */
392                         pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
393
394                         /* indicate that this is reassembled data */
395                         tcpinfo->is_reassembled = TRUE;
396
397                         /* call subdissector */
398                         decode_tcp_ports(next_tvb, 0, pinfo, tree,
399                                 sport, dport);
400                         called_dissector = TRUE;
401
402                         /*
403                          * OK, did the subdissector think it was completely
404                          * desegmented, or does it think we need even more
405                          * data?
406                          */
407                         old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
408                         if(pinfo->desegment_len &&
409                             pinfo->desegment_offset<=old_len){
410                                 tcp_segment_key *new_tsk;
411
412                                 /*
413                                  * "desegment_len" isn't 0, so it needs more
414                                  * data for something - and "desegment_offset"
415                                  * is before "old_len", so it needs more data
416                                  * to dissect the stuff we thought was
417                                  * completely desegmented (as opposed to the
418                                  * stuff at the beginning being completely
419                                  * desegmented, but the stuff at the end
420                                  * being a new higher-level PDU that also
421                                  * needs desegmentation).
422                                  */
423                                 fragment_set_partial_reassembly(pinfo,tsk->start_seq,tcp_fragment_table);
424                                 tsk->tot_len = tvb_reported_length(next_tvb) + pinfo->desegment_len;
425
426                                 /*
427                                  * Update tsk structure.
428                                  * Can ask ->next->next because at least there's a hdr and one
429                                  * entry in fragment_add()
430                                  */
431                                 for(ipfd=ipfd_head->next; ipfd->next; ipfd=ipfd->next){
432                                         old_tsk.seq = tsk->start_seq + ipfd->offset;
433                                         new_tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
434                                         new_tsk->tot_len = tsk->tot_len;
435                                 }
436
437                                 /* this is the next segment in the sequence we want */
438                                 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
439                                 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
440                                 new_tsk->seq = nxtseq;
441                                 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
442                         } else {
443                                 /*
444                                  * The subdissector thought it was completely
445                                  * desegmented (although the stuff at the
446                                  * end may, in turn, require desegmentation),
447                                  * so we show a tree with all segments.
448                                  */
449                                 si = proto_tree_add_text(tcp_tree, tvb, 0, 0,
450                                                 "Segments");
451                                 st = proto_item_add_subtree(si, ett_tcp_segments);
452                                 for(ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
453                                         proto_tree_add_text(st, tvb, 0, 0,
454                                         "Frame:%u seq#:%u-%u [%u-%u]",
455                                         ipfd->frame,
456                                         tsk->start_seq + ipfd->offset,
457                                         tsk->start_seq + ipfd->offset + ipfd->len-1,
458                                         ipfd->offset,
459                                         ipfd->offset + ipfd->len - 1);
460                                 }
461
462                                 /* Did the subdissector ask us to desegment
463                                    some more data?  This means that the data
464                                    at the beginning of this segment completed
465                                    a higher-level PDU, but the data at the
466                                    end of this segment started a higher-level
467                                    PDU but didn't complete it.
468
469                                    If so, we have to create some structures
470                                    in our table, but this is something we
471                                    only do the first time we see this packet.
472                                 */
473                                 if(pinfo->desegment_len) {
474                                         if (!pinfo->fd->flags.visited)
475                                                 must_desegment = TRUE;
476
477                                         /* The stuff we couldn't dissect
478                                            must have come from this segment,
479                                            so it's all in "tvb".
480
481                                            "pinfo->desegment_offset" is
482                                            relative to the beginning of
483                                            "next_tvb"; we want an offset
484                                            relative to the beginning of "tvb".
485
486                                            First, compute the offset relative
487                                            to the *end* of "next_tvb" - i.e.,
488                                            the number of bytes before the end
489                                            of "next_tvb" at which the
490                                            subdissector stopped.  That's the
491                                            length of "next_tvb" minus the
492                                            offset, relative to the beginning
493                                            of "next_tvb, at which the
494                                            subdissector stopped.
495                                         */
496                                         deseg_offset =
497                                             ipfd_head->datalen - pinfo->desegment_offset;
498
499                                         /* "tvb" and "next_tvb" end at the
500                                            same byte of data, so the offset
501                                            relative to the end of "next_tvb"
502                                            of the byte at which we stopped
503                                            is also the offset relative to
504                                            the end of "tvb" of the byte at
505                                            which we stopped.
506
507                                            Convert that back into an offset
508                                            relative to the beginninng of
509                                            "tvb", by taking the length of
510                                            "tvb" and subtracting the offset
511                                            relative to the end.
512                                         */
513                                         deseg_offset=tvb_reported_length(tvb) - deseg_offset;
514                                 }
515                         }
516                 }
517         }
518
519         if (must_desegment) {
520             tcp_segment_key *tsk, *new_tsk;
521
522             /*
523              * The sequence number at which the stuff to be desegmented
524              * starts is the sequence number of the byte at an offset
525              * of "deseg_offset" into "tvb".
526              *
527              * The sequence number of the byte at an offset of "offset"
528              * is "seq", i.e. the starting sequence number of this
529              * segment, so the sequence number of the byte at
530              * "deseg_offset" is "seq + (deseg_offset - offset)".
531              */
532             deseg_seq = seq + (deseg_offset - offset);
533
534             /*
535              * XXX - how do we detect out-of-order transmissions?
536              * We can't just check for "nxtseq" being greater than
537              * "tsk->start_seq"; for now, we check for the difference
538              * being less than a megabyte, but this is a really
539              * gross hack - we really need to handle out-of-order
540              * transmissions correctly.
541              */
542             if ((nxtseq - deseg_seq) <= 1024*1024) {
543                 /* OK, subdissector wants us to desegment
544                    some data before it can process it. Add
545                    what remains of this packet and set
546                    up next packet/sequence number as well.
547
548                    We must remember this segment
549                 */
550                 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
551                 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
552                 COPY_ADDRESS(tsk->src, &pinfo->src);
553                 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
554                 COPY_ADDRESS(tsk->dst, &pinfo->dst);
555                 tsk->seq = deseg_seq;
556                 tsk->start_seq = tsk->seq;
557                 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
558                 tsk->first_frame = pinfo->fd->num;
559                 g_hash_table_insert(tcp_segment_table, tsk, tsk);
560
561                 /* Add portion of segment unprocessed by the subdissector
562                    to defragmentation lists */
563                 fragment_add(tvb, deseg_offset, pinfo, tsk->start_seq,
564                     tcp_fragment_table,
565                     tsk->seq - tsk->start_seq,
566                     nxtseq - tsk->start_seq,
567                     (nxtseq < tsk->start_seq + tsk->tot_len));
568
569                 /* this is the next segment in the sequence we want */
570                 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
571                 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
572                 new_tsk->seq = nxtseq;
573                 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
574             }
575         }
576
577         if (!called_dissector || pinfo->desegment_len != 0) {
578                 /*
579                  * Either we didn't call the subdissector at all (i.e.,
580                  * this is a segment that contains the middle of a
581                  * higher-level PDU, but contains neither the beginning
582                  * nor the end), or the subdissector couldn't dissect it
583                  * all, as some data was missing (i.e., it set
584                  * "pinfo->desegment_len" to the amount of additional
585                  * data it needs).
586                  */
587                 if (pinfo->desegment_offset == 0) {
588                         /*
589                          * It couldn't, in fact, dissect any of it (the
590                          * first byte it couldn't dissect is at an offset
591                          * of "pinfo->desegment_offset" from the beginning
592                          * of the payload, and that's 0).
593                          * Just mark this as TCP.
594                          */
595                         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
596                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
597                         }
598                         if (check_col(pinfo->cinfo, COL_INFO)){
599                                 col_set_str(pinfo->cinfo, COL_INFO, "[Desegmented TCP]");
600                         }
601                 }
602
603                 /*
604                  * Show what's left in the packet as data.
605                  * XXX - remember what protocol the last subdissector
606                  * was, and report it as a continuation of that, instead.
607                  */
608                 call_dissector(data_handle,tvb_new_subset(tvb, deseg_offset,-1,tvb_reported_length_remaining(tvb,deseg_offset)), pinfo, tree);
609         }
610         pinfo->can_desegment=0;
611         pinfo->desegment_offset = 0;
612         pinfo->desegment_len = 0;
613 }
614
615
616
617
618 static void
619 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
620 {
621   if (check_col(pinfo->cinfo, COL_INFO))
622     col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
623 }
624
625 static void
626 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
627     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
628 {
629   guint16 mss;
630
631   mss = tvb_get_ntohs(tvb, offset + 2);
632   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
633                         "%s: %u bytes", optp->name, mss);
634   tcp_info_append_uint(pinfo, "MSS", mss);
635 }
636
637 static void
638 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
639     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
640 {
641   guint8 ws;
642
643   ws = tvb_get_guint8(tvb, offset + 2);
644   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
645                         "%s: %u bytes", optp->name, ws);
646   tcp_info_append_uint(pinfo, "WS", ws);
647 }
648
649 static void
650 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
651     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
652 {
653   proto_tree *field_tree = NULL;
654   proto_item *tf;
655   guint leftedge, rightedge;
656
657   tf = proto_tree_add_text(opt_tree, tvb, offset,      optlen, "%s:", optp->name);
658   offset += 2;  /* skip past type and length */
659   optlen -= 2;  /* subtract size of type and length */
660   while (optlen > 0) {
661     if (field_tree == NULL) {
662       /* Haven't yet made a subtree out of this option.  Do so. */
663       field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
664     }
665     if (optlen < 4) {
666       proto_tree_add_text(field_tree, tvb, offset,      optlen,
667         "(suboption would go past end of option)");
668       break;
669     }
670     leftedge = tvb_get_ntohl(tvb, offset);
671     optlen -= 4;
672     if (optlen < 4) {
673       proto_tree_add_text(field_tree, tvb, offset,      optlen,
674         "(suboption would go past end of option)");
675       break;
676     }
677     /* XXX - check whether it goes past end of packet */
678     rightedge = tvb_get_ntohl(tvb, offset + 4);
679     optlen -= 4;
680     proto_tree_add_text(field_tree, tvb, offset,      8,
681         "left edge = %u, right edge = %u", leftedge, rightedge);
682     tcp_info_append_uint(pinfo, "SLE", leftedge);
683     tcp_info_append_uint(pinfo, "SRE", rightedge);
684     offset += 8;
685   }
686 }
687
688 static void
689 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
690     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
691 {
692   guint32 echo;
693
694   echo = tvb_get_ntohl(tvb, offset + 2);
695   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
696                         "%s: %u", optp->name, echo);
697   tcp_info_append_uint(pinfo, "ECHO", echo);
698 }
699
700 static void
701 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
702     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
703 {
704   guint32 tsv, tser;
705
706   tsv = tvb_get_ntohl(tvb, offset + 2);
707   tser = tvb_get_ntohl(tvb, offset + 6);
708   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
709     "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
710   tcp_info_append_uint(pinfo, "TSV", tsv);
711   tcp_info_append_uint(pinfo, "TSER", tser);
712 }
713
714 static void
715 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
716     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
717 {
718   guint32 cc;
719
720   cc = tvb_get_ntohl(tvb, offset + 2);
721   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
722                         "%s: %u", optp->name, cc);
723   tcp_info_append_uint(pinfo, "CC", cc);
724 }
725
726 static const ip_tcp_opt tcpopts[] = {
727   {
728     TCPOPT_EOL,
729     "EOL",
730     NULL,
731     NO_LENGTH,
732     0,
733     NULL,
734   },
735   {
736     TCPOPT_NOP,
737     "NOP",
738     NULL,
739     NO_LENGTH,
740     0,
741     NULL,
742   },
743   {
744     TCPOPT_MSS,
745     "Maximum segment size",
746     NULL,
747     FIXED_LENGTH,
748     TCPOLEN_MSS,
749     dissect_tcpopt_maxseg
750   },
751   {
752     TCPOPT_WINDOW,
753     "Window scale",
754     NULL,
755     FIXED_LENGTH,
756     TCPOLEN_WINDOW,
757     dissect_tcpopt_wscale
758   },
759   {
760     TCPOPT_SACK_PERM,
761     "SACK permitted",
762     NULL,
763     FIXED_LENGTH,
764     TCPOLEN_SACK_PERM,
765     NULL,
766   },
767   {
768     TCPOPT_SACK,
769     "SACK",
770     &ett_tcp_option_sack,
771     VARIABLE_LENGTH,
772     TCPOLEN_SACK_MIN,
773     dissect_tcpopt_sack
774   },
775   {
776     TCPOPT_ECHO,
777     "Echo",
778     NULL,
779     FIXED_LENGTH,
780     TCPOLEN_ECHO,
781     dissect_tcpopt_echo
782   },
783   {
784     TCPOPT_ECHOREPLY,
785     "Echo reply",
786     NULL,
787     FIXED_LENGTH,
788     TCPOLEN_ECHOREPLY,
789     dissect_tcpopt_echo
790   },
791   {
792     TCPOPT_TIMESTAMP,
793     "Time stamp",
794     NULL,
795     FIXED_LENGTH,
796     TCPOLEN_TIMESTAMP,
797     dissect_tcpopt_timestamp
798   },
799   {
800     TCPOPT_CC,
801     "CC",
802     NULL,
803     FIXED_LENGTH,
804     TCPOLEN_CC,
805     dissect_tcpopt_cc
806   },
807   {
808     TCPOPT_CCNEW,
809     "CC.NEW",
810     NULL,
811     FIXED_LENGTH,
812     TCPOLEN_CCNEW,
813     dissect_tcpopt_cc
814   },
815   {
816     TCPOPT_CCECHO,
817     "CC.ECHO",
818     NULL,
819     FIXED_LENGTH,
820     TCPOLEN_CCECHO,
821     dissect_tcpopt_cc
822   },
823   {
824     TCPOPT_MD5,
825     "TCP MD5 signature",
826     NULL,
827     FIXED_LENGTH,
828     TCPOLEN_MD5,
829     NULL
830   }
831 };
832
833 #define N_TCP_OPTS      (sizeof tcpopts / sizeof tcpopts[0])
834
835 /* TCP flags flag */
836 static const true_false_string flags_set_truth = {
837   "Set",
838   "Not set"
839 };
840
841
842 /* Determine if there is a sub-dissector and call it.  This has been */
843 /* separated into a stand alone routine to other protocol dissectors */
844 /* can call to it, ie. socks    */
845
846 void
847 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
848         proto_tree *tree, int src_port, int dst_port)
849 {
850   tvbuff_t *next_tvb;
851
852   next_tvb = tvb_new_subset(tvb, offset, -1, -1);
853
854 /* determine if this packet is part of a conversation and call dissector */
855 /* for the conversation if available */
856
857   if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
858                 src_port, dst_port, next_tvb, pinfo, tree))
859     return;
860
861   /* do lookup with the subdissector table */
862   if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
863       dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
864     return;
865
866   /* do lookup with the heuristic subdissector table */
867   if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
868     return;
869
870   /* Oh, well, we don't know this; dissect it as data. */
871   call_dissector(data_handle,next_tvb, pinfo, tree);
872 }
873
874
875 static void
876 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
877 {
878   guint16 th_sport;
879   guint16 th_dport;
880   guint32 th_seq;
881   guint32 th_ack;
882   guint8  th_off_x2; /* combines th_off and th_x2 */
883   guint8  th_flags;
884   guint16 th_win;
885   guint16 th_sum;
886   guint16 th_urp;
887   proto_tree *tcp_tree = NULL, *field_tree = NULL;
888   proto_item *ti = NULL, *tf;
889   int        offset = 0;
890   gchar      flags[64] = "<None>";
891   gchar     *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
892   gint       fpos = 0, i;
893   guint      bpos;
894   guint      hlen;
895   guint      optlen;
896   guint32    seglen;
897   guint32    nxtseq;
898   guint      len;
899   guint      reported_len;
900   vec_t      cksum_vec[4];
901   guint32    phdr[2];
902   guint16    computed_cksum;
903   guint      length_remaining;
904   gboolean   desegment_ok;
905   struct tcpinfo tcpinfo;
906   gboolean   save_fragmented;
907
908   if (check_col(pinfo->cinfo, COL_PROTOCOL))
909     col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
910
911   /* Clear out the Info column. */
912   if (check_col(pinfo->cinfo, COL_INFO))
913     col_clear(pinfo->cinfo, COL_INFO);
914
915   th_sport = tvb_get_ntohs(tvb, offset);
916   th_dport = tvb_get_ntohs(tvb, offset + 2);
917   if (check_col(pinfo->cinfo, COL_INFO)) {
918     col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
919       get_tcp_port(th_sport), get_tcp_port(th_dport));
920   }
921   
922   if (tree) {
923     if (tcp_summary_in_tree) {
924             ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
925                 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
926                 get_tcp_port(th_sport), th_sport,
927                 get_tcp_port(th_dport), th_dport);
928     }
929     else {
930             ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
931     }
932     tcp_tree = proto_item_add_subtree(ti, ett_tcp);
933     proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th_sport,
934         "Source port: %s (%u)", get_tcp_port(th_sport), th_sport);
935     proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th_dport,
936         "Destination port: %s (%u)", get_tcp_port(th_dport), th_dport);
937     proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th_sport);
938     proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th_dport);
939   }
940
941   th_seq = tvb_get_ntohl(tvb, offset + 4);
942   th_ack = tvb_get_ntohl(tvb, offset + 8);
943   th_off_x2 = tvb_get_guint8(tvb, offset + 12);
944   th_flags = tvb_get_guint8(tvb, offset + 13);
945   th_win = tvb_get_ntohs(tvb, offset + 14);
946   
947   if (check_col(pinfo->cinfo, COL_INFO) || tree) {  
948     for (i = 0; i < 8; i++) {
949       bpos = 1 << i;
950       if (th_flags & bpos) {
951         if (fpos) {
952           strcpy(&flags[fpos], ", ");
953           fpos += 2;
954         }
955         strcpy(&flags[fpos], fstr[i]);
956         fpos += 3;
957       }
958     }
959     flags[fpos] = '\0';
960   }
961
962   if (check_col(pinfo->cinfo, COL_INFO)) {
963     col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
964       flags, th_seq, th_ack, th_win);
965   }
966
967   if (tree) {
968     if (tcp_summary_in_tree)
969       proto_item_append_text(ti, ", Seq: %u", th_seq);
970     proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th_seq);
971   }
972
973   hlen = hi_nibble(th_off_x2) * 4;  /* TCP header length, in bytes */
974
975   if (hlen < TCPH_MIN_LEN) {
976     /* Give up at this point; we put the source and destination port in
977        the tree, before fetching the header length, so that they'll
978        show up if this is in the failing packet in an ICMP error packet,
979        but it's now time to give up if the header length is bogus. */
980     if (check_col(pinfo->cinfo, COL_INFO))
981       col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
982         hlen, TCPH_MIN_LEN);
983     if (tree) {
984       proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
985        "Header length: %u bytes (bogus, must be at least %u)", hlen,
986        TCPH_MIN_LEN);
987     }
988     return;
989   }
990
991   reported_len = tvb_reported_length(tvb);
992   len = tvb_length(tvb);
993
994   /* Compute the length of data in this segment. */
995   seglen = reported_len - hlen;
996
997   /* Compute the sequence number of next octet after this segment. */
998   nxtseq = th_seq + seglen;
999
1000   if (tree) {
1001     if (tcp_summary_in_tree)
1002       proto_item_append_text(ti, ", Ack: %u", th_ack);
1003     proto_item_set_len(ti, hlen);
1004     if (nxtseq != th_seq)
1005       proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
1006     if (th_flags & TH_ACK)
1007       proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th_ack);
1008     proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
1009         "Header length: %u bytes", hlen);
1010     tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
1011         th_flags, "Flags: 0x%04x (%s)", th_flags, flags);
1012     field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
1013     proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th_flags);
1014     proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th_flags);
1015     proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th_flags);
1016     proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th_flags);
1017     proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th_flags);
1018     proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th_flags);
1019     proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th_flags);
1020     proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th_flags);
1021     proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th_win);
1022   }
1023
1024   /* Assume we'll pass un-reassembled data to subdissectors. */
1025   tcpinfo.is_reassembled = FALSE;
1026
1027   pinfo->private_data = &tcpinfo;
1028
1029   /*
1030    * Assume, initially, that we can't desegment.
1031    */
1032   pinfo->can_desegment = 0;
1033
1034   th_sum = tvb_get_ntohs(tvb, offset + 16);
1035   if (!pinfo->fragmented && len >= reported_len) {
1036     /* The packet isn't part of an un-reassembled fragmented datagram
1037        and isn't truncated.  This means we have all the data, and thus
1038        can checksum it and, unless it's being returned in an error
1039        packet, are willing to allow subdissectors to request reassembly
1040        on it. */
1041   
1042     if (tcp_check_checksum) {
1043       /* We haven't turned checksum checking off; checksum it. */
1044
1045       /* Set up the fields of the pseudo-header. */
1046       cksum_vec[0].ptr = pinfo->src.data;
1047       cksum_vec[0].len = pinfo->src.len;
1048       cksum_vec[1].ptr = pinfo->dst.data;
1049       cksum_vec[1].len = pinfo->dst.len;
1050       cksum_vec[2].ptr = (const guint8 *)&phdr;
1051       switch (pinfo->src.type) {
1052
1053       case AT_IPv4:
1054         phdr[0] = htonl((IP_PROTO_TCP<<16) + reported_len);
1055         cksum_vec[2].len = 4;
1056         break;
1057
1058       case AT_IPv6:
1059         phdr[0] = htonl(reported_len);
1060         phdr[1] = htonl(IP_PROTO_TCP);
1061         cksum_vec[2].len = 8;
1062         break;
1063
1064       default:
1065         /* TCP runs only atop IPv4 and IPv6.... */
1066         g_assert_not_reached();
1067         break;
1068       }
1069       cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
1070       cksum_vec[3].len = reported_len;
1071       computed_cksum = in_cksum(&cksum_vec[0], 4);
1072       if (computed_cksum == 0) {
1073         proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1074           offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
1075
1076         /* Checksum is valid, so we're willing to desegment it. */
1077         desegment_ok = TRUE;
1078       } else {
1079         proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
1080            offset + 16, 2, TRUE);
1081         proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1082            offset + 16, 2, th_sum,
1083            "Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
1084            in_cksum_shouldbe(th_sum, computed_cksum));
1085
1086         /* Checksum is invalid, so we're not willing to desegment it. */
1087         desegment_ok = FALSE;
1088       }
1089     } else {
1090       proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1091          offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1092
1093       /* We didn't check the checksum, and don't care if it's valid,
1094          so we're willing to desegment it. */
1095       desegment_ok = TRUE;
1096     }
1097   } else {
1098     /* We don't have all the packet data, so we can't checksum it... */
1099     proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1100        offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1101
1102     /* ...and aren't willing to desegment it. */
1103     desegment_ok = FALSE;
1104   }
1105
1106   if (desegment_ok) {
1107     /* We're willing to desegment this.  Is desegmentation enabled? */
1108     if (tcp_desegment) {
1109       /* Yes - is this segment being returned in an error packet? */
1110       if (!pinfo->in_error_pkt) {
1111         /* No - indicate that we will desegment.
1112            We do NOT want to desegment segments returned in error
1113            packets, as they're not part of a TCP connection. */
1114         pinfo->can_desegment = 2;
1115       }
1116     }
1117   }
1118
1119   if (th_flags & TH_URG) {
1120     th_urp = tvb_get_ntohs(tvb, offset + 18);
1121     /* Export the urgent pointer, for the benefit of protocols such as
1122        rlogin. */
1123     tcpinfo.urgent = TRUE;
1124     tcpinfo.urgent_pointer = th_urp;
1125     if (check_col(pinfo->cinfo, COL_INFO))
1126       col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
1127     if (tcp_tree != NULL)
1128       proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
1129   } else
1130     tcpinfo.urgent = FALSE;
1131
1132   if (check_col(pinfo->cinfo, COL_INFO))
1133     col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", seglen);
1134
1135   /* Decode TCP options, if any. */
1136   if (tree && hlen > TCPH_MIN_LEN) {
1137     /* There's more than just the fixed-length header.  Decode the
1138        options. */
1139     optlen = hlen - TCPH_MIN_LEN; /* length of options, in bytes */
1140     tf = proto_tree_add_text(tcp_tree, tvb, offset +  20, optlen,
1141       "Options: (%u bytes)", optlen);
1142     field_tree = proto_item_add_subtree(tf, ett_tcp_options);
1143     dissect_ip_tcp_options(tvb, offset + 20, optlen,
1144       tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
1145   }
1146
1147   /* Skip over header + options */
1148   offset += hlen;
1149
1150   pinfo->ptype = PT_TCP;
1151   pinfo->srcport = th_sport;
1152   pinfo->destport = th_dport;
1153   
1154   /* Check the packet length to see if there's more data
1155      (it could be an ACK-only packet) */
1156   length_remaining = tvb_length_remaining(tvb, offset);
1157   if (length_remaining != 0) {
1158     if (th_flags & TH_RST) {
1159       /*
1160        * RFC1122 says:
1161        *
1162        *        4.2.2.12  RST Segment: RFC-793 Section 3.4
1163        *
1164        *          A TCP SHOULD allow a received RST segment to include data.
1165        *
1166        *          DISCUSSION
1167        *               It has been suggested that a RST segment could contain
1168        *               ASCII text that encoded and explained the cause of the
1169        *               RST.  No standard has yet been established for such
1170        *               data.
1171        *
1172        * so for segments with RST we just display the data as text.
1173        */
1174       proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
1175                             "Reset cause: %s",
1176                             tvb_format_text(tvb, offset, length_remaining));
1177     } else {
1178       /* Can we desegment this segment? */
1179       if (pinfo->can_desegment) {
1180         /* Yes. */
1181         desegment_tcp(tvb, pinfo, offset, th_seq, nxtseq, th_sport, th_dport, tree, tcp_tree);
1182       } else {
1183         /* No - just call the subdissector.
1184            Mark this as fragmented, so if somebody throws an exception,
1185            we don't report it as a malformed frame. */
1186         save_fragmented = pinfo->fragmented;
1187         pinfo->fragmented = TRUE;
1188         decode_tcp_ports(tvb, offset, pinfo, tree, th_sport, th_dport);
1189         pinfo->fragmented = save_fragmented;
1190       }
1191     }
1192   }
1193  
1194   if( data_out_file ) {
1195     reassemble_tcp( th_seq,             /* sequence number */
1196         seglen,                         /* data length */
1197         tvb_get_ptr(tvb, offset, length_remaining),     /* data */
1198         length_remaining,               /* captured data length */
1199         ( th_flags & TH_SYN ),          /* is syn set? */
1200         &pinfo->net_src,
1201         &pinfo->net_dst,
1202         pinfo->srcport,
1203         pinfo->destport);
1204   }
1205 }
1206
1207 void
1208 proto_register_tcp(void)
1209 {
1210         static hf_register_info hf[] = {
1211
1212                 { &hf_tcp_srcport,
1213                 { "Source Port",                "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
1214                         "", HFILL }},
1215
1216                 { &hf_tcp_dstport,
1217                 { "Destination Port",           "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
1218                         "", HFILL }},
1219
1220                 { &hf_tcp_port,
1221                 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
1222                         "", HFILL }},
1223
1224                 { &hf_tcp_seq,
1225                 { "Sequence number",            "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
1226                         "", HFILL }},
1227
1228                 { &hf_tcp_nxtseq,
1229                 { "Next sequence number",       "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
1230                         "", HFILL }},
1231
1232                 { &hf_tcp_ack,
1233                 { "Acknowledgement number",     "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
1234                         "", HFILL }},
1235
1236                 { &hf_tcp_hdr_len,
1237                 { "Header Length",              "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1238                         "", HFILL }},
1239
1240                 { &hf_tcp_flags,
1241                 { "Flags",                      "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1242                         "", HFILL }},
1243
1244                 { &hf_tcp_flags_cwr,
1245                 { "Congestion Window Reduced (CWR)",                    "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
1246                         "", HFILL }},
1247
1248                 { &hf_tcp_flags_ecn,
1249                 { "ECN-Echo",                   "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
1250                         "", HFILL }},
1251
1252                 { &hf_tcp_flags_urg,
1253                 { "Urgent",                     "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
1254                         "", HFILL }},
1255
1256                 { &hf_tcp_flags_ack,
1257                 { "Acknowledgment",             "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
1258                         "", HFILL }},
1259
1260                 { &hf_tcp_flags_push,
1261                 { "Push",                       "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
1262                         "", HFILL }},
1263
1264                 { &hf_tcp_flags_reset,
1265                 { "Reset",                      "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
1266                         "", HFILL }},
1267
1268                 { &hf_tcp_flags_syn,
1269                 { "Syn",                        "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
1270                         "", HFILL }},
1271
1272                 { &hf_tcp_flags_fin,
1273                 { "Fin",                        "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
1274                         "", HFILL }},
1275
1276                 { &hf_tcp_window_size,
1277                 { "Window size",                "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1278                         "", HFILL }},
1279
1280                 { &hf_tcp_checksum,
1281                 { "Checksum",                   "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1282                         "", HFILL }},
1283
1284                 { &hf_tcp_checksum_bad,
1285                 { "Bad Checksum",               "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1286                         "", HFILL }},
1287
1288                 { &hf_tcp_urgent_pointer,
1289                 { "Urgent pointer",             "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
1290                         "", HFILL }},
1291         };
1292         static gint *ett[] = {
1293                 &ett_tcp,
1294                 &ett_tcp_flags,
1295                 &ett_tcp_options,
1296                 &ett_tcp_option_sack,
1297                 &ett_tcp_segments,
1298         };
1299         module_t *tcp_module;
1300
1301         proto_tcp = proto_register_protocol("Transmission Control Protocol",
1302             "TCP", "tcp");
1303         proto_register_field_array(proto_tcp, hf, array_length(hf));
1304         proto_register_subtree_array(ett, array_length(ett));
1305
1306         /* subdissector code */
1307         subdissector_table = register_dissector_table("tcp.port",
1308             "TCP port", FT_UINT16, BASE_DEC);
1309         register_heur_dissector_list("tcp", &heur_subdissector_list);
1310
1311         /* Register configuration preferences */
1312         tcp_module = prefs_register_protocol(proto_tcp, NULL);
1313         prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
1314             "Show TCP summary in protocol tree",
1315 "Whether the TCP summary line should be shown in the protocol tree",
1316             &tcp_summary_in_tree);
1317         prefs_register_bool_preference(tcp_module, "check_checksum",
1318             "Check the validity of the TCP checksum when possible",
1319 "Whether to check the validity of the TCP checksum",
1320             &tcp_check_checksum);
1321         prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
1322             "Allow subdissector to desegment TCP streams",
1323 "Whether subdissector can request TCP streams to be desegmented",
1324             &tcp_desegment);
1325
1326         register_init_routine(tcp_desegment_init);
1327         register_init_routine(tcp_fragment_init);
1328 }
1329
1330 void
1331 proto_reg_handoff_tcp(void)
1332 {
1333         dissector_handle_t tcp_handle;
1334
1335         tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
1336         dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
1337         data_handle = find_dissector("data");
1338 }