2 * Routines for TCP packet disassembly
4 * $Id: packet-tcp.c,v 1.119 2001/12/03 03:59:40 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"
50 #include "packet-tcp.h"
51 #include "packet-ip.h"
52 #include "conversation.h"
54 #include "reassemble.h"
56 /* Place TCP summary in proto tree */
57 static gboolean tcp_summary_in_tree = TRUE;
59 extern FILE* data_out_file;
61 static int proto_tcp = -1;
62 static int hf_tcp_srcport = -1;
63 static int hf_tcp_dstport = -1;
64 static int hf_tcp_port = -1;
65 static int hf_tcp_seq = -1;
66 static int hf_tcp_nxtseq = -1;
67 static int hf_tcp_ack = -1;
68 static int hf_tcp_hdr_len = -1;
69 static int hf_tcp_flags = -1;
70 static int hf_tcp_flags_cwr = -1;
71 static int hf_tcp_flags_ecn = -1;
72 static int hf_tcp_flags_urg = -1;
73 static int hf_tcp_flags_ack = -1;
74 static int hf_tcp_flags_push = -1;
75 static int hf_tcp_flags_reset = -1;
76 static int hf_tcp_flags_syn = -1;
77 static int hf_tcp_flags_fin = -1;
78 static int hf_tcp_window_size = -1;
79 static int hf_tcp_checksum = -1;
80 static int hf_tcp_checksum_bad = -1;
81 static int hf_tcp_urgent_pointer = -1;
83 static gint ett_tcp = -1;
84 static gint ett_tcp_flags = -1;
85 static gint ett_tcp_options = -1;
86 static gint ett_tcp_option_sack = -1;
87 static gint ett_tcp_segments = -1;
89 static dissector_table_t subdissector_table;
90 static heur_dissector_list_t heur_subdissector_list;
91 static conv_dissector_list_t conv_subdissector_list;
92 static dissector_handle_t data_handle;
94 /* TCP structs and definitions */
105 /* Minimum TCP header length. */
106 #define TCPH_MIN_LEN 20
112 #define TCPOPT_NOP 1 /* Padding */
113 #define TCPOPT_EOL 0 /* End of options */
114 #define TCPOPT_MSS 2 /* Segment size negotiating */
115 #define TCPOPT_WINDOW 3 /* Window scaling */
116 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
117 #define TCPOPT_SACK 5 /* SACK Block */
118 #define TCPOPT_ECHO 6
119 #define TCPOPT_ECHOREPLY 7
120 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
122 #define TCPOPT_CCNEW 12
123 #define TCPOPT_CCECHO 13
124 #define TCPOPT_MD5 19 /* RFC2385 */
130 #define TCPOLEN_MSS 4
131 #define TCPOLEN_WINDOW 3
132 #define TCPOLEN_SACK_PERM 2
133 #define TCPOLEN_SACK_MIN 2
134 #define TCPOLEN_ECHO 6
135 #define TCPOLEN_ECHOREPLY 6
136 #define TCPOLEN_TIMESTAMP 10
138 #define TCPOLEN_CCNEW 6
139 #define TCPOLEN_CCECHO 6
140 #define TCPOLEN_MD5 18
144 /* Desegmentation of TCP streams */
145 /* table to hold defragmented TCP streams */
146 static GHashTable *tcp_fragment_table = NULL;
148 tcp_fragment_init(void)
150 fragment_table_init(&tcp_fragment_table);
153 /* functions to trace tcp segments */
154 /* Enable desegmenting of TCP streams */
155 static gboolean tcp_desegment = FALSE;
157 static GHashTable *tcp_segment_table = NULL;
158 static GMemChunk *tcp_segment_key_chunk = NULL;
159 static int tcp_segment_init_count = 200;
160 static GMemChunk *tcp_segment_address_chunk = NULL;
161 static int tcp_segment_address_init_count = 500;
163 typedef struct _tcp_segment_key {
164 /* for ouwn bookkeeping inside packet-tcp.c */
175 free_all_segments(gpointer key_arg, gpointer value, gpointer user_data)
177 tcp_segment_key *key = key_arg;
179 if((key->src)&&(key->src->data)){
180 g_free((gpointer)key->src->data);
184 if((key->dst)&&(key->dst->data)){
185 g_free((gpointer)key->dst->data);
193 tcp_segment_hash(gconstpointer k)
195 tcp_segment_key *key = (tcp_segment_key *)k;
201 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
203 tcp_segment_key *key1 = (tcp_segment_key *)k1;
204 tcp_segment_key *key2 = (tcp_segment_key *)k2;
206 return ( ( (key1->seq==key2->seq)
207 &&(ADDRESSES_EQUAL(key1->src, key2->src))
208 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
213 tcp_desegment_init(void)
216 /* dont allocate any memory chunks unless the user really
223 if(tcp_segment_table){
224 g_hash_table_foreach_remove(tcp_segment_table,
225 free_all_segments, NULL);
227 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
231 if(tcp_segment_key_chunk){
232 g_mem_chunk_destroy(tcp_segment_key_chunk);
234 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
235 sizeof(tcp_segment_key),
236 tcp_segment_init_count*sizeof(tcp_segment_key),
239 if(tcp_segment_address_chunk){
240 g_mem_chunk_destroy(tcp_segment_address_chunk);
242 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
244 tcp_segment_address_init_count*sizeof(address),
249 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
250 guint32 seq, guint32 nxtseq,
251 guint32 sport, guint32 dport,
252 proto_tree *tree, proto_tree *tcp_tree)
254 struct tcpinfo *tcpinfo = pinfo->private_data;
255 fragment_data *ipfd_head;
256 tcp_segment_key old_tsk, *tsk;
257 gboolean must_desegment = FALSE;
258 gboolean called_dissector = FALSE;
263 * Initialize these to assume no desegmentation.
264 * If that's not the case, these will be set appropriately
265 * by the subdissector.
267 pinfo->desegment_offset = 0;
268 pinfo->desegment_len = 0;
271 * Initialize this to assume that this segment will just be
272 * added to the middle of a desegmented chunk of data, so
273 * that we should show it all as data.
274 * If that's not the case, it will be set appropriately.
276 deseg_offset = offset;
278 /* First we must check if this TCP segment should be desegmented.
279 This is only to check if we should desegment this packet,
280 so we dont spend time doing COPY_ADDRESS/g_free.
281 We just "borrow" some address structures from pinfo instead. Cheaper.
283 old_tsk.src = &pinfo->src;
284 old_tsk.dst = &pinfo->dst;
286 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
289 /* OK, this segment was found, which means it continues
290 a higher-level PDU. This means we must desegment it.
291 Add it to the defragmentation lists.
293 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->start_seq,
295 seq - tsk->start_seq,
297 (nxtseq < (tsk->start_seq + tsk->tot_len)) );
300 /* fragment_add() returned NULL, This means that
301 desegmentation is not completed yet.
302 (its like defragmentation but we know we will
303 always add the segments in order).
304 XXX - no, we don't; there is no guarantee that
305 TCP segments are in order on the wire.
307 we must add next segment to our table so we will
310 tcp_segment_key *new_tsk;
312 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
313 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
315 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
318 /* This segment was not found in our table, so it doesn't
319 contain a continuation of a higher-level PDU.
320 Call the normal subdissector.
322 decode_tcp_ports(tvb, offset, pinfo, tree,
324 called_dissector = TRUE;
326 /* Did the subdissector ask us to desegment some more data
327 before it could handle the packet?
328 If so we have to create some structures in our table but
329 this is something we only do the first time we see this
332 if(pinfo->desegment_len) {
333 if (!pinfo->fd->flags.visited)
334 must_desegment = TRUE;
337 * Set "deseg_offset" to the offset in "tvb"
338 * of the first byte of data that the
339 * subdissector didn't process.
341 deseg_offset = offset + pinfo->desegment_offset;
344 /* Either no desegmentation is necessary, or this is
345 segment contains the beginning but not the end of
346 a higher-level PDU and thus isn't completely
352 /* is it completely desegmented? */
355 proto_tree *st = NULL;
356 proto_item *si = NULL;
358 /* first we show a tree with all segments */
359 si = proto_tree_add_text(tcp_tree, tvb, 0, 0,
361 st = proto_item_add_subtree(si, ett_tcp_segments);
362 for(ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
363 proto_tree_add_text(st, tvb, 0, 0,
364 "Frame:%d seq#:%d-%d [%d-%d]",
366 tsk->start_seq + ipfd->offset,
367 tsk->start_seq + ipfd->offset + ipfd->len - 1,
369 ipfd->offset + ipfd->len - 1);
373 * We only call subdissector for the last segment.
374 * Note that the last segment may include more than what
377 if(nxtseq >= (tsk->start_seq + tsk->tot_len)){
378 /* ok, lest call subdissector with desegmented data */
381 /* create a new TVB structure for desegmented data */
382 next_tvb = tvb_new_real_data(ipfd_head->data,
383 ipfd_head->datalen, ipfd_head->datalen,
386 /* add this tvb as a child to the original one */
387 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
389 /* add desegmented data to the data source list */
390 pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
392 /* indicate that this is reassembled data */
393 tcpinfo->is_reassembled = TRUE;
395 /* call subdissector */
396 decode_tcp_ports(next_tvb, 0, pinfo, tree,
398 called_dissector = TRUE;
400 /* Did the subdissector ask us to desegment some more
401 data? This means that the data at the beginning
402 of this segment completed a higher-level PDU,
403 but the data at the end of this segment started
404 a higher-level PDU but didn't complete it.
406 If so we have to create some structures in our
407 table but this is something we only do the first
408 time we see this packet.
410 if(pinfo->desegment_len) {
411 if (!pinfo->fd->flags.visited)
412 must_desegment = TRUE;
415 * The stuff we couldn't dissect must have
416 * come from this segment, so it's all in
419 * "pinfo->desegment_offset" is relative
420 * to the beginning of "next_tvb";
421 * we want an offset relative to the
422 * beginning of "tvb".
424 * First, compute the offset relative to
425 * the *end* of "next_tvb" - i.e., the number
426 * of bytes before the end of "next_tvb"
427 * at which the subdissector stopped.
428 * That's the length of "next_tvb" minus
429 * the offset, relative to the beginning
430 * of "next_tvb, at which the subdissector
434 ipfd_head->datalen - pinfo->desegment_offset;
437 * "tvb" and "next_tvb" end at the same byte
438 * of data, so the offset relative to the
439 * end of "next_tvb" of the byte at which
440 * we stopped is also the offset relative
441 * to the end of "tvb" of the byte at which
444 * Convert that back into an offset relative
445 * to the beginninng of "tvb", by taking
446 * the length of "tvb" and subtracting the
447 * offset relative to the end.
449 deseg_offset = tvb_length(tvb) - deseg_offset;
454 if (must_desegment) {
455 tcp_segment_key *tsk, *new_tsk;
458 * The sequence number at which the stuff to be desegmented
459 * starts is the sequence number of the byte at an offset
460 * of "deseg_offset" into "tvb".
462 * The sequence number of the byte at an offset of "offset"
463 * is "seq", i.e. the starting sequence number of this
464 * segment, so the sequence number of the byte at
465 * "deseg_offset" is "seq + (deseg_offset - offset)".
467 deseg_seq = seq + (deseg_offset - offset);
470 * XXX - how do we detect out-of-order transmissions?
471 * We can't just check for "nxtseq" being greater than
472 * "tsk->start_seq"; for now, we check for the difference
473 * being less than a megabyte, but this is a really
474 * gross hack - we really need to handle out-of-order
475 * transmissions correctly.
477 if ((nxtseq - deseg_seq) <= 1024*1024) {
478 /* OK, subdissector wants us to desegment
479 some data before it can process it. Add
480 what remains of this packet and set
481 up next packet/sequence number as well.
483 We must remember this segment
485 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
486 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
487 COPY_ADDRESS(tsk->src, &pinfo->src);
488 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
489 COPY_ADDRESS(tsk->dst, &pinfo->dst);
490 tsk->seq = deseg_seq;
491 tsk->start_seq = tsk->seq;
492 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
493 tsk->first_frame = pinfo->fd->num;
494 g_hash_table_insert(tcp_segment_table, tsk, tsk);
496 /* Add portion of segment unprocessed by the subdissector
497 to defragmentation lists */
498 fragment_add(tvb, deseg_offset, pinfo, tsk->start_seq,
500 tsk->seq - tsk->start_seq,
501 nxtseq - tsk->start_seq,
502 (nxtseq < tsk->start_seq + tsk->tot_len));
504 /* this is the next segment in the sequence we want */
505 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
506 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
507 new_tsk->seq = nxtseq;
508 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
512 if (!called_dissector || pinfo->desegment_len != 0) {
514 * Either we didn't call the subdissector at all (i.e.,
515 * this is a segment that contains the middle of a
516 * higher-level PDU, but contains neither the beginning
517 * nor the end), or the subdissector couldn't dissect it
518 * all, as some data was missing (i.e., it set
519 * "pinfo->desegment_len" to the amount of additional
522 if (pinfo->desegment_offset == 0) {
524 * It couldn't, in fact, dissect any of it (the
525 * first byte it couldn't dissect is at an offset
526 * of "pinfo->desegment_offset" from the beginning
527 * of the payload, and that's 0).
528 * Just mark this as TCP.
530 if (check_col(pinfo->fd, COL_PROTOCOL)){
531 col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
533 if (check_col(pinfo->fd, COL_INFO)){
534 col_set_str(pinfo->fd, COL_INFO, "[Desegmented TCP]");
539 * Show what's left in the packet as data.
541 call_dissector(data_handle,tvb_new_subset(tvb, deseg_offset,-1,tvb_reported_length_remaining(tvb,deseg_offset)), pinfo, tree);
549 tcp_info_append_uint(frame_data *fd, const char *abbrev, guint32 val)
551 if (check_col(fd, COL_INFO))
552 col_append_fstr(fd, COL_INFO, " %s=%u", abbrev, val);
556 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
557 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
561 mss = tvb_get_ntohs(tvb, offset + 2);
562 proto_tree_add_text(opt_tree, tvb, offset, optlen,
563 "%s: %u bytes", optp->name, mss);
564 tcp_info_append_uint(fd, "MSS", mss);
568 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
569 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
573 ws = tvb_get_guint8(tvb, offset + 2);
574 proto_tree_add_text(opt_tree, tvb, offset, optlen,
575 "%s: %u bytes", optp->name, ws);
576 tcp_info_append_uint(fd, "WS", ws);
580 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
581 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
583 proto_tree *field_tree = NULL;
585 guint leftedge, rightedge;
587 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
588 offset += 2; /* skip past type and length */
589 optlen -= 2; /* subtract size of type and length */
591 if (field_tree == NULL) {
592 /* Haven't yet made a subtree out of this option. Do so. */
593 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
596 proto_tree_add_text(field_tree, tvb, offset, optlen,
597 "(suboption would go past end of option)");
600 leftedge = tvb_get_ntohl(tvb, offset);
603 proto_tree_add_text(field_tree, tvb, offset, optlen,
604 "(suboption would go past end of option)");
607 /* XXX - check whether it goes past end of packet */
608 rightedge = tvb_get_ntohl(tvb, offset + 4);
610 proto_tree_add_text(field_tree, tvb, offset, 8,
611 "left edge = %u, right edge = %u", leftedge, rightedge);
612 tcp_info_append_uint(fd, "SLE", leftedge);
613 tcp_info_append_uint(fd, "SRE", rightedge);
619 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
620 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
624 echo = tvb_get_ntohl(tvb, offset + 2);
625 proto_tree_add_text(opt_tree, tvb, offset, optlen,
626 "%s: %u", optp->name, echo);
627 tcp_info_append_uint(fd, "ECHO", echo);
631 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
632 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
636 tsv = tvb_get_ntohl(tvb, offset + 2);
637 tser = tvb_get_ntohl(tvb, offset + 6);
638 proto_tree_add_text(opt_tree, tvb, offset, optlen,
639 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
640 tcp_info_append_uint(fd, "TSV", tsv);
641 tcp_info_append_uint(fd, "TSER", tser);
645 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
646 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
650 cc = tvb_get_ntohl(tvb, offset + 2);
651 proto_tree_add_text(opt_tree, tvb, offset, optlen,
652 "%s: %u", optp->name, cc);
653 tcp_info_append_uint(fd, "CC", cc);
656 static const ip_tcp_opt tcpopts[] = {
675 "Maximum segment size",
679 dissect_tcpopt_maxseg
687 dissect_tcpopt_wscale
700 &ett_tcp_option_sack,
727 dissect_tcpopt_timestamp
763 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
766 static const true_false_string flags_set_truth = {
772 /* Determine if there is a sub-dissector and call it. This has been */
773 /* separated into a stand alone routine to other protocol dissectors */
774 /* can call to it, ie. socks */
777 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
778 proto_tree *tree, int src_port, int dst_port)
782 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
784 /* determine if this packet is part of a conversation and call dissector */
785 /* for the conversation if available */
787 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
788 src_port, dst_port, next_tvb, pinfo, tree))
791 /* do lookup with the subdissector table */
792 if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
793 dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
796 /* do lookup with the heuristic subdissector table */
797 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
800 /* Oh, well, we don't know this; dissect it as data. */
801 call_dissector(data_handle,next_tvb, pinfo, tree);
806 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
812 guint8 th_off_x2; /* combines th_off and th_x2 */
817 proto_tree *tcp_tree = NULL, *field_tree = NULL;
818 proto_item *ti = NULL, *tf;
820 gchar flags[64] = "<None>";
821 gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
832 guint16 computed_cksum;
833 guint length_remaining;
834 struct tcpinfo tcpinfo;
836 if (check_col(pinfo->fd, COL_PROTOCOL))
837 col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
839 /* Clear out the Info column. */
840 if (check_col(pinfo->fd, COL_INFO))
841 col_clear(pinfo->fd, COL_INFO);
843 th_sport = tvb_get_ntohs(tvb, offset);
844 th_dport = tvb_get_ntohs(tvb, offset + 2);
845 if (check_col(pinfo->fd, COL_INFO)) {
846 col_append_fstr(pinfo->fd, COL_INFO, "%s > %s",
847 get_tcp_port(th_sport), get_tcp_port(th_dport));
851 if (tcp_summary_in_tree) {
852 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0,
854 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
855 get_tcp_port(th_sport), th_sport,
856 get_tcp_port(th_dport), th_dport);
859 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0,
860 tvb_length(tvb), FALSE);
862 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
863 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th_sport,
864 "Source port: %s (%u)", get_tcp_port(th_sport), th_sport);
865 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th_dport,
866 "Destination port: %s (%u)", get_tcp_port(th_dport), th_dport);
867 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th_sport);
868 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th_dport);
871 th_seq = tvb_get_ntohl(tvb, offset + 4);
872 th_ack = tvb_get_ntohl(tvb, offset + 8);
873 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
874 th_flags = tvb_get_guint8(tvb, offset + 13);
875 th_win = tvb_get_ntohs(tvb, offset + 14);
877 if (check_col(pinfo->fd, COL_INFO) || tree) {
878 for (i = 0; i < 8; i++) {
880 if (th_flags & bpos) {
882 strcpy(&flags[fpos], ", ");
885 strcpy(&flags[fpos], fstr[i]);
892 if (check_col(pinfo->fd, COL_INFO)) {
893 col_append_fstr(pinfo->fd, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
894 flags, th_seq, th_ack, th_win);
898 if (tcp_summary_in_tree)
899 proto_item_append_text(ti, ", Seq: %u", th_seq);
900 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th_seq);
903 hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
905 if (hlen < TCPH_MIN_LEN) {
906 /* Give up at this point; we put the source and destination port in
907 the tree, before fetching the header length, so that they'll
908 show up if this is in the failing packet in an ICMP error packet,
909 but it's now time to give up if the header length is bogus. */
910 if (check_col(pinfo->fd, COL_INFO))
911 col_append_fstr(pinfo->fd, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
914 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
915 "Header length: %u bytes (bogus, must be at least %u)", hlen,
921 reported_len = tvb_reported_length(tvb);
922 len = tvb_length(tvb);
924 /* Compute the length of data in this segment. */
925 seglen = reported_len - hlen;
927 /* Compute the sequence number of next octet after this segment. */
928 nxtseq = th_seq + seglen;
931 if (tcp_summary_in_tree)
932 proto_item_append_text(ti, ", Ack: %u", th_ack);
933 proto_item_set_len(ti, hlen);
934 if (nxtseq != th_seq)
935 proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
936 if (th_flags & TH_ACK)
937 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th_ack);
938 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
939 "Header length: %u bytes", hlen);
940 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
941 th_flags, "Flags: 0x%04x (%s)", th_flags, flags);
942 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
943 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th_flags);
944 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th_flags);
945 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th_flags);
946 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th_flags);
947 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th_flags);
948 proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th_flags);
949 proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th_flags);
950 proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th_flags);
951 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th_win);
954 /* Assume we'll pass un-reassembled data to subdissectors. */
955 tcpinfo.is_reassembled = FALSE;
957 pinfo->private_data = &tcpinfo;
960 * Assume, initially, that we can't desegment.
962 pinfo->can_desegment = 0;
964 th_sum = tvb_get_ntohs(tvb, offset + 16);
965 if (!pinfo->fragmented && len >= reported_len) {
966 /* The packet isn't part of a fragmented datagram, isn't being
967 returned inside an ICMP error packet, and isn't truncated, so we
969 XXX - make a bigger scatter-gather list once we do fragment
972 /* Set up the fields of the pseudo-header. */
973 cksum_vec[0].ptr = pinfo->src.data;
974 cksum_vec[0].len = pinfo->src.len;
975 cksum_vec[1].ptr = pinfo->dst.data;
976 cksum_vec[1].len = pinfo->dst.len;
977 cksum_vec[2].ptr = (const guint8 *)&phdr;
978 switch (pinfo->src.type) {
981 phdr[0] = htonl((IP_PROTO_TCP<<16) + reported_len);
982 cksum_vec[2].len = 4;
986 phdr[0] = htonl(reported_len);
987 phdr[1] = htonl(IP_PROTO_TCP);
988 cksum_vec[2].len = 8;
992 /* TCP runs only atop IPv4 and IPv6.... */
993 g_assert_not_reached();
996 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
997 cksum_vec[3].len = reported_len;
998 computed_cksum = in_cksum(&cksum_vec[0], 4);
999 if (computed_cksum == 0) {
1001 * We have all the data for this TCP segment, and the checksum of
1002 * the header and the data is good, so we can desegment it.
1003 * Is desegmentation enabled?
1005 if (tcp_desegment) {
1006 /* Yes - is this segment being returned in an error packet? */
1007 if (!pinfo->in_error_pkt) {
1008 /* No - indicate that we will desegment.
1009 We do NOT want to desegment segments returned in error
1010 packets, as they're not part of a TCP connection. */
1011 pinfo->can_desegment = 2;
1014 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1015 offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
1017 proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
1018 offset + 16, 2, TRUE);
1019 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1020 offset + 16, 2, th_sum,
1021 "Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
1022 in_cksum_shouldbe(th_sum, computed_cksum));
1025 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1026 offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1028 if (th_flags & TH_URG) {
1029 th_urp = tvb_get_ntohs(tvb, offset + 18);
1030 /* Export the urgent pointer, for the benefit of protocols such as
1032 tcpinfo.urgent = TRUE;
1033 tcpinfo.urgent_pointer = th_urp;
1034 if (check_col(pinfo->fd, COL_INFO))
1035 col_append_fstr(pinfo->fd, COL_INFO, " Urg=%u", th_urp);
1036 if (tcp_tree != NULL)
1037 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
1039 tcpinfo.urgent = FALSE;
1041 if (check_col(pinfo->fd, COL_INFO))
1042 col_append_fstr(pinfo->fd, COL_INFO, " Len=%d", seglen);
1044 /* Decode TCP options, if any. */
1045 if (tree && hlen > TCPH_MIN_LEN) {
1046 /* There's more than just the fixed-length header. Decode the
1048 optlen = hlen - TCPH_MIN_LEN; /* length of options, in bytes */
1049 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
1050 "Options: (%d bytes)", optlen);
1051 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
1052 dissect_ip_tcp_options(tvb, offset + 20, optlen,
1053 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo->fd, field_tree);
1056 /* Skip over header + options */
1059 pinfo->ptype = PT_TCP;
1060 pinfo->srcport = th_sport;
1061 pinfo->destport = th_dport;
1063 /* Check the packet length to see if there's more data
1064 (it could be an ACK-only packet) */
1065 length_remaining = tvb_length_remaining(tvb, offset);
1066 if (length_remaining != 0) {
1067 if (th_flags & TH_RST) {
1071 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
1073 * A TCP SHOULD allow a received RST segment to include data.
1076 * It has been suggested that a RST segment could contain
1077 * ASCII text that encoded and explained the cause of the
1078 * RST. No standard has yet been established for such
1081 * so for segments with RST we just display the data as text.
1083 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
1085 tvb_format_text(tvb, offset, length_remaining));
1087 /* Can we desegment this segment? */
1088 if (pinfo->can_desegment) {
1090 desegment_tcp(tvb, pinfo, offset, th_seq, nxtseq, th_sport, th_dport, tree, tcp_tree);
1092 /* No - just call the subdissector. */
1093 decode_tcp_ports(tvb, offset, pinfo, tree, th_sport, th_dport);
1098 if( data_out_file ) {
1099 reassemble_tcp( th_seq, /* sequence number */
1100 seglen, /* data length */
1101 tvb_get_ptr(tvb, offset, length_remaining), /* data */
1102 length_remaining, /* captured data length */
1103 ( th_flags & TH_SYN ), /* is syn set? */
1112 proto_register_tcp(void)
1114 static hf_register_info hf[] = {
1117 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
1121 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
1125 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
1129 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
1133 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
1137 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
1141 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1145 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1148 { &hf_tcp_flags_cwr,
1149 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
1152 { &hf_tcp_flags_ecn,
1153 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
1156 { &hf_tcp_flags_urg,
1157 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
1160 { &hf_tcp_flags_ack,
1161 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
1164 { &hf_tcp_flags_push,
1165 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
1168 { &hf_tcp_flags_reset,
1169 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
1172 { &hf_tcp_flags_syn,
1173 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
1176 { &hf_tcp_flags_fin,
1177 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
1180 { &hf_tcp_window_size,
1181 { "Window size", "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1185 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1188 { &hf_tcp_checksum_bad,
1189 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1192 { &hf_tcp_urgent_pointer,
1193 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
1196 static gint *ett[] = {
1200 &ett_tcp_option_sack,
1203 module_t *tcp_module;
1205 proto_tcp = proto_register_protocol("Transmission Control Protocol",
1207 proto_register_field_array(proto_tcp, hf, array_length(hf));
1208 proto_register_subtree_array(ett, array_length(ett));
1210 /* subdissector code */
1211 subdissector_table = register_dissector_table("tcp.port");
1212 register_heur_dissector_list("tcp", &heur_subdissector_list);
1213 register_conv_dissector_list("tcp", &conv_subdissector_list);
1215 /* Register configuration preferences */
1216 tcp_module = prefs_register_protocol(proto_tcp, NULL);
1217 prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
1218 "Show TCP summary in protocol tree",
1219 "Whether the TCP summary line should be shown in the protocol tree",
1220 &tcp_summary_in_tree);
1221 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
1222 "Allow subdissector to desegment TCP streams",
1223 "Whether subdissector can request TCP streams to be desegmented",
1226 register_init_routine(tcp_desegment_init);
1227 register_init_routine(tcp_fragment_init);
1231 proto_reg_handoff_tcp(void)
1233 dissector_handle_t tcp_handle;
1235 tcp_handle = create_dissector_handle(dissect_tcp, proto_tcp);
1236 dissector_add("ip.proto", IP_PROTO_TCP, tcp_handle);
1237 data_handle = find_dissector("data");