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