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