2 * Routines for TCP packet disassembly
4 * $Id: packet-tcp.c,v 1.130 2002/02/03 23:28:38 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
33 #ifdef HAVE_NETINET_IN_H
34 # include <netinet/in.h>
42 #ifdef NEED_SNPRINTF_H
43 # include "snprintf.h"
46 #include <epan/resolv.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"
56 /* Place TCP summary in proto tree */
57 static gboolean tcp_summary_in_tree = TRUE;
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
68 static gboolean tcp_check_checksum = TRUE;
70 extern FILE* data_out_file;
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;
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;
100 static dissector_table_t subdissector_table;
101 static heur_dissector_list_t heur_subdissector_list;
102 static dissector_handle_t data_handle;
104 /* TCP structs and definitions */
115 /* Minimum TCP header length. */
116 #define TCPH_MIN_LEN 20
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 */
132 #define TCPOPT_CCNEW 12
133 #define TCPOPT_CCECHO 13
134 #define TCPOPT_MD5 19 /* RFC2385 */
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
148 #define TCPOLEN_CCNEW 6
149 #define TCPOLEN_CCECHO 6
150 #define TCPOLEN_MD5 18
154 /* Desegmentation of TCP streams */
155 /* table to hold defragmented TCP streams */
156 static GHashTable *tcp_fragment_table = NULL;
158 tcp_fragment_init(void)
160 fragment_table_init(&tcp_fragment_table);
163 /* functions to trace tcp segments */
164 /* Enable desegmenting of TCP streams */
165 static gboolean tcp_desegment = FALSE;
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;
173 typedef struct _tcp_segment_key {
174 /* for ouwn bookkeeping inside packet-tcp.c */
185 free_all_segments(gpointer key_arg, gpointer value, gpointer user_data)
187 tcp_segment_key *key = key_arg;
189 if((key->src)&&(key->src->data)){
190 g_free((gpointer)key->src->data);
194 if((key->dst)&&(key->dst->data)){
195 g_free((gpointer)key->dst->data);
203 tcp_segment_hash(gconstpointer k)
205 tcp_segment_key *key = (tcp_segment_key *)k;
211 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
213 tcp_segment_key *key1 = (tcp_segment_key *)k1;
214 tcp_segment_key *key2 = (tcp_segment_key *)k2;
216 return ( ( (key1->seq==key2->seq)
217 &&(ADDRESSES_EQUAL(key1->src, key2->src))
218 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
223 tcp_desegment_init(void)
226 /* dont allocate any memory chunks unless the user really
233 if(tcp_segment_table){
234 g_hash_table_foreach_remove(tcp_segment_table,
235 free_all_segments, NULL);
237 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
241 if(tcp_segment_key_chunk){
242 g_mem_chunk_destroy(tcp_segment_key_chunk);
244 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
245 sizeof(tcp_segment_key),
246 tcp_segment_init_count*sizeof(tcp_segment_key),
249 if(tcp_segment_address_chunk){
250 g_mem_chunk_destroy(tcp_segment_address_chunk);
252 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
254 tcp_segment_address_init_count*sizeof(address),
259 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
260 guint32 seq, guint32 nxtseq,
261 guint32 sport, guint32 dport,
262 proto_tree *tree, proto_tree *tcp_tree)
264 struct tcpinfo *tcpinfo = pinfo->private_data;
265 fragment_data *ipfd_head;
266 tcp_segment_key old_tsk, *tsk;
267 gboolean must_desegment = FALSE;
268 gboolean called_dissector = FALSE;
273 * Initialize these to assume no desegmentation.
274 * If that's not the case, these will be set appropriately
275 * by the subdissector.
277 pinfo->desegment_offset = 0;
278 pinfo->desegment_len = 0;
281 * Initialize this to assume that this segment will just be
282 * added to the middle of a desegmented chunk of data, so
283 * that we should show it all as data.
284 * If that's not the case, it will be set appropriately.
286 deseg_offset = offset;
288 /* First we must check if this TCP segment should be desegmented.
289 This is only to check if we should desegment this packet,
290 so we dont spend time doing COPY_ADDRESS/g_free.
291 We just "borrow" some address structures from pinfo instead. Cheaper.
293 old_tsk.src = &pinfo->src;
294 old_tsk.dst = &pinfo->dst;
296 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
299 /* OK, this segment was found, which means it continues
300 a higher-level PDU. This means we must desegment it.
301 Add it to the defragmentation lists.
303 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->start_seq,
305 seq - tsk->start_seq,
307 (nxtseq < (tsk->start_seq + tsk->tot_len)) );
310 /* fragment_add() returned NULL, This means that
311 desegmentation is not completed yet.
312 (its like defragmentation but we know we will
313 always add the segments in order).
314 XXX - no, we don't; there is no guarantee that
315 TCP segments are in order on the wire.
317 we must add next segment to our table so we will
320 tcp_segment_key *new_tsk;
322 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
323 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
325 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
328 /* This segment was not found in our table, so it doesn't
329 contain a continuation of a higher-level PDU.
330 Call the normal subdissector.
332 decode_tcp_ports(tvb, offset, pinfo, tree,
334 called_dissector = TRUE;
336 /* Did the subdissector ask us to desegment some more data
337 before it could handle the packet?
338 If so we have to create some structures in our table but
339 this is something we only do the first time we see this
342 if(pinfo->desegment_len) {
343 if (!pinfo->fd->flags.visited)
344 must_desegment = TRUE;
347 * Set "deseg_offset" to the offset in "tvb"
348 * of the first byte of data that the
349 * subdissector didn't process.
351 deseg_offset = offset + pinfo->desegment_offset;
354 /* Either no desegmentation is necessary, or this is
355 segment contains the beginning but not the end of
356 a higher-level PDU and thus isn't completely
362 /* is it completely desegmented? */
365 proto_tree *st = NULL;
366 proto_item *si = NULL;
369 * Yes, we think it is.
370 * We only call subdissector for the last segment.
371 * Note that the last segment may include more than what
374 if(nxtseq >= (tsk->start_seq + tsk->tot_len)){
376 * OK, this is the last segment.
377 * Let's call the subdissector with the desegmented
383 /* create a new TVB structure for desegmented data */
384 next_tvb = tvb_new_real_data(ipfd_head->data,
385 ipfd_head->datalen, ipfd_head->datalen,
388 /* add this tvb as a child to the original one */
389 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
391 /* add desegmented data to the data source list */
392 pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
394 /* indicate that this is reassembled data */
395 tcpinfo->is_reassembled = TRUE;
397 /* call subdissector */
398 decode_tcp_ports(next_tvb, 0, pinfo, tree,
400 called_dissector = TRUE;
403 * OK, did the subdissector think it was completely
404 * desegmented, or does it think we need even more
407 old_len=(int)(tvb_reported_length(next_tvb)-tvb_reported_length_remaining(tvb, offset));
408 if(pinfo->desegment_len &&
409 pinfo->desegment_offset<=old_len){
410 tcp_segment_key *new_tsk;
413 * "desegment_len" isn't 0, so it needs more
414 * data for something - and "desegment_offset"
415 * is before "old_len", so it needs more data
416 * to dissect the stuff we thought was
417 * completely desegmented (as opposed to the
418 * stuff at the beginning being completely
419 * desegmented, but the stuff at the end
420 * being a new higher-level PDU that also
421 * needs desegmentation).
423 fragment_set_partial_reassembly(pinfo,tsk->start_seq,tcp_fragment_table);
424 tsk->tot_len = tvb_reported_length(next_tvb) + pinfo->desegment_len;
427 * Update tsk structure.
428 * Can ask ->next->next because at least there's a hdr and one
429 * entry in fragment_add()
431 for(ipfd=ipfd_head->next; ipfd->next; ipfd=ipfd->next){
432 old_tsk.seq = tsk->start_seq + ipfd->offset;
433 new_tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
434 new_tsk->tot_len = tsk->tot_len;
437 /* this is the next segment in the sequence we want */
438 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
439 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
440 new_tsk->seq = nxtseq;
441 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
444 * The subdissector thought it was completely
445 * desegmented (although the stuff at the
446 * end may, in turn, require desegmentation),
447 * so we show a tree with all segments.
449 si = proto_tree_add_text(tcp_tree, tvb, 0, 0,
451 st = proto_item_add_subtree(si, ett_tcp_segments);
452 for(ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
453 proto_tree_add_text(st, tvb, 0, 0,
454 "Frame:%u seq#:%u-%u [%u-%u]",
456 tsk->start_seq + ipfd->offset,
457 tsk->start_seq + ipfd->offset + ipfd->len-1,
459 ipfd->offset + ipfd->len - 1);
462 /* Did the subdissector ask us to desegment
463 some more data? This means that the data
464 at the beginning of this segment completed
465 a higher-level PDU, but the data at the
466 end of this segment started a higher-level
467 PDU but didn't complete it.
469 If so, we have to create some structures
470 in our table, but this is something we
471 only do the first time we see this packet.
473 if(pinfo->desegment_len) {
474 if (!pinfo->fd->flags.visited)
475 must_desegment = TRUE;
477 /* The stuff we couldn't dissect
478 must have come from this segment,
479 so it's all in "tvb".
481 "pinfo->desegment_offset" is
482 relative to the beginning of
483 "next_tvb"; we want an offset
484 relative to the beginning of "tvb".
486 First, compute the offset relative
487 to the *end* of "next_tvb" - i.e.,
488 the number of bytes before the end
489 of "next_tvb" at which the
490 subdissector stopped. That's the
491 length of "next_tvb" minus the
492 offset, relative to the beginning
493 of "next_tvb, at which the
494 subdissector stopped.
497 ipfd_head->datalen - pinfo->desegment_offset;
499 /* "tvb" and "next_tvb" end at the
500 same byte of data, so the offset
501 relative to the end of "next_tvb"
502 of the byte at which we stopped
503 is also the offset relative to
504 the end of "tvb" of the byte at
507 Convert that back into an offset
508 relative to the beginninng of
509 "tvb", by taking the length of
510 "tvb" and subtracting the offset
513 deseg_offset=tvb_reported_length(tvb) - deseg_offset;
519 if (must_desegment) {
520 tcp_segment_key *tsk, *new_tsk;
523 * The sequence number at which the stuff to be desegmented
524 * starts is the sequence number of the byte at an offset
525 * of "deseg_offset" into "tvb".
527 * The sequence number of the byte at an offset of "offset"
528 * is "seq", i.e. the starting sequence number of this
529 * segment, so the sequence number of the byte at
530 * "deseg_offset" is "seq + (deseg_offset - offset)".
532 deseg_seq = seq + (deseg_offset - offset);
535 * XXX - how do we detect out-of-order transmissions?
536 * We can't just check for "nxtseq" being greater than
537 * "tsk->start_seq"; for now, we check for the difference
538 * being less than a megabyte, but this is a really
539 * gross hack - we really need to handle out-of-order
540 * transmissions correctly.
542 if ((nxtseq - deseg_seq) <= 1024*1024) {
543 /* OK, subdissector wants us to desegment
544 some data before it can process it. Add
545 what remains of this packet and set
546 up next packet/sequence number as well.
548 We must remember this segment
550 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
551 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
552 COPY_ADDRESS(tsk->src, &pinfo->src);
553 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
554 COPY_ADDRESS(tsk->dst, &pinfo->dst);
555 tsk->seq = deseg_seq;
556 tsk->start_seq = tsk->seq;
557 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
558 tsk->first_frame = pinfo->fd->num;
559 g_hash_table_insert(tcp_segment_table, tsk, tsk);
561 /* Add portion of segment unprocessed by the subdissector
562 to defragmentation lists */
563 fragment_add(tvb, deseg_offset, pinfo, tsk->start_seq,
565 tsk->seq - tsk->start_seq,
566 nxtseq - tsk->start_seq,
567 (nxtseq < tsk->start_seq + tsk->tot_len));
569 /* this is the next segment in the sequence we want */
570 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
571 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
572 new_tsk->seq = nxtseq;
573 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
577 if (!called_dissector || pinfo->desegment_len != 0) {
579 * Either we didn't call the subdissector at all (i.e.,
580 * this is a segment that contains the middle of a
581 * higher-level PDU, but contains neither the beginning
582 * nor the end), or the subdissector couldn't dissect it
583 * all, as some data was missing (i.e., it set
584 * "pinfo->desegment_len" to the amount of additional
587 if (pinfo->desegment_offset == 0) {
589 * It couldn't, in fact, dissect any of it (the
590 * first byte it couldn't dissect is at an offset
591 * of "pinfo->desegment_offset" from the beginning
592 * of the payload, and that's 0).
593 * Just mark this as TCP.
595 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
596 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
598 if (check_col(pinfo->cinfo, COL_INFO)){
599 col_set_str(pinfo->cinfo, COL_INFO, "[Desegmented TCP]");
604 * Show what's left in the packet as data.
605 * XXX - remember what protocol the last subdissector
606 * was, and report it as a continuation of that, instead.
608 call_dissector(data_handle,tvb_new_subset(tvb, deseg_offset,-1,tvb_reported_length_remaining(tvb,deseg_offset)), pinfo, tree);
610 pinfo->can_desegment=0;
611 pinfo->desegment_offset = 0;
612 pinfo->desegment_len = 0;
619 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
621 if (check_col(pinfo->cinfo, COL_INFO))
622 col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
626 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
627 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
631 mss = tvb_get_ntohs(tvb, offset + 2);
632 proto_tree_add_text(opt_tree, tvb, offset, optlen,
633 "%s: %u bytes", optp->name, mss);
634 tcp_info_append_uint(pinfo, "MSS", mss);
638 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
639 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
643 ws = tvb_get_guint8(tvb, offset + 2);
644 proto_tree_add_text(opt_tree, tvb, offset, optlen,
645 "%s: %u bytes", optp->name, ws);
646 tcp_info_append_uint(pinfo, "WS", ws);
650 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
651 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
653 proto_tree *field_tree = NULL;
655 guint leftedge, rightedge;
657 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
658 offset += 2; /* skip past type and length */
659 optlen -= 2; /* subtract size of type and length */
661 if (field_tree == NULL) {
662 /* Haven't yet made a subtree out of this option. Do so. */
663 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
666 proto_tree_add_text(field_tree, tvb, offset, optlen,
667 "(suboption would go past end of option)");
670 leftedge = tvb_get_ntohl(tvb, offset);
673 proto_tree_add_text(field_tree, tvb, offset, optlen,
674 "(suboption would go past end of option)");
677 /* XXX - check whether it goes past end of packet */
678 rightedge = tvb_get_ntohl(tvb, offset + 4);
680 proto_tree_add_text(field_tree, tvb, offset, 8,
681 "left edge = %u, right edge = %u", leftedge, rightedge);
682 tcp_info_append_uint(pinfo, "SLE", leftedge);
683 tcp_info_append_uint(pinfo, "SRE", rightedge);
689 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
690 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
694 echo = tvb_get_ntohl(tvb, offset + 2);
695 proto_tree_add_text(opt_tree, tvb, offset, optlen,
696 "%s: %u", optp->name, echo);
697 tcp_info_append_uint(pinfo, "ECHO", echo);
701 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
702 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
706 tsv = tvb_get_ntohl(tvb, offset + 2);
707 tser = tvb_get_ntohl(tvb, offset + 6);
708 proto_tree_add_text(opt_tree, tvb, offset, optlen,
709 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
710 tcp_info_append_uint(pinfo, "TSV", tsv);
711 tcp_info_append_uint(pinfo, "TSER", tser);
715 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
716 int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
720 cc = tvb_get_ntohl(tvb, offset + 2);
721 proto_tree_add_text(opt_tree, tvb, offset, optlen,
722 "%s: %u", optp->name, cc);
723 tcp_info_append_uint(pinfo, "CC", cc);
726 static const ip_tcp_opt tcpopts[] = {
745 "Maximum segment size",
749 dissect_tcpopt_maxseg
757 dissect_tcpopt_wscale
770 &ett_tcp_option_sack,
797 dissect_tcpopt_timestamp
833 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
836 static const true_false_string flags_set_truth = {
842 /* Determine if there is a sub-dissector and call it. This has been */
843 /* separated into a stand alone routine to other protocol dissectors */
844 /* can call to it, ie. socks */
847 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
848 proto_tree *tree, int src_port, int dst_port)
852 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
854 /* determine if this packet is part of a conversation and call dissector */
855 /* for the conversation if available */
857 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
858 src_port, dst_port, next_tvb, pinfo, tree))
861 /* do lookup with the subdissector table */
862 if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
863 dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
866 /* do lookup with the heuristic subdissector table */
867 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
870 /* Oh, well, we don't know this; dissect it as data. */
871 call_dissector(data_handle,next_tvb, pinfo, tree);
876 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
882 guint8 th_off_x2; /* combines th_off and th_x2 */
887 proto_tree *tcp_tree = NULL, *field_tree = NULL;
888 proto_item *ti = NULL, *tf;
890 gchar flags[64] = "<None>";
891 gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
902 guint16 computed_cksum;
903 guint length_remaining;
904 gboolean desegment_ok;
905 struct tcpinfo tcpinfo;
906 gboolean save_fragmented;
908 if (check_col(pinfo->cinfo, COL_PROTOCOL))
909 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
911 /* Clear out the Info column. */
912 if (check_col(pinfo->cinfo, COL_INFO))
913 col_clear(pinfo->cinfo, COL_INFO);
915 th_sport = tvb_get_ntohs(tvb, offset);
916 th_dport = tvb_get_ntohs(tvb, offset + 2);
917 if (check_col(pinfo->cinfo, COL_INFO)) {
918 col_append_fstr(pinfo->cinfo, COL_INFO, "%s > %s",
919 get_tcp_port(th_sport), get_tcp_port(th_dport));
923 if (tcp_summary_in_tree) {
924 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
925 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
926 get_tcp_port(th_sport), th_sport,
927 get_tcp_port(th_dport), th_dport);
930 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, FALSE);
932 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
933 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th_sport,
934 "Source port: %s (%u)", get_tcp_port(th_sport), th_sport);
935 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th_dport,
936 "Destination port: %s (%u)", get_tcp_port(th_dport), th_dport);
937 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th_sport);
938 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th_dport);
941 th_seq = tvb_get_ntohl(tvb, offset + 4);
942 th_ack = tvb_get_ntohl(tvb, offset + 8);
943 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
944 th_flags = tvb_get_guint8(tvb, offset + 13);
945 th_win = tvb_get_ntohs(tvb, offset + 14);
947 if (check_col(pinfo->cinfo, COL_INFO) || tree) {
948 for (i = 0; i < 8; i++) {
950 if (th_flags & bpos) {
952 strcpy(&flags[fpos], ", ");
955 strcpy(&flags[fpos], fstr[i]);
962 if (check_col(pinfo->cinfo, COL_INFO)) {
963 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
964 flags, th_seq, th_ack, th_win);
968 if (tcp_summary_in_tree)
969 proto_item_append_text(ti, ", Seq: %u", th_seq);
970 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th_seq);
973 hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
975 if (hlen < TCPH_MIN_LEN) {
976 /* Give up at this point; we put the source and destination port in
977 the tree, before fetching the header length, so that they'll
978 show up if this is in the failing packet in an ICMP error packet,
979 but it's now time to give up if the header length is bogus. */
980 if (check_col(pinfo->cinfo, COL_INFO))
981 col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
984 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
985 "Header length: %u bytes (bogus, must be at least %u)", hlen,
991 reported_len = tvb_reported_length(tvb);
992 len = tvb_length(tvb);
994 /* Compute the length of data in this segment. */
995 seglen = reported_len - hlen;
997 /* Compute the sequence number of next octet after this segment. */
998 nxtseq = th_seq + seglen;
1001 if (tcp_summary_in_tree)
1002 proto_item_append_text(ti, ", Ack: %u", th_ack);
1003 proto_item_set_len(ti, hlen);
1004 if (nxtseq != th_seq)
1005 proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
1006 if (th_flags & TH_ACK)
1007 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th_ack);
1008 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
1009 "Header length: %u bytes", hlen);
1010 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
1011 th_flags, "Flags: 0x%04x (%s)", th_flags, flags);
1012 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
1013 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th_flags);
1014 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th_flags);
1015 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th_flags);
1016 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th_flags);
1017 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th_flags);
1018 proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th_flags);
1019 proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th_flags);
1020 proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th_flags);
1021 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th_win);
1024 /* Assume we'll pass un-reassembled data to subdissectors. */
1025 tcpinfo.is_reassembled = FALSE;
1027 pinfo->private_data = &tcpinfo;
1030 * Assume, initially, that we can't desegment.
1032 pinfo->can_desegment = 0;
1034 th_sum = tvb_get_ntohs(tvb, offset + 16);
1035 if (!pinfo->fragmented && len >= reported_len) {
1036 /* The packet isn't part of an un-reassembled fragmented datagram
1037 and isn't truncated. This means we have all the data, and thus
1038 can checksum it and, unless it's being returned in an error
1039 packet, are willing to allow subdissectors to request reassembly
1042 if (tcp_check_checksum) {
1043 /* We haven't turned checksum checking off; checksum it. */
1045 /* Set up the fields of the pseudo-header. */
1046 cksum_vec[0].ptr = pinfo->src.data;
1047 cksum_vec[0].len = pinfo->src.len;
1048 cksum_vec[1].ptr = pinfo->dst.data;
1049 cksum_vec[1].len = pinfo->dst.len;
1050 cksum_vec[2].ptr = (const guint8 *)&phdr;
1051 switch (pinfo->src.type) {
1054 phdr[0] = htonl((IP_PROTO_TCP<<16) + reported_len);
1055 cksum_vec[2].len = 4;
1059 phdr[0] = htonl(reported_len);
1060 phdr[1] = htonl(IP_PROTO_TCP);
1061 cksum_vec[2].len = 8;
1065 /* TCP runs only atop IPv4 and IPv6.... */
1066 g_assert_not_reached();
1069 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
1070 cksum_vec[3].len = reported_len;
1071 computed_cksum = in_cksum(&cksum_vec[0], 4);
1072 if (computed_cksum == 0) {
1073 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1074 offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
1076 /* Checksum is valid, so we're willing to desegment it. */
1077 desegment_ok = TRUE;
1079 proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
1080 offset + 16, 2, TRUE);
1081 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1082 offset + 16, 2, th_sum,
1083 "Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
1084 in_cksum_shouldbe(th_sum, computed_cksum));
1086 /* Checksum is invalid, so we're not willing to desegment it. */
1087 desegment_ok = FALSE;
1090 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1091 offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1093 /* We didn't check the checksum, and don't care if it's valid,
1094 so we're willing to desegment it. */
1095 desegment_ok = TRUE;
1098 /* We don't have all the packet data, so we can't checksum it... */
1099 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1100 offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1102 /* ...and aren't willing to desegment it. */
1103 desegment_ok = FALSE;
1107 /* We're willing to desegment this. Is desegmentation enabled? */
1108 if (tcp_desegment) {
1109 /* Yes - is this segment being returned in an error packet? */
1110 if (!pinfo->in_error_pkt) {
1111 /* No - indicate that we will desegment.
1112 We do NOT want to desegment segments returned in error
1113 packets, as they're not part of a TCP connection. */
1114 pinfo->can_desegment = 2;
1119 if (th_flags & TH_URG) {
1120 th_urp = tvb_get_ntohs(tvb, offset + 18);
1121 /* Export the urgent pointer, for the benefit of protocols such as
1123 tcpinfo.urgent = TRUE;
1124 tcpinfo.urgent_pointer = th_urp;
1125 if (check_col(pinfo->cinfo, COL_INFO))
1126 col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
1127 if (tcp_tree != NULL)
1128 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
1130 tcpinfo.urgent = FALSE;
1132 if (check_col(pinfo->cinfo, COL_INFO))
1133 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", seglen);
1135 /* Decode TCP options, if any. */
1136 if (tree && hlen > TCPH_MIN_LEN) {
1137 /* There's more than just the fixed-length header. Decode the
1139 optlen = hlen - TCPH_MIN_LEN; /* length of options, in bytes */
1140 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
1141 "Options: (%u bytes)", optlen);
1142 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
1143 dissect_ip_tcp_options(tvb, offset + 20, optlen,
1144 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree);
1147 /* Skip over header + options */
1150 pinfo->ptype = PT_TCP;
1151 pinfo->srcport = th_sport;
1152 pinfo->destport = th_dport;
1154 /* Check the packet length to see if there's more data
1155 (it could be an ACK-only packet) */
1156 length_remaining = tvb_length_remaining(tvb, offset);
1157 if (length_remaining != 0) {
1158 if (th_flags & TH_RST) {
1162 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
1164 * A TCP SHOULD allow a received RST segment to include data.
1167 * It has been suggested that a RST segment could contain
1168 * ASCII text that encoded and explained the cause of the
1169 * RST. No standard has yet been established for such
1172 * so for segments with RST we just display the data as text.
1174 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
1176 tvb_format_text(tvb, offset, length_remaining));
1178 /* Can we desegment this segment? */
1179 if (pinfo->can_desegment) {
1181 desegment_tcp(tvb, pinfo, offset, th_seq, nxtseq, th_sport, th_dport, tree, tcp_tree);
1183 /* No - just call the subdissector.
1184 Mark this as fragmented, so if somebody throws an exception,
1185 we don't report it as a malformed frame. */
1186 save_fragmented = pinfo->fragmented;
1187 pinfo->fragmented = TRUE;
1188 decode_tcp_ports(tvb, offset, pinfo, tree, th_sport, th_dport);
1189 pinfo->fragmented = save_fragmented;
1194 if( data_out_file ) {
1195 reassemble_tcp( th_seq, /* sequence number */
1196 seglen, /* data length */
1197 tvb_get_ptr(tvb, offset, length_remaining), /* data */
1198 length_remaining, /* captured data length */
1199 ( th_flags & TH_SYN ), /* is syn set? */
1208 proto_register_tcp(void)
1210 static hf_register_info hf[] = {
1213 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
1217 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
1221 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
1225 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
1229 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
1233 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
1237 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1241 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1244 { &hf_tcp_flags_cwr,
1245 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
1248 { &hf_tcp_flags_ecn,
1249 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
1252 { &hf_tcp_flags_urg,
1253 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
1256 { &hf_tcp_flags_ack,
1257 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
1260 { &hf_tcp_flags_push,
1261 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
1264 { &hf_tcp_flags_reset,
1265 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
1268 { &hf_tcp_flags_syn,
1269 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
1272 { &hf_tcp_flags_fin,
1273 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
1276 { &hf_tcp_window_size,
1277 { "Window size", "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1281 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1284 { &hf_tcp_checksum_bad,
1285 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1288 { &hf_tcp_urgent_pointer,
1289 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
1292 static gint *ett[] = {
1296 &ett_tcp_option_sack,
1299 module_t *tcp_module;
1301 proto_tcp = proto_register_protocol("Transmission Control Protocol",
1303 proto_register_field_array(proto_tcp, hf, array_length(hf));
1304 proto_register_subtree_array(ett, array_length(ett));
1306 /* subdissector code */
1307 subdissector_table = register_dissector_table("tcp.port",
1308 "TCP port", FT_UINT16, BASE_DEC);
1309 register_heur_dissector_list("tcp", &heur_subdissector_list);
1311 /* Register configuration preferences */
1312 tcp_module = prefs_register_protocol(proto_tcp, NULL);
1313 prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
1314 "Show TCP summary in protocol tree",
1315 "Whether the TCP summary line should be shown in the protocol tree",
1316 &tcp_summary_in_tree);
1317 prefs_register_bool_preference(tcp_module, "check_checksum",
1318 "Check the validity of the TCP checksum when possible",
1319 "Whether to check the validity of the TCP checksum",
1320 &tcp_check_checksum);
1321 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
1322 "Allow subdissector to desegment TCP streams",
1323 "Whether subdissector can request TCP streams to be desegmented",
1326 register_init_routine(tcp_desegment_init);
1327 register_init_routine(tcp_fragment_init);
1331 proto_reg_handoff_tcp(void)
1333 dissector_handle_t tcp_handle;
1335 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
1336 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
1337 data_handle = find_dissector("data");