2 * Routines for TCP packet disassembly
4 * $Id: packet-tcp.c,v 1.114 2001/11/15 10:58:48 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;
93 /* TCP structs and definitions */
104 /* Minimum TCP header length. */
105 #define TCPH_MIN_LEN 20
111 #define TCPOPT_NOP 1 /* Padding */
112 #define TCPOPT_EOL 0 /* End of options */
113 #define TCPOPT_MSS 2 /* Segment size negotiating */
114 #define TCPOPT_WINDOW 3 /* Window scaling */
115 #define TCPOPT_SACK_PERM 4 /* SACK Permitted */
116 #define TCPOPT_SACK 5 /* SACK Block */
117 #define TCPOPT_ECHO 6
118 #define TCPOPT_ECHOREPLY 7
119 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
121 #define TCPOPT_CCNEW 12
122 #define TCPOPT_CCECHO 13
123 #define TCPOPT_MD5 19 /* RFC2385 */
129 #define TCPOLEN_MSS 4
130 #define TCPOLEN_WINDOW 3
131 #define TCPOLEN_SACK_PERM 2
132 #define TCPOLEN_SACK_MIN 2
133 #define TCPOLEN_ECHO 6
134 #define TCPOLEN_ECHOREPLY 6
135 #define TCPOLEN_TIMESTAMP 10
137 #define TCPOLEN_CCNEW 6
138 #define TCPOLEN_CCECHO 6
139 #define TCPOLEN_MD5 18
143 /* Desegmentation of TCP streams */
144 /* table to hold defragmented TCP streams */
145 static GHashTable *tcp_fragment_table = NULL;
147 tcp_fragment_init(void)
149 fragment_table_init(&tcp_fragment_table);
152 /* functions to trace tcp segments */
153 /* Enable desegmenting of TCP streams */
154 static gboolean tcp_desegment = FALSE;
156 static GHashTable *tcp_segment_table = NULL;
157 static GMemChunk *tcp_segment_key_chunk = NULL;
158 static int tcp_segment_init_count = 200;
159 static GMemChunk *tcp_segment_address_chunk = NULL;
160 static int tcp_segment_address_init_count = 500;
162 typedef struct _tcp_segment_key {
163 /* for ouwn bookkeeping inside packet-tcp.c */
174 free_all_segments(gpointer key_arg, gpointer value, gpointer user_data)
176 tcp_segment_key *key = key_arg;
178 if((key->src)&&(key->src->data)){
179 g_free((gpointer)key->src->data);
183 if((key->dst)&&(key->dst->data)){
184 g_free((gpointer)key->dst->data);
192 tcp_segment_hash(gconstpointer k)
194 tcp_segment_key *key = (tcp_segment_key *)k;
200 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
202 tcp_segment_key *key1 = (tcp_segment_key *)k1;
203 tcp_segment_key *key2 = (tcp_segment_key *)k2;
205 return ( ( (key1->seq==key2->seq)
206 &&(ADDRESSES_EQUAL(key1->src, key2->src))
207 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
212 tcp_desegment_init(void)
215 /* dont allocate any memory chunks unless the user really
222 if(tcp_segment_table){
223 g_hash_table_foreach_remove(tcp_segment_table,
224 free_all_segments, NULL);
226 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
230 if(tcp_segment_key_chunk){
231 g_mem_chunk_destroy(tcp_segment_key_chunk);
233 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
234 sizeof(tcp_segment_key),
235 tcp_segment_init_count*sizeof(tcp_segment_key),
238 if(tcp_segment_address_chunk){
239 g_mem_chunk_destroy(tcp_segment_address_chunk);
241 tcp_segment_address_chunk = g_mem_chunk_new("tcp_segment_address_chunk",
243 tcp_segment_address_init_count*sizeof(address),
248 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
249 guint32 seq, guint32 nxtseq,
250 guint32 sport, guint32 dport,
251 proto_tree *tree, proto_tree *tcp_tree)
253 struct tcpinfo *tcpinfo = pinfo->private_data;
254 fragment_data *ipfd_head;
255 tcp_segment_key old_tsk, *tsk;
256 gboolean must_desegment = FALSE;
257 gboolean called_dissector = FALSE;
262 * Initialize these to assume no desegmentation.
263 * If that's not the case, these will be set appropriately
264 * by the subdissector.
266 pinfo->desegment_offset = 0;
267 pinfo->desegment_len = 0;
270 * Initialize this to assume that this segment will just be
271 * added to the middle of a desegmented chunk of data, so
272 * that we should show it all as data.
273 * If that's not the case, it will be set appropriately.
275 deseg_offset = offset;
277 /* First we must check if this TCP segment should be desegmented.
278 This is only to check if we should desegment this packet,
279 so we dont spend time doing COPY_ADDRESS/g_free.
280 We just "borrow" some address structures from pinfo instead. Cheaper.
282 old_tsk.src = &pinfo->src;
283 old_tsk.dst = &pinfo->dst;
285 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
288 /* OK, this segment was found, which means it continues
289 a higher-level PDU. This means we must desegment it.
290 Add it to the defragmentation lists.
292 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->start_seq,
294 seq - tsk->start_seq,
296 (nxtseq < (tsk->start_seq + tsk->tot_len)) );
299 /* fragment_add() returned NULL, This means that
300 desegmentation is not completed yet.
301 (its like defragmentation but we know we will
302 always add the segments in order).
303 XXX - no, we don't; there is no guarantee that
304 TCP segments are in order on the wire.
306 we must add next segment to our table so we will
309 tcp_segment_key *new_tsk;
311 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
312 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
314 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
317 /* This segment was not found in our table, so it doesn't
318 contain a continuation of a higher-level PDU.
319 Call the normal subdissector.
321 decode_tcp_ports(tvb, offset, pinfo, tree,
323 called_dissector = TRUE;
325 /* Did the subdissector ask us to desegment some more data
326 before it could handle the packet?
327 If so we have to create some structures in our table but
328 this is something we only do the first time we see this
331 if(pinfo->desegment_len) {
332 if (!pinfo->fd->flags.visited)
333 must_desegment = TRUE;
336 * Set "deseg_offset" to the offset in "tvb"
337 * of the first byte of data that the
338 * subdissector didn't process.
340 deseg_offset = offset + pinfo->desegment_offset;
343 /* Either no desegmentation is necessary, or this is
344 segment contains the beginning but not the end of
345 a higher-level PDU and thus isn't completely
351 /* is it completely desegmented? */
354 proto_tree *st = NULL;
355 proto_item *si = NULL;
357 /* first we show a tree with all segments */
358 si = proto_tree_add_text(tcp_tree, tvb, 0, 0,
360 st = proto_item_add_subtree(si, ett_tcp_segments);
361 for(ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
362 proto_tree_add_text(st, tvb, 0, 0,
363 "Frame:%d seq#:%d-%d [%d-%d]",
365 tsk->start_seq + ipfd->offset,
366 tsk->start_seq + ipfd->offset + ipfd->len - 1,
368 ipfd->offset + ipfd->len - 1);
372 * We only call subdissector for the last segment.
373 * Note that the last segment may include more than what
376 if(nxtseq >= (tsk->start_seq + tsk->tot_len)){
377 /* 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 /* save current value of *pinfo across call to
398 pinfo->len = tvb_reported_length(next_tvb);
399 pinfo->captured_len = tvb_length(next_tvb);
401 /* call subdissector */
402 decode_tcp_ports(next_tvb, 0, pinfo, tree,
404 called_dissector = TRUE;
407 * Don't trash the new values of "desegment_offset"
408 * and "desegment_len".
410 save_pi.desegment_offset = pinfo->desegment_offset;
411 save_pi.desegment_len = pinfo->desegment_len;
414 /* Did the subdissector ask us to desegment some more
415 data? This means that the data at the beginning
416 of this segment completed a higher-level PDU,
417 but the data at the end of this segment started
418 a higher-level PDU but didn't complete it.
420 If so we have to create some structures in our
421 table but this is something we only do the first
422 time we see this packet.
424 if(pinfo->desegment_len) {
425 if (!pinfo->fd->flags.visited)
426 must_desegment = TRUE;
429 * The stuff we couldn't dissect must have
430 * come from this segment, so it's all in
433 * "pinfo->desegment_offset" is relative
434 * to the beginning of "next_tvb";
435 * we want an offset relative to the
436 * beginning of "tvb".
438 * First, compute the offset relative to
439 * the *end* of "next_tvb" - i.e., the number
440 * of bytes before the end of "next_tvb"
441 * at which the subdissector stopped.
442 * That's the length of "next_tvb" minus
443 * the offset, relative to the beginning
444 * of "next_tvb, at which the subdissector
448 ipfd_head->datalen - pinfo->desegment_offset;
451 * "tvb" and "next_tvb" end at the same byte
452 * of data, so the offset relative to the
453 * end of "next_tvb" of the byte at which
454 * we stopped is also the offset relative
455 * to the end of "tvb" of the byte at which
458 * Convert that back into an offset relative
459 * to the beginninng of "tvb", by taking
460 * the length of "tvb" and subtracting the
461 * offset relative to the end.
463 deseg_offset = tvb_length(tvb) - deseg_offset;
468 if (must_desegment) {
469 tcp_segment_key *tsk, *new_tsk;
472 * The sequence number at which the stuff to be desegmented
473 * starts is the sequence number of the byte at an offset
474 * of "deseg_offset" into "tvb".
476 * The sequence number of the byte at an offset of "offset"
477 * is "seq", i.e. the starting sequence number of this
478 * segment, so the sequence number of the byte at
479 * "deseg_offset" is "seq + (deseg_offset - offset)".
481 deseg_seq = seq + (deseg_offset - offset);
484 * XXX - how do we detect out-of-order transmissions?
485 * We can't just check for "nxtseq" being greater than
486 * "tsk->start_seq"; for now, we check for the difference
487 * being less than a megabyte, but this is a really
488 * gross hack - we really need to handle out-of-order
489 * transmissions correctly.
491 if ((nxtseq - deseg_seq) <= 1024*1024) {
492 /* OK, subdissector wants us to desegment
493 some data before it can process it. Add
494 what remains of this packet and set
495 up next packet/sequence number as well.
497 We must remember this segment
499 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
500 tsk->src = g_mem_chunk_alloc(tcp_segment_address_chunk);
501 COPY_ADDRESS(tsk->src, &pinfo->src);
502 tsk->dst = g_mem_chunk_alloc(tcp_segment_address_chunk);
503 COPY_ADDRESS(tsk->dst, &pinfo->dst);
504 tsk->seq = deseg_seq;
505 tsk->start_seq = tsk->seq;
506 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
507 tsk->first_frame = pinfo->fd->num;
508 g_hash_table_insert(tcp_segment_table, tsk, tsk);
510 /* Add portion of segment unprocessed by the subdissector
511 to defragmentation lists */
512 fragment_add(tvb, deseg_offset, pinfo, tsk->start_seq,
514 tsk->seq - tsk->start_seq,
515 nxtseq - tsk->start_seq,
516 (nxtseq < tsk->start_seq + tsk->tot_len));
518 /* this is the next segment in the sequence we want */
519 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
520 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
521 new_tsk->seq = nxtseq;
522 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
526 if (!called_dissector || pinfo->desegment_len != 0) {
528 * Either we didn't call the subdissector at all (i.e.,
529 * this is a segment that contains the middle of a
530 * higher-level PDU, but contains neither the beginning
531 * nor the end), or the subdissector couldn't dissect it
532 * all, as some data was missing (i.e., it set
533 * "pinfo->desegment_len" to the amount of additional
536 if (pinfo->desegment_offset == 0) {
538 * It couldn't, in fact, dissect any of it (the
539 * first byte it couldn't dissect is at an offset
540 * of "pinfo->desegment_offset" from the beginning
541 * of the payload, and that's 0).
542 * Just mark this as TCP.
544 if (check_col(pinfo->fd, COL_PROTOCOL)){
545 col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
547 if (check_col(pinfo->fd, COL_INFO)){
548 col_set_str(pinfo->fd, COL_INFO, "[Desegmented TCP]");
553 * Show what's left in the packet as data.
555 dissect_data(tvb, deseg_offset, pinfo, tree);
563 tcp_info_append_uint(frame_data *fd, const char *abbrev, guint32 val)
565 if (check_col(fd, COL_INFO))
566 col_append_fstr(fd, COL_INFO, " %s=%u", abbrev, val);
570 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
571 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
575 mss = tvb_get_ntohs(tvb, offset + 2);
576 proto_tree_add_text(opt_tree, tvb, offset, optlen,
577 "%s: %u bytes", optp->name, mss);
578 tcp_info_append_uint(fd, "MSS", mss);
582 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
583 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
587 ws = tvb_get_guint8(tvb, offset + 2);
588 proto_tree_add_text(opt_tree, tvb, offset, optlen,
589 "%s: %u bytes", optp->name, ws);
590 tcp_info_append_uint(fd, "WS", ws);
594 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
595 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
597 proto_tree *field_tree = NULL;
599 guint leftedge, rightedge;
601 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
602 offset += 2; /* skip past type and length */
603 optlen -= 2; /* subtract size of type and length */
605 if (field_tree == NULL) {
606 /* Haven't yet made a subtree out of this option. Do so. */
607 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
610 proto_tree_add_text(field_tree, tvb, offset, optlen,
611 "(suboption would go past end of option)");
614 leftedge = tvb_get_ntohl(tvb, offset);
617 proto_tree_add_text(field_tree, tvb, offset, optlen,
618 "(suboption would go past end of option)");
621 /* XXX - check whether it goes past end of packet */
622 rightedge = tvb_get_ntohl(tvb, offset + 4);
624 proto_tree_add_text(field_tree, tvb, offset, 8,
625 "left edge = %u, right edge = %u", leftedge, rightedge);
626 tcp_info_append_uint(fd, "SLE", leftedge);
627 tcp_info_append_uint(fd, "SRE", rightedge);
633 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
634 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
638 echo = tvb_get_ntohl(tvb, offset + 2);
639 proto_tree_add_text(opt_tree, tvb, offset, optlen,
640 "%s: %u", optp->name, echo);
641 tcp_info_append_uint(fd, "ECHO", echo);
645 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
646 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
650 tsv = tvb_get_ntohl(tvb, offset + 2);
651 tser = tvb_get_ntohl(tvb, offset + 6);
652 proto_tree_add_text(opt_tree, tvb, offset, optlen,
653 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
654 tcp_info_append_uint(fd, "TSV", tsv);
655 tcp_info_append_uint(fd, "TSER", tser);
659 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
660 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
664 cc = tvb_get_ntohl(tvb, offset + 2);
665 proto_tree_add_text(opt_tree, tvb, offset, optlen,
666 "%s: %u", optp->name, cc);
667 tcp_info_append_uint(fd, "CC", cc);
670 static const ip_tcp_opt tcpopts[] = {
689 "Maximum segment size",
693 dissect_tcpopt_maxseg
701 dissect_tcpopt_wscale
714 &ett_tcp_option_sack,
741 dissect_tcpopt_timestamp
777 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
780 static const true_false_string flags_set_truth = {
786 /* Determine if there is a sub-dissector and call it. This has been */
787 /* separated into a stand alone routine to other protocol dissectors */
788 /* can call to it, ie. socks */
791 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
792 proto_tree *tree, int src_port, int dst_port)
796 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
798 /* determine if this packet is part of a conversation and call dissector */
799 /* for the conversation if available */
801 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
802 src_port, dst_port, next_tvb, pinfo, tree))
805 /* do lookup with the subdissector table */
806 if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
807 dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
810 /* do lookup with the heuristic subdissector table */
811 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
814 /* Oh, well, we don't know this; dissect it as data. */
815 dissect_data(next_tvb, 0, pinfo, tree);
820 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
826 guint8 th_off_x2; /* combines th_off and th_x2 */
831 proto_tree *tcp_tree = NULL, *field_tree = NULL;
832 proto_item *ti = NULL, *tf;
834 gchar flags[64] = "<None>";
835 gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
846 guint16 computed_cksum;
847 guint length_remaining;
848 struct tcpinfo tcpinfo;
850 if (check_col(pinfo->fd, COL_PROTOCOL))
851 col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
853 /* Clear out the Info column. */
854 if (check_col(pinfo->fd, COL_INFO))
855 col_clear(pinfo->fd, COL_INFO);
857 th_sport = tvb_get_ntohs(tvb, offset);
858 th_dport = tvb_get_ntohs(tvb, offset + 2);
859 if (check_col(pinfo->fd, COL_INFO)) {
860 col_append_fstr(pinfo->fd, COL_INFO, "%s > %s",
861 get_tcp_port(th_sport), get_tcp_port(th_dport));
865 if (tcp_summary_in_tree) {
866 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0,
868 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
869 get_tcp_port(th_sport), th_sport,
870 get_tcp_port(th_dport), th_dport);
873 ti = proto_tree_add_item(tree, proto_tcp, tvb, 0,
874 tvb_length(tvb), FALSE);
876 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
877 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th_sport,
878 "Source port: %s (%u)", get_tcp_port(th_sport), th_sport);
879 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th_dport,
880 "Destination port: %s (%u)", get_tcp_port(th_dport), th_dport);
881 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th_sport);
882 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th_dport);
885 th_seq = tvb_get_ntohl(tvb, offset + 4);
886 th_ack = tvb_get_ntohl(tvb, offset + 8);
887 th_off_x2 = tvb_get_guint8(tvb, offset + 12);
888 th_flags = tvb_get_guint8(tvb, offset + 13);
889 th_win = tvb_get_ntohs(tvb, offset + 14);
891 if (check_col(pinfo->fd, COL_INFO) || tree) {
892 for (i = 0; i < 8; i++) {
894 if (th_flags & bpos) {
896 strcpy(&flags[fpos], ", ");
899 strcpy(&flags[fpos], fstr[i]);
906 if (check_col(pinfo->fd, COL_INFO)) {
907 col_append_fstr(pinfo->fd, COL_INFO, " [%s] Seq=%u Ack=%u Win=%u",
908 flags, th_seq, th_ack, th_win);
912 if (tcp_summary_in_tree)
913 proto_item_append_text(ti, ", Seq: %u", th_seq);
914 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th_seq);
917 hlen = hi_nibble(th_off_x2) * 4; /* TCP header length, in bytes */
919 if (hlen < TCPH_MIN_LEN) {
920 /* Give up at this point; we put the source and destination port in
921 the tree, before fetching the header length, so that they'll
922 show up if this is in the failing packet in an ICMP error packet,
923 but it's now time to give up if the header length is bogus. */
924 if (check_col(pinfo->fd, COL_INFO))
925 col_append_fstr(pinfo->fd, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
928 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
929 "Header length: %u bytes (bogus, must be at least %u)", hlen,
935 reported_len = tvb_reported_length(tvb);
936 len = tvb_length(tvb);
938 /* Compute the length of data in this segment. */
939 seglen = reported_len - hlen;
941 /* Compute the sequence number of next octet after this segment. */
942 nxtseq = th_seq + seglen;
945 if (tcp_summary_in_tree)
946 proto_item_append_text(ti, ", Ack: %u", th_ack);
947 proto_item_set_len(ti, hlen);
948 if (nxtseq != th_seq)
949 proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
950 if (th_flags & TH_ACK)
951 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th_ack);
952 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
953 "Header length: %u bytes", hlen);
954 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
955 th_flags, "Flags: 0x%04x (%s)", th_flags, flags);
956 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
957 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th_flags);
958 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th_flags);
959 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th_flags);
960 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th_flags);
961 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th_flags);
962 proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th_flags);
963 proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th_flags);
964 proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th_flags);
965 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th_win);
968 /* Assume we'll pass un-reassembled data to subdissectors. */
969 tcpinfo.is_reassembled = FALSE;
971 pinfo->private_data = &tcpinfo;
974 * Assume, initially, that we can't desegment.
976 pinfo->can_desegment = FALSE;
978 th_sum = tvb_get_ntohs(tvb, offset + 16);
979 if (!pinfo->fragmented && len >= reported_len) {
980 /* The packet isn't part of a fragmented datagram, isn't being
981 returned inside an ICMP error packet, and isn't truncated, so we
983 XXX - make a bigger scatter-gather list once we do fragment
986 /* Set up the fields of the pseudo-header. */
987 cksum_vec[0].ptr = pinfo->src.data;
988 cksum_vec[0].len = pinfo->src.len;
989 cksum_vec[1].ptr = pinfo->dst.data;
990 cksum_vec[1].len = pinfo->dst.len;
991 cksum_vec[2].ptr = (const guint8 *)&phdr;
992 switch (pinfo->src.type) {
995 phdr[0] = htonl((IP_PROTO_TCP<<16) + reported_len);
996 cksum_vec[2].len = 4;
1000 phdr[0] = htonl(reported_len);
1001 phdr[1] = htonl(IP_PROTO_TCP);
1002 cksum_vec[2].len = 8;
1006 /* TCP runs only atop IPv4 and IPv6.... */
1007 g_assert_not_reached();
1010 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
1011 cksum_vec[3].len = reported_len;
1012 computed_cksum = in_cksum(&cksum_vec[0], 4);
1013 if (computed_cksum == 0) {
1015 * We have all the data for this TCP segment, and the checksum of
1016 * the header and the data is good, so we can desegment it.
1017 * Is desegmentation enabled?
1019 if (tcp_desegment) {
1020 /* Yes - is this segment being returned in an error packet? */
1021 if (!pinfo->in_error_pkt) {
1022 /* No - indicate that we will desegment.
1023 We do NOT want to desegment segments returned in error
1024 packets, as they're not part of a TCP connection. */
1025 pinfo->can_desegment = TRUE;
1028 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1029 offset + 16, 2, th_sum, "Checksum: 0x%04x (correct)", th_sum);
1031 proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
1032 offset + 16, 2, TRUE);
1033 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1034 offset + 16, 2, th_sum,
1035 "Checksum: 0x%04x (incorrect, should be 0x%04x)", th_sum,
1036 in_cksum_shouldbe(th_sum, computed_cksum));
1039 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1040 offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
1042 if (th_flags & TH_URG) {
1043 th_urp = tvb_get_ntohs(tvb, offset + 18);
1044 /* Export the urgent pointer, for the benefit of protocols such as
1046 tcpinfo.urgent = TRUE;
1047 tcpinfo.urgent_pointer = th_urp;
1048 if (check_col(pinfo->fd, COL_INFO))
1049 col_append_fstr(pinfo->fd, COL_INFO, " Urg=%u", th_urp);
1050 if (tcp_tree != NULL)
1051 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th_urp);
1053 tcpinfo.urgent = FALSE;
1055 if (check_col(pinfo->fd, COL_INFO))
1056 col_append_fstr(pinfo->fd, COL_INFO, " Len=%d", seglen);
1058 /* Decode TCP options, if any. */
1059 if (tree && hlen > TCPH_MIN_LEN) {
1060 /* There's more than just the fixed-length header. Decode the
1062 optlen = hlen - TCPH_MIN_LEN; /* length of options, in bytes */
1063 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
1064 "Options: (%d bytes)", optlen);
1065 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
1066 dissect_ip_tcp_options(tvb, offset + 20, optlen,
1067 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo->fd, field_tree);
1070 /* Skip over header + options */
1073 pinfo->ptype = PT_TCP;
1074 pinfo->srcport = th_sport;
1075 pinfo->destport = th_dport;
1077 /* Check the packet length to see if there's more data
1078 (it could be an ACK-only packet) */
1079 length_remaining = tvb_length_remaining(tvb, offset);
1080 if (length_remaining != 0) {
1081 if (th_flags & TH_RST) {
1085 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
1087 * A TCP SHOULD allow a received RST segment to include data.
1090 * It has been suggested that a RST segment could contain
1091 * ASCII text that encoded and explained the cause of the
1092 * RST. No standard has yet been established for such
1095 * so for segments with RST we just display the data as text.
1097 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
1099 tvb_format_text(tvb, offset, length_remaining));
1101 /* Can we desegment this segment? */
1102 if (pinfo->can_desegment) {
1104 desegment_tcp(tvb, pinfo, offset, th_seq, nxtseq, th_sport, th_dport, tree, tcp_tree);
1106 /* No - just call the subdissector. */
1107 decode_tcp_ports(tvb, offset, pinfo, tree, th_sport, th_dport);
1112 if( data_out_file ) {
1113 reassemble_tcp( th_seq, /* sequence number */
1114 seglen, /* data length */
1115 tvb_get_ptr(tvb, offset, length_remaining), /* data */
1116 length_remaining, /* captured data length */
1117 ( th_flags & TH_SYN ), /* is syn set? */
1126 proto_register_tcp(void)
1128 static hf_register_info hf[] = {
1131 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
1135 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
1139 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
1143 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
1147 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
1151 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
1155 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1159 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1162 { &hf_tcp_flags_cwr,
1163 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
1166 { &hf_tcp_flags_ecn,
1167 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
1170 { &hf_tcp_flags_urg,
1171 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
1174 { &hf_tcp_flags_ack,
1175 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
1178 { &hf_tcp_flags_push,
1179 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
1182 { &hf_tcp_flags_reset,
1183 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
1186 { &hf_tcp_flags_syn,
1187 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
1190 { &hf_tcp_flags_fin,
1191 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
1194 { &hf_tcp_window_size,
1195 { "Window size", "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1199 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1202 { &hf_tcp_checksum_bad,
1203 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1206 { &hf_tcp_urgent_pointer,
1207 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
1210 static gint *ett[] = {
1214 &ett_tcp_option_sack,
1217 module_t *tcp_module;
1219 proto_tcp = proto_register_protocol("Transmission Control Protocol",
1221 proto_register_field_array(proto_tcp, hf, array_length(hf));
1222 proto_register_subtree_array(ett, array_length(ett));
1224 /* subdissector code */
1225 subdissector_table = register_dissector_table("tcp.port");
1226 register_heur_dissector_list("tcp", &heur_subdissector_list);
1227 register_conv_dissector_list("tcp", &conv_subdissector_list);
1229 /* Register configuration preferences */
1230 tcp_module = prefs_register_protocol(proto_tcp, NULL);
1231 prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
1232 "Show TCP summary in protocol tree",
1233 "Whether the TCP summary line should be shown in the protocol tree",
1234 &tcp_summary_in_tree);
1235 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
1236 "Allow subdissector to desegment TCP streams",
1237 "Whether subdissector can request TCP streams to be desegmented",
1240 register_init_routine(tcp_desegment_init);
1241 register_init_routine(tcp_fragment_init);
1245 proto_reg_handoff_tcp(void)
1247 dissector_add("ip.proto", IP_PROTO_TCP, dissect_tcp, proto_tcp);