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