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