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