539870e949915cdd59df5080acaf19a003716fa9
[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.126 2002/01/18 22:35:19 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 "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 "conversation.h"
53 #include "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                 /* first we show a tree with all segments */
369                 si = proto_tree_add_text(tcp_tree, tvb, 0, 0,
370                                 "Segments");
371                 st = proto_item_add_subtree(si, ett_tcp_segments);
372                 for(ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
373                         proto_tree_add_text(st, tvb, 0, 0,
374                                 "Frame:%u  seq#:%u-%u [%u-%u]",
375                                 ipfd->frame,
376                                 tsk->start_seq + ipfd->offset,
377                                 tsk->start_seq + ipfd->offset + ipfd->len - 1,
378                                 ipfd->offset,
379                                 ipfd->offset + ipfd->len - 1); 
380                 }
381
382                 /*
383                  * We only call subdissector for the last segment.
384                  * Note that the last segment may include more than what
385                  * we needed.
386                  */
387                 if(nxtseq >= (tsk->start_seq + tsk->tot_len)){
388                         /* ok, lest call subdissector with desegmented data */
389                         tvbuff_t *next_tvb;
390
391                         /* create a new TVB structure for desegmented data */
392                         next_tvb = tvb_new_real_data(ipfd_head->data,
393                                         ipfd_head->datalen, ipfd_head->datalen,
394                                         "Desegmented");
395
396                         /* add this tvb as a child to the original one */
397                         tvb_set_child_real_data_tvbuff(tvb, next_tvb);
398
399                         /* add desegmented data to the data source list */
400                         pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
401
402                         /* indicate that this is reassembled data */
403                         tcpinfo->is_reassembled = TRUE;
404
405                         /* call subdissector */
406                         decode_tcp_ports(next_tvb, 0, pinfo, tree,
407                                 sport, dport);
408                         called_dissector = TRUE;
409
410                         /* Did the subdissector ask us to desegment some more
411                            data?  This means that the data at the beginning
412                            of this segment completed a higher-level PDU,
413                            but the data at the end of this segment started
414                            a higher-level PDU but didn't complete it.
415
416                            If so we have to create some structures in our
417                            table but this is something we only do the first
418                            time we see this packet.
419                         */
420                         if(pinfo->desegment_len) {
421                                 if (!pinfo->fd->flags.visited)
422                                         must_desegment = TRUE;
423
424                                 /*
425                                  * The stuff we couldn't dissect must have
426                                  * come from this segment, so it's all in
427                                  * "tvb".
428                                  *
429                                  * "pinfo->desegment_offset" is relative
430                                  * to the beginning of "next_tvb";
431                                  * we want an offset relative to the
432                                  * beginning of "tvb".
433                                  *
434                                  * First, compute the offset relative to
435                                  * the *end* of "next_tvb" - i.e., the number
436                                  * of bytes before the end of "next_tvb"
437                                  * at which the subdissector stopped.
438                                  * That's the length of "next_tvb" minus
439                                  * the offset, relative to the beginning
440                                  * of "next_tvb, at which the subdissector
441                                  * stopped.
442                                  */
443                                 deseg_offset =
444                                     ipfd_head->datalen - pinfo->desegment_offset;
445
446                                 /*
447                                  * "tvb" and "next_tvb" end at the same byte
448                                  * of data, so the offset relative to the
449                                  * end of "next_tvb" of the byte at which
450                                  * we stopped is also the offset relative
451                                  * to the end of "tvb" of the byte at which
452                                  * we stopped.
453                                  *
454                                  * Convert that back into an offset relative
455                                  * to the beginninng of "tvb", by taking
456                                  * the length of "tvb" and subtracting the
457                                  * offset relative to the end.
458                                  */
459                                 deseg_offset = tvb_length(tvb) - deseg_offset;
460                         }
461                 }
462         }
463
464         if (must_desegment) {
465             tcp_segment_key *tsk, *new_tsk;
466
467             /*
468              * The sequence number at which the stuff to be desegmented
469              * starts is the sequence number of the byte at an offset
470              * of "deseg_offset" into "tvb".
471              *
472              * The sequence number of the byte at an offset of "offset"
473              * is "seq", i.e. the starting sequence number of this
474              * segment, so the sequence number of the byte at
475              * "deseg_offset" is "seq + (deseg_offset - offset)".
476              */
477             deseg_seq = seq + (deseg_offset - offset);
478
479             /*
480              * XXX - how do we detect out-of-order transmissions?
481              * We can't just check for "nxtseq" being greater than
482              * "tsk->start_seq"; for now, we check for the difference
483              * being less than a megabyte, but this is a really
484              * gross hack - we really need to handle out-of-order
485              * transmissions correctly.
486              */
487             if ((nxtseq - deseg_seq) <= 1024*1024) {
488                 /* OK, subdissector wants us to desegment
489                    some data before it can process it. Add
490                    what remains of this packet and set
491                    up next packet/sequence number as well.
492
493                    We must remember this segment
494                 */
495                 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
496                 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
497                 COPY_ADDRESS(tsk->src, &pinfo->src);
498                 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
499                 COPY_ADDRESS(tsk->dst, &pinfo->dst);
500                 tsk->seq = deseg_seq;
501                 tsk->start_seq = tsk->seq;
502                 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
503                 tsk->first_frame = pinfo->fd->num;
504                 g_hash_table_insert(tcp_segment_table, tsk, tsk);
505
506                 /* Add portion of segment unprocessed by the subdissector
507                    to defragmentation lists */
508                 fragment_add(tvb, deseg_offset, pinfo, tsk->start_seq,
509                     tcp_fragment_table,
510                     tsk->seq - tsk->start_seq,
511                     nxtseq - tsk->start_seq,
512                     (nxtseq < tsk->start_seq + tsk->tot_len));
513
514                 /* this is the next segment in the sequence we want */
515                 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
516                 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
517                 new_tsk->seq = nxtseq;
518                 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
519             }
520         }
521
522         if (!called_dissector || pinfo->desegment_len != 0) {
523                 /*
524                  * Either we didn't call the subdissector at all (i.e.,
525                  * this is a segment that contains the middle of a
526                  * higher-level PDU, but contains neither the beginning
527                  * nor the end), or the subdissector couldn't dissect it
528                  * all, as some data was missing (i.e., it set
529                  * "pinfo->desegment_len" to the amount of additional
530                  * data it needs).
531                  */
532                 if (pinfo->desegment_offset == 0) {
533                         /*
534                          * It couldn't, in fact, dissect any of it (the
535                          * first byte it couldn't dissect is at an offset
536                          * of "pinfo->desegment_offset" from the beginning
537                          * of the payload, and that's 0).
538                          * Just mark this as TCP.
539                          */
540                         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
541                                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
542                         }
543                         if (check_col(pinfo->cinfo, COL_INFO)){
544                                 col_set_str(pinfo->cinfo, COL_INFO, "[Desegmented TCP]");
545                         }
546                 }
547
548                 /*
549                  * Show what's left in the packet as data.
550                  * XXX - remember what protocol the last subdissector
551                  * was, and report it as a continuation of that, instead.
552                  */
553                 call_dissector(data_handle,tvb_new_subset(tvb, deseg_offset,-1,tvb_reported_length_remaining(tvb,deseg_offset)), pinfo, tree);
554         }
555         pinfo->can_desegment=0;
556         pinfo->desegment_offset = 0;
557         pinfo->desegment_len = 0;
558 }
559
560
561
562
563 static void
564 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
565 {
566   if (check_col(pinfo->cinfo, COL_INFO))
567     col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
568 }
569
570 static void
571 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
572     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
573 {
574   guint16 mss;
575
576   mss = tvb_get_ntohs(tvb, offset + 2);
577   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
578                         "%s: %u bytes", optp->name, mss);
579   tcp_info_append_uint(pinfo, "MSS", mss);
580 }
581
582 static void
583 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
584     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
585 {
586   guint8 ws;
587
588   ws = tvb_get_guint8(tvb, offset + 2);
589   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
590                         "%s: %u bytes", optp->name, ws);
591   tcp_info_append_uint(pinfo, "WS", ws);
592 }
593
594 static void
595 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
596     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
597 {
598   proto_tree *field_tree = NULL;
599   proto_item *tf;
600   guint leftedge, rightedge;
601
602   tf = proto_tree_add_text(opt_tree, tvb, offset,      optlen, "%s:", optp->name);
603   offset += 2;  /* skip past type and length */
604   optlen -= 2;  /* subtract size of type and length */
605   while (optlen > 0) {
606     if (field_tree == NULL) {
607       /* Haven't yet made a subtree out of this option.  Do so. */
608       field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
609     }
610     if (optlen < 4) {
611       proto_tree_add_text(field_tree, tvb, offset,      optlen,
612         "(suboption would go past end of option)");
613       break;
614     }
615     leftedge = tvb_get_ntohl(tvb, offset);
616     optlen -= 4;
617     if (optlen < 4) {
618       proto_tree_add_text(field_tree, tvb, offset,      optlen,
619         "(suboption would go past end of option)");
620       break;
621     }
622     /* XXX - check whether it goes past end of packet */
623     rightedge = tvb_get_ntohl(tvb, offset + 4);
624     optlen -= 4;
625     proto_tree_add_text(field_tree, tvb, offset,      8,
626         "left edge = %u, right edge = %u", leftedge, rightedge);
627     tcp_info_append_uint(pinfo, "SLE", leftedge);
628     tcp_info_append_uint(pinfo, "SRE", rightedge);
629     offset += 8;
630   }
631 }
632
633 static void
634 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
635     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
636 {
637   guint32 echo;
638
639   echo = tvb_get_ntohl(tvb, offset + 2);
640   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
641                         "%s: %u", optp->name, echo);
642   tcp_info_append_uint(pinfo, "ECHO", echo);
643 }
644
645 static void
646 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
647     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
648 {
649   guint32 tsv, tser;
650
651   tsv = tvb_get_ntohl(tvb, offset + 2);
652   tser = tvb_get_ntohl(tvb, offset + 6);
653   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
654     "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
655   tcp_info_append_uint(pinfo, "TSV", tsv);
656   tcp_info_append_uint(pinfo, "TSER", tser);
657 }
658
659 static void
660 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
661     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
662 {
663   guint32 cc;
664
665   cc = tvb_get_ntohl(tvb, offset + 2);
666   proto_tree_add_text(opt_tree, tvb, offset,      optlen,
667                         "%s: %u", optp->name, cc);
668   tcp_info_append_uint(pinfo, "CC", cc);
669 }
670
671 static const ip_tcp_opt tcpopts[] = {
672   {
673     TCPOPT_EOL,
674     "EOL",
675     NULL,
676     NO_LENGTH,
677     0,
678     NULL,
679   },
680   {
681     TCPOPT_NOP,
682     "NOP",
683     NULL,
684     NO_LENGTH,
685     0,
686     NULL,
687   },
688   {
689     TCPOPT_MSS,
690     "Maximum segment size",
691     NULL,
692     FIXED_LENGTH,
693     TCPOLEN_MSS,
694     dissect_tcpopt_maxseg
695   },
696   {
697     TCPOPT_WINDOW,
698     "Window scale",
699     NULL,
700     FIXED_LENGTH,
701     TCPOLEN_WINDOW,
702     dissect_tcpopt_wscale
703   },
704   {
705     TCPOPT_SACK_PERM,
706     "SACK permitted",
707     NULL,
708     FIXED_LENGTH,
709     TCPOLEN_SACK_PERM,
710     NULL,
711   },
712   {
713     TCPOPT_SACK,
714     "SACK",
715     &ett_tcp_option_sack,
716     VARIABLE_LENGTH,
717     TCPOLEN_SACK_MIN,
718     dissect_tcpopt_sack
719   },
720   {
721     TCPOPT_ECHO,
722     "Echo",
723     NULL,
724     FIXED_LENGTH,
725     TCPOLEN_ECHO,
726     dissect_tcpopt_echo
727   },
728   {
729     TCPOPT_ECHOREPLY,
730     "Echo reply",
731     NULL,
732     FIXED_LENGTH,
733     TCPOLEN_ECHOREPLY,
734     dissect_tcpopt_echo
735   },
736   {
737     TCPOPT_TIMESTAMP,
738     "Time stamp",
739     NULL,
740     FIXED_LENGTH,
741     TCPOLEN_TIMESTAMP,
742     dissect_tcpopt_timestamp
743   },
744   {
745     TCPOPT_CC,
746     "CC",
747     NULL,
748     FIXED_LENGTH,
749     TCPOLEN_CC,
750     dissect_tcpopt_cc
751   },
752   {
753     TCPOPT_CCNEW,
754     "CC.NEW",
755     NULL,
756     FIXED_LENGTH,
757     TCPOLEN_CCNEW,
758     dissect_tcpopt_cc
759   },
760   {
761     TCPOPT_CCECHO,
762     "CC.ECHO",
763     NULL,
764     FIXED_LENGTH,
765     TCPOLEN_CCECHO,
766     dissect_tcpopt_cc
767   },
768   {
769     TCPOPT_MD5,
770     "TCP MD5 signature",
771     NULL,
772     FIXED_LENGTH,
773     TCPOLEN_MD5,
774     NULL
775   }
776 };
777
778 #define N_TCP_OPTS      (sizeof tcpopts / sizeof tcpopts[0])
779
780 /* TCP flags flag */
781 static const true_false_string flags_set_truth = {
782   "Set",
783   "Not set"
784 };
785
786
787 /* Determine if there is a sub-dissector and call it.  This has been */
788 /* separated into a stand alone routine to other protocol dissectors */
789 /* can call to it, ie. socks    */
790
791 void
792 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
793         proto_tree *tree, int src_port, int dst_port)
794 {
795   tvbuff_t *next_tvb;
796
797   next_tvb = tvb_new_subset(tvb, offset, -1, -1);
798
799 /* determine if this packet is part of a conversation and call dissector */
800 /* for the conversation if available */
801
802   if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
803                 src_port, dst_port, next_tvb, pinfo, tree))
804     return;
805
806   /* do lookup with the subdissector table */
807   if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
808       dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
809     return;
810
811   /* do lookup with the heuristic subdissector table */
812   if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
813     return;
814
815   /* Oh, well, we don't know this; dissect it as data. */
816   call_dissector(data_handle,next_tvb, pinfo, tree);
817 }
818
819
820 static void
821 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
822 {
823   guint16 th_sport;
824   guint16 th_dport;
825   guint32 th_seq;
826   guint32 th_ack;
827   guint8  th_off_x2; /* combines th_off and th_x2 */
828   guint8  th_flags;
829   guint16 th_win;
830   guint16 th_sum;
831   guint16 th_urp;
832   proto_tree *tcp_tree = NULL, *field_tree = NULL;
833   proto_item *ti = NULL, *tf;
834   int        offset = 0;
835   gchar      flags[64] = "<None>";
836   gchar     *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
837   gint       fpos = 0, i;
838   guint      bpos;
839   guint      hlen;
840   guint      optlen;
841   guint32    seglen;
842   guint32    nxtseq;
843   guint      len;
844   guint      reported_len;
845   vec_t      cksum_vec[4];
846   guint32    phdr[2];
847   guint16    computed_cksum;
848   guint      length_remaining;
849   gboolean   desegment_ok;
850   struct tcpinfo tcpinfo;
851   gboolean   save_fragmented;
852
853   if (check_col(pinfo->cinfo, COL_PROTOCOL))
854     col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
855
856   /* Clear out the Info column. */
857   if (check_col(pinfo->cinfo, COL_INFO))
858     col_clear(pinfo->cinfo, COL_INFO);
859
860   th_sport = tvb_get_ntohs(tvb, offset);
861   th_dport = tvb_get_ntohs(tvb, offset + 2);
862   if (check_col(pinfo->cinfo, COL_INFO)) {
863     col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
864       get_tcp_port(th_sport), get_tcp_port(th_dport));
865   }
866   
867   if (tree) {
868     if (tcp_summary_in_tree) {
869             ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0,
870                 tvb_length(tvb),
871                 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
872                 get_tcp_port(th_sport), th_sport,
873                 get_tcp_port(th_dport), th_dport);
874     }
875     else {
876             ti = proto_tree_add_item(tree, proto_tcp, tvb, 0,
877                 tvb_length(tvb), FALSE);
878     }
879     tcp_tree = proto_item_add_subtree(ti, ett_tcp);
880     proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th_sport,
881         "Source port: %s (%u)", get_tcp_port(th_sport), th_sport);
882     proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th_dport,
883         "Destination port: %s (%u)", get_tcp_port(th_dport), th_dport);
884     proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th_sport);
885     proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th_dport);
886   }
887
888   th_seq = tvb_get_ntohl(tvb, offset + 4);
889   th_ack = tvb_get_ntohl(tvb, offset + 8);
890   th_off_x2 = tvb_get_guint8(tvb, offset + 12);
891   th_flags = tvb_get_guint8(tvb, offset + 13);
892   th_win = tvb_get_ntohs(tvb, offset + 14);
893   
894   if (check_col(pinfo->cinfo, COL_INFO) || tree) {  
895     for (i = 0; i < 8; i++) {
896       bpos = 1 << i;
897       if (th_flags & bpos) {
898         if (fpos) {
899           strcpy(&flags[fpos], ", ");
900           fpos += 2;
901         }
902         strcpy(&flags[fpos], fstr[i]);
903         fpos += 3;
904       }
905     }
906     flags[fpos] = '\0';
907   }
908
909   if (check_col(pinfo->cinfo, COL_INFO)) {
910     col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
911       flags, th_seq, th_ack, th_win);
912   }
913
914   if (tree) {
915     if (tcp_summary_in_tree)
916       proto_item_append_text(ti, ", Seq: %u", th_seq);
917     proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th_seq);
918   }
919
920   hlen = hi_nibble(th_off_x2) * 4;  /* TCP header length, in bytes */
921
922   if (hlen < TCPH_MIN_LEN) {
923     /* Give up at this point; we put the source and destination port in
924        the tree, before fetching the header length, so that they'll
925        show up if this is in the failing packet in an ICMP error packet,
926        but it's now time to give up if the header length is bogus. */
927     if (check_col(pinfo->cinfo, COL_INFO))
928       col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
929         hlen, TCPH_MIN_LEN);
930     if (tree) {
931       proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
932        "Header length: %u bytes (bogus, must be at least %u)", hlen,
933        TCPH_MIN_LEN);
934     }
935     return;
936   }
937
938   reported_len = tvb_reported_length(tvb);
939   len = tvb_length(tvb);
940
941   /* Compute the length of data in this segment. */
942   seglen = reported_len - hlen;
943
944   /* Compute the sequence number of next octet after this segment. */
945   nxtseq = th_seq + seglen;
946
947   if (tree) {
948     if (tcp_summary_in_tree)
949       proto_item_append_text(ti, ", Ack: %u", th_ack);
950     proto_item_set_len(ti, hlen);
951     if (nxtseq != th_seq)
952       proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
953     if (th_flags & TH_ACK)
954       proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th_ack);
955     proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
956         "Header length: %u bytes", hlen);
957     tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
958         th_flags, "Flags: 0x%04x (%s)", th_flags, flags);
959     field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
960     proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th_flags);
961     proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th_flags);
962     proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th_flags);
963     proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th_flags);
964     proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th_flags);
965     proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th_flags);
966     proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th_flags);
967     proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th_flags);
968     proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th_win);
969   }
970
971   /* Assume we'll pass un-reassembled data to subdissectors. */
972   tcpinfo.is_reassembled = FALSE;
973
974   pinfo->private_data = &tcpinfo;
975
976   /*
977    * Assume, initially, that we can't desegment.
978    */
979   pinfo->can_desegment = 0;
980
981   th_sum = tvb_get_ntohs(tvb, offset + 16);
982   if (!pinfo->fragmented && len >= reported_len) {
983     /* The packet isn't part of an un-reassembled fragmented datagram
984        and isn't truncated.  This means we have all the data, and thus
985        can checksum it and, unless it's being returned in an error
986        packet, are willing to allow subdissectors to request reassembly
987        on it. */
988   
989     if (tcp_check_checksum) {
990       /* We haven't turned checksum checking off; checksum it. */
991
992       /* Set up the fields of the pseudo-header. */
993       cksum_vec[0].ptr = pinfo->src.data;
994       cksum_vec[0].len = pinfo->src.len;
995       cksum_vec[1].ptr = pinfo->dst.data;
996       cksum_vec[1].len = pinfo->dst.len;
997       cksum_vec[2].ptr = (const guint8 *)&phdr;
998       switch (pinfo->src.type) {
999
1000       case AT_IPv4:
1001         phdr[0] = htonl((IP_PROTO_TCP<<16) + reported_len);
1002         cksum_vec[2].len = 4;
1003         break;
1004
1005       case AT_IPv6:
1006         phdr[0] = htonl(reported_len);
1007         phdr[1] = htonl(IP_PROTO_TCP);
1008         cksum_vec[2].len = 8;
1009         break;
1010
1011       default:
1012         /* TCP runs only atop IPv4 and IPv6.... */
1013         g_assert_not_reached();
1014         break;
1015       }
1016       cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
1017       cksum_vec[3].len = reported_len;
1018       computed_cksum = in_cksum(&cksum_vec[0], 4);
1019       if (computed_cksum == 0) {
1020         proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1021           offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
1022
1023         /* Checksum is valid, so we're willing to desegment it. */
1024         desegment_ok = TRUE;
1025       } else {
1026         proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
1027            offset + 16, 2, TRUE);
1028         proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1029            offset + 16, 2, th_sum,
1030            "Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
1031            in_cksum_shouldbe(th_sum, computed_cksum));
1032
1033         /* Checksum is invalid, so we're not willing to desegment it. */
1034         desegment_ok = FALSE;
1035       }
1036     } else {
1037       proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1038          offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1039
1040       /* We didn't check the checksum, and don't care if it's valid,
1041          so we're willing to desegment it. */
1042       desegment_ok = TRUE;
1043     }
1044   } else {
1045     /* We don't have all the packet data, so we can't checksum it... */
1046     proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1047        offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1048
1049     /* ...and aren't willing to desegment it. */
1050     desegment_ok = FALSE;
1051   }
1052
1053   if (desegment_ok) {
1054     /* We're willing to desegment this.  Is desegmentation enabled? */
1055     if (tcp_desegment) {
1056       /* Yes - is this segment being returned in an error packet? */
1057       if (!pinfo->in_error_pkt) {
1058         /* No - indicate that we will desegment.
1059            We do NOT want to desegment segments returned in error
1060            packets, as they're not part of a TCP connection. */
1061         pinfo->can_desegment = 2;
1062       }
1063     }
1064   }
1065
1066   if (th_flags & TH_URG) {
1067     th_urp = tvb_get_ntohs(tvb, offset + 18);
1068     /* Export the urgent pointer, for the benefit of protocols such as
1069        rlogin. */
1070     tcpinfo.urgent = TRUE;
1071     tcpinfo.urgent_pointer = th_urp;
1072     if (check_col(pinfo->cinfo, COL_INFO))
1073       col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
1074     if (tcp_tree != NULL)
1075       proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
1076   } else
1077     tcpinfo.urgent = FALSE;
1078
1079   if (check_col(pinfo->cinfo, COL_INFO))
1080     col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", seglen);
1081
1082   /* Decode TCP options, if any. */
1083   if (tree && hlen > TCPH_MIN_LEN) {
1084     /* There's more than just the fixed-length header.  Decode the
1085        options. */
1086     optlen = hlen - TCPH_MIN_LEN; /* length of options, in bytes */
1087     tf = proto_tree_add_text(tcp_tree, tvb, offset +  20, optlen,
1088       "Options: (%u bytes)", optlen);
1089     field_tree = proto_item_add_subtree(tf, ett_tcp_options);
1090     dissect_ip_tcp_options(tvb, offset + 20, optlen,
1091       tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
1092   }
1093
1094   /* Skip over header + options */
1095   offset += hlen;
1096
1097   pinfo->ptype = PT_TCP;
1098   pinfo->srcport = th_sport;
1099   pinfo->destport = th_dport;
1100   
1101   /* Check the packet length to see if there's more data
1102      (it could be an ACK-only packet) */
1103   length_remaining = tvb_length_remaining(tvb, offset);
1104   if (length_remaining != 0) {
1105     if (th_flags & TH_RST) {
1106       /*
1107        * RFC1122 says:
1108        *
1109        *        4.2.2.12  RST Segment: RFC-793 Section 3.4
1110        *
1111        *          A TCP SHOULD allow a received RST segment to include data.
1112        *
1113        *          DISCUSSION
1114        *               It has been suggested that a RST segment could contain
1115        *               ASCII text that encoded and explained the cause of the
1116        *               RST.  No standard has yet been established for such
1117        *               data.
1118        *
1119        * so for segments with RST we just display the data as text.
1120        */
1121       proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
1122                             "Reset cause: %s",
1123                             tvb_format_text(tvb, offset, length_remaining));
1124     } else {
1125       /* Can we desegment this segment? */
1126       if (pinfo->can_desegment) {
1127         /* Yes. */
1128         desegment_tcp(tvb, pinfo, offset, th_seq, nxtseq, th_sport, th_dport, tree, tcp_tree);
1129       } else {
1130         /* No - just call the subdissector.
1131            Mark this as fragmented, so if somebody throws an exception,
1132            we don't report it as a malformed frame. */
1133         save_fragmented = pinfo->fragmented;
1134         pinfo->fragmented = TRUE;
1135         decode_tcp_ports(tvb, offset, pinfo, tree, th_sport, th_dport);
1136         pinfo->fragmented = save_fragmented;
1137       }
1138     }
1139   }
1140  
1141   if( data_out_file ) {
1142     reassemble_tcp( th_seq,             /* sequence number */
1143         seglen,                         /* data length */
1144         tvb_get_ptr(tvb, offset, length_remaining),     /* data */
1145         length_remaining,               /* captured data length */
1146         ( th_flags & TH_SYN ),          /* is syn set? */
1147         &pinfo->net_src,
1148         &pinfo->net_dst,
1149         pinfo->srcport,
1150         pinfo->destport);
1151   }
1152 }
1153
1154 void
1155 proto_register_tcp(void)
1156 {
1157         static hf_register_info hf[] = {
1158
1159                 { &hf_tcp_srcport,
1160                 { "Source Port",                "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
1161                         "", HFILL }},
1162
1163                 { &hf_tcp_dstport,
1164                 { "Destination Port",           "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
1165                         "", HFILL }},
1166
1167                 { &hf_tcp_port,
1168                 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
1169                         "", HFILL }},
1170
1171                 { &hf_tcp_seq,
1172                 { "Sequence number",            "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
1173                         "", HFILL }},
1174
1175                 { &hf_tcp_nxtseq,
1176                 { "Next sequence number",       "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
1177                         "", HFILL }},
1178
1179                 { &hf_tcp_ack,
1180                 { "Acknowledgement number",     "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
1181                         "", HFILL }},
1182
1183                 { &hf_tcp_hdr_len,
1184                 { "Header Length",              "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1185                         "", HFILL }},
1186
1187                 { &hf_tcp_flags,
1188                 { "Flags",                      "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1189                         "", HFILL }},
1190
1191                 { &hf_tcp_flags_cwr,
1192                 { "Congestion Window Reduced (CWR)",                    "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
1193                         "", HFILL }},
1194
1195                 { &hf_tcp_flags_ecn,
1196                 { "ECN-Echo",                   "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
1197                         "", HFILL }},
1198
1199                 { &hf_tcp_flags_urg,
1200                 { "Urgent",                     "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
1201                         "", HFILL }},
1202
1203                 { &hf_tcp_flags_ack,
1204                 { "Acknowledgment",             "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
1205                         "", HFILL }},
1206
1207                 { &hf_tcp_flags_push,
1208                 { "Push",                       "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
1209                         "", HFILL }},
1210
1211                 { &hf_tcp_flags_reset,
1212                 { "Reset",                      "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
1213                         "", HFILL }},
1214
1215                 { &hf_tcp_flags_syn,
1216                 { "Syn",                        "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
1217                         "", HFILL }},
1218
1219                 { &hf_tcp_flags_fin,
1220                 { "Fin",                        "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
1221                         "", HFILL }},
1222
1223                 { &hf_tcp_window_size,
1224                 { "Window size",                "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1225                         "", HFILL }},
1226
1227                 { &hf_tcp_checksum,
1228                 { "Checksum",                   "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1229                         "", HFILL }},
1230
1231                 { &hf_tcp_checksum_bad,
1232                 { "Bad Checksum",               "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1233                         "", HFILL }},
1234
1235                 { &hf_tcp_urgent_pointer,
1236                 { "Urgent pointer",             "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
1237                         "", HFILL }},
1238         };
1239         static gint *ett[] = {
1240                 &ett_tcp,
1241                 &ett_tcp_flags,
1242                 &ett_tcp_options,
1243                 &ett_tcp_option_sack,
1244                 &ett_tcp_segments,
1245         };
1246         module_t *tcp_module;
1247
1248         proto_tcp = proto_register_protocol("Transmission Control Protocol",
1249             "TCP", "tcp");
1250         proto_register_field_array(proto_tcp, hf, array_length(hf));
1251         proto_register_subtree_array(ett, array_length(ett));
1252
1253         /* subdissector code */
1254         subdissector_table = register_dissector_table("tcp.port",
1255             "TCP port", FT_UINT16, BASE_DEC);
1256         register_heur_dissector_list("tcp", &heur_subdissector_list);
1257
1258         /* Register configuration preferences */
1259         tcp_module = prefs_register_protocol(proto_tcp, NULL);
1260         prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
1261             "Show TCP summary in protocol tree",
1262 "Whether the TCP summary line should be shown in the protocol tree",
1263             &tcp_summary_in_tree);
1264         prefs_register_bool_preference(tcp_module, "check_checksum",
1265             "Check the validity of the TCP checksum when possible",
1266 "Whether to check the validity of the TCP checksum",
1267             &tcp_check_checksum);
1268         prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
1269             "Allow subdissector to desegment TCP streams",
1270 "Whether subdissector can request TCP streams to be desegmented",
1271             &tcp_desegment);
1272
1273         register_init_routine(tcp_desegment_init);
1274         register_init_routine(tcp_fragment_init);
1275 }
1276
1277 void
1278 proto_reg_handoff_tcp(void)
1279 {
1280         dissector_handle_t tcp_handle;
1281
1282         tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
1283         dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
1284         data_handle = find_dissector("data");
1285 }