2 * Routines for TCP packet disassembly
4 * $Id: packet-tcp.c,v 1.110 2001/09/30 23:14:43 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 */
95 typedef struct _e_tcphdr {
100 guint8 th_off_x2; /* combines th_off and th_x2 */
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;
171 typedef struct _tcp_segment_key {
172 /* for ouwn bookkeeping inside packet-tcp.c */
183 free_all_segments(gpointer key_arg, gpointer value, gpointer user_data)
185 tcp_segment_key *key = key_arg;
187 if((key->src)&&(key->src->data)){
188 g_free((gpointer)key->src->data);
190 g_free((gpointer)key->src);
193 if((key->dst)&&(key->dst->data)){
194 g_free((gpointer)key->dst->data);
196 g_free((gpointer)key->dst);
204 tcp_segment_hash(gconstpointer k)
206 tcp_segment_key *key = (tcp_segment_key *)k;
212 tcp_segment_equal(gconstpointer k1, gconstpointer k2)
214 tcp_segment_key *key1 = (tcp_segment_key *)k1;
215 tcp_segment_key *key2 = (tcp_segment_key *)k2;
217 return ( ( (key1->seq==key2->seq)
218 &&(ADDRESSES_EQUAL(key1->src, key2->src))
219 &&(ADDRESSES_EQUAL(key1->dst, key2->dst))
224 tcp_desegment_init(void)
227 /* dont allocate any memory chunks unless the user really
234 if(tcp_segment_table){
235 g_hash_table_foreach_remove(tcp_segment_table,
236 free_all_segments, NULL);
238 tcp_segment_table = g_hash_table_new(tcp_segment_hash,
242 if(tcp_segment_key_chunk){
243 g_mem_chunk_destroy(tcp_segment_key_chunk);
245 tcp_segment_key_chunk = g_mem_chunk_new("tcp_segment_key_chunk",
246 sizeof(tcp_segment_key),
247 tcp_segment_init_count*sizeof(tcp_segment_key),
252 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
253 guint32 seq, guint32 nxtseq,
254 guint32 sport, guint32 dport,
255 proto_tree *tree, proto_tree *tcp_tree)
257 struct tcpinfo *tcpinfo = pinfo->private;
258 fragment_data *ipfd_head;
259 tcp_segment_key old_tsk, *tsk;
260 gboolean must_desegment = FALSE;
261 gboolean called_dissector = FALSE;
266 * Initialize these to assume no desegmentation.
267 * If that's not the case, these will be set appropriately
268 * by the subdissector.
270 pinfo->desegment_offset = 0;
271 pinfo->desegment_len = 0;
274 * Initialize this to assume that this segment will just be
275 * added to the middle of a desegmented chunk of data, so
276 * that we should show it all as data.
277 * If that's not the case, it will be set appropriately.
279 deseg_offset = offset;
281 /* First we must check if this TCP segment should be desegmented.
282 This is only to check if we should desegment this packet,
283 so we dont spend time doing COPY_ADDRESS/g_free.
284 We just "borrow" some address structures from pinfo instead. Cheaper.
286 old_tsk.src = &pinfo->src;
287 old_tsk.dst = &pinfo->dst;
289 tsk = g_hash_table_lookup(tcp_segment_table, &old_tsk);
292 /* OK, this segment was found, which means it continues
293 a higher-level PDU. This means we must desegment it.
294 Add it to the defragmentation lists.
296 ipfd_head = fragment_add(tvb, offset, pinfo, tsk->start_seq,
298 seq - tsk->start_seq,
300 (nxtseq < (tsk->start_seq + tsk->tot_len)) );
303 /* fragment_add() returned NULL, This means that
304 desegmentation is not completed yet.
305 (its like defragmentation but we know we will
306 always add the segments in order).
307 XXX - no, we don't; there is no guarantee that
308 TCP segments are in order on the wire.
310 we must add next segment to our table so we will
313 tcp_segment_key *new_tsk;
315 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
316 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
318 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
321 /* This segment was not found in our table, so it doesn't
322 contain a continuation of a higher-level PDU.
323 Call the normal subdissector.
325 decode_tcp_ports(tvb, offset, pinfo, tree,
327 called_dissector = TRUE;
329 /* Did the subdissector ask us to desegment some more data
330 before it could handle the packet?
331 If so we have to create some structures in our table but
332 this is something we only do the first time we see this
335 if(pinfo->desegment_len) {
336 if (!pinfo->fd->flags.visited)
337 must_desegment = TRUE;
340 * Set "deseg_offset" to the offset in "tvb"
341 * of the first byte of data that the
342 * subdissector didn't process.
344 deseg_offset = offset + pinfo->desegment_offset;
347 /* Either no desegmentation is necessary, or this is
348 segment contains the beginning but not the end of
349 a higher-level PDU and thus isn't completely
355 /* is it completely desegmented? */
358 proto_tree *st = NULL;
359 proto_item *si = NULL;
361 /* first we show a tree with all segments */
362 si = proto_tree_add_text(tcp_tree, tvb, 0, 0,
364 st = proto_item_add_subtree(si, ett_tcp_segments);
365 for(ipfd=ipfd_head->next; ipfd; ipfd=ipfd->next){
366 proto_tree_add_text(st, tvb, 0, 0,
367 "Frame:%d seq#:%d-%d [%d-%d]",
369 tsk->start_seq + ipfd->offset,
370 tsk->start_seq + ipfd->offset + ipfd->len - 1,
372 ipfd->offset + ipfd->len - 1);
376 * We only call subdissector for the last segment.
377 * Note that the last segment may include more than what
380 if(nxtseq >= (tsk->start_seq + tsk->tot_len)){
381 /* ok, lest call subdissector with desegmented data */
385 /* create a new TVB structure for desegmented data */
386 next_tvb = tvb_new_real_data(ipfd_head->data,
387 ipfd_head->datalen, ipfd_head->datalen,
390 /* add this tvb as a child to the original one */
391 tvb_set_child_real_data_tvbuff(tvb, next_tvb);
393 /* add desegmented data to the data source list */
394 pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
396 /* indicate that this is reassembled data */
397 tcpinfo->is_reassembled = TRUE;
399 /* save current value of *pinfo across call to
402 pinfo->compat_top_tvb = next_tvb;
403 pinfo->len = tvb_reported_length(next_tvb);
404 pinfo->captured_len = tvb_length(next_tvb);
406 /* call subdissector */
407 decode_tcp_ports(next_tvb, 0, pinfo, tree,
409 called_dissector = TRUE;
412 * Don't trash the new values of "desegment_offset"
413 * and "desegment_len".
415 save_pi.desegment_offset = pinfo->desegment_offset;
416 save_pi.desegment_len = pinfo->desegment_len;
419 /* Did the subdissector ask us to desegment some more
420 data? This means that the data at the beginning
421 of this segment completed a higher-level PDU,
422 but the data at the end of this segment started
423 a higher-level PDU but didn't complete it.
425 If so we have to create some structures in our
426 table but this is something we only do the first
427 time we see this packet.
429 if(pinfo->desegment_len) {
430 if (!pinfo->fd->flags.visited)
431 must_desegment = TRUE;
434 * The stuff we couldn't dissect must have
435 * come from this segment, so it's all in
438 * "pinfo->desegment_offset" is relative
439 * to the beginning of "next_tvb";
440 * we want an offset relative to the
441 * beginning of "tvb".
443 * First, compute the offset relative to
444 * the *end* of "next_tvb" - i.e., the number
445 * of bytes before the end of "next_tvb"
446 * at which the subdissector stopped.
447 * That's the length of "next_tvb" minus
448 * the offset, relative to the beginning
449 * of "next_tvb, at which the subdissector
453 ipfd_head->datalen - pinfo->desegment_offset;
456 * "tvb" and "next_tvb" end at the same byte
457 * of data, so the offset relative to the
458 * end of "next_tvb" of the byte at which
459 * we stopped is also the offset relative
460 * to the end of "tvb" of the byte at which
463 * Convert that back into an offset relative
464 * to the beginninng of "tvb", by taking
465 * the length of "tvb" and subtracting the
466 * offset relative to the end.
468 deseg_offset = tvb_length(tvb) - deseg_offset;
473 if (must_desegment) {
474 tcp_segment_key *tsk, *new_tsk;
477 * The sequence number at which the stuff to be desegmented
478 * starts is the sequence number of the byte at an offset
479 * of "deseg_offset" into "tvb".
481 * The sequence number of the byte at an offset of "offset"
482 * is "seq", i.e. the starting sequence number of this
483 * segment, so the sequence number of the byte at
484 * "deseg_offset" is "seq + (deseg_offset - offset)".
486 deseg_seq = seq + (deseg_offset - offset);
489 * XXX - how do we detect out-of-order transmissions?
490 * We can't just check for "nxtseq" being greater than
491 * "tsk->start_seq"; for now, we check for the difference
492 * being less than a megabyte, but this is a really
493 * gross hack - we really need to handle out-of-order
494 * transmissions correctly.
496 if ((nxtseq - deseg_seq) <= 1024*1024) {
497 /* OK, subdissector wants us to desegment
498 some data before it can process it. Add
499 what remains of this packet and set
500 up next packet/sequence number as well.
502 We must remember this segment
504 tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
505 tsk->src = g_malloc(sizeof(address));
506 COPY_ADDRESS(tsk->src, &pinfo->src);
507 tsk->dst = g_malloc(sizeof(address));
508 COPY_ADDRESS(tsk->dst, &pinfo->dst);
509 tsk->seq = deseg_seq;
510 tsk->start_seq = tsk->seq;
511 tsk->tot_len = nxtseq - tsk->start_seq + pinfo->desegment_len;
512 tsk->first_frame = pinfo->fd->num;
513 g_hash_table_insert(tcp_segment_table, tsk, tsk);
515 /* Add portion of segment unprocessed by the subdissector
516 to defragmentation lists */
517 fragment_add(tvb, deseg_offset, pinfo, tsk->start_seq,
519 tsk->seq - tsk->start_seq,
520 nxtseq - tsk->start_seq,
521 (nxtseq < tsk->start_seq + tsk->tot_len));
523 /* this is the next segment in the sequence we want */
524 new_tsk = g_mem_chunk_alloc(tcp_segment_key_chunk);
525 memcpy(new_tsk, tsk, sizeof(tcp_segment_key));
526 new_tsk->seq = nxtseq;
527 g_hash_table_insert(tcp_segment_table,new_tsk,new_tsk);
531 if (!called_dissector || pinfo->desegment_len != 0) {
533 * Either we didn't call the subdissector at all (i.e.,
534 * this is a segment that contains the middle of a
535 * higher-level PDU, but contains neither the beginning
536 * nor the end), or the subdissector couldn't dissect it
537 * all, as some data was missing (i.e., it set
538 * "pinfo->desegment_len" to the amount of additional
541 if (pinfo->desegment_offset == 0) {
543 * It couldn't, in fact, dissect any of it (the
544 * first byte it couldn't dissect is at an offset
545 * of "pinfo->desegment_offset" from the beginning
546 * of the payload, and that's 0).
547 * Just mark this as TCP.
549 if (check_col(pinfo->fd, COL_PROTOCOL)){
550 col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
552 if (check_col(pinfo->fd, COL_INFO)){
553 col_set_str(pinfo->fd, COL_INFO, "[Desegmented TCP]");
558 * Show what's left in the packet as data.
560 dissect_data(tvb, deseg_offset, pinfo, tree);
568 tcp_info_append_uint(frame_data *fd, const char *abbrev, guint32 val)
570 if (check_col(fd, COL_INFO))
571 col_append_fstr(fd, COL_INFO, " %s=%u", abbrev, val);
575 dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
576 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
580 mss = tvb_get_ntohs(tvb, offset + 2);
581 proto_tree_add_text(opt_tree, tvb, offset, optlen,
582 "%s: %u bytes", optp->name, mss);
583 tcp_info_append_uint(fd, "MSS", mss);
587 dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
588 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
592 ws = tvb_get_guint8(tvb, offset + 2);
593 proto_tree_add_text(opt_tree, tvb, offset, optlen,
594 "%s: %u bytes", optp->name, ws);
595 tcp_info_append_uint(fd, "WS", ws);
599 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
600 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
602 proto_tree *field_tree = NULL;
604 guint leftedge, rightedge;
606 tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
607 offset += 2; /* skip past type and length */
608 optlen -= 2; /* subtract size of type and length */
610 if (field_tree == NULL) {
611 /* Haven't yet made a subtree out of this option. Do so. */
612 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
615 proto_tree_add_text(field_tree, tvb, offset, optlen,
616 "(suboption would go past end of option)");
619 leftedge = tvb_get_ntohl(tvb, offset);
622 proto_tree_add_text(field_tree, tvb, offset, optlen,
623 "(suboption would go past end of option)");
626 /* XXX - check whether it goes past end of packet */
627 rightedge = tvb_get_ntohl(tvb, offset + 4);
629 proto_tree_add_text(field_tree, tvb, offset, 8,
630 "left edge = %u, right edge = %u", leftedge, rightedge);
631 tcp_info_append_uint(fd, "SLE", leftedge);
632 tcp_info_append_uint(fd, "SRE", rightedge);
638 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
639 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
643 echo = tvb_get_ntohl(tvb, offset + 2);
644 proto_tree_add_text(opt_tree, tvb, offset, optlen,
645 "%s: %u", optp->name, echo);
646 tcp_info_append_uint(fd, "ECHO", echo);
650 dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
651 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
655 tsv = tvb_get_ntohl(tvb, offset + 2);
656 tser = tvb_get_ntohl(tvb, offset + 6);
657 proto_tree_add_text(opt_tree, tvb, offset, optlen,
658 "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
659 tcp_info_append_uint(fd, "TSV", tsv);
660 tcp_info_append_uint(fd, "TSER", tser);
664 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
665 int offset, guint optlen, frame_data *fd, proto_tree *opt_tree)
669 cc = tvb_get_ntohl(tvb, offset + 2);
670 proto_tree_add_text(opt_tree, tvb, offset, optlen,
671 "%s: %u", optp->name, cc);
672 tcp_info_append_uint(fd, "CC", cc);
675 static const ip_tcp_opt tcpopts[] = {
694 "Maximum segment size",
698 dissect_tcpopt_maxseg
706 dissect_tcpopt_wscale
719 &ett_tcp_option_sack,
746 dissect_tcpopt_timestamp
782 #define N_TCP_OPTS (sizeof tcpopts / sizeof tcpopts[0])
785 static const true_false_string flags_set_truth = {
791 /* Determine if there is a sub-dissector and call it. This has been */
792 /* separated into a stand alone routine to other protocol dissectors */
793 /* can call to it, ie. socks */
796 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
797 proto_tree *tree, int src_port, int dst_port)
801 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
803 /* determine if this packet is part of a conversation and call dissector */
804 /* for the conversation if available */
806 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
807 src_port, dst_port, next_tvb, pinfo, tree))
810 /* do lookup with the subdissector table */
811 if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
812 dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
815 /* do lookup with the heuristic subdissector table */
816 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
819 /* Oh, well, we don't know this; dissect it as data. */
820 dissect_data(next_tvb, 0, pinfo, tree);
825 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
827 struct tcpinfo tcpinfo;
829 proto_tree *tcp_tree = NULL, *field_tree = NULL;
832 gchar flags[64] = "<None>";
833 gchar *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
844 guint16 computed_cksum;
845 guint length_remaining;
847 if (check_col(pinfo->fd, COL_PROTOCOL))
848 col_set_str(pinfo->fd, COL_PROTOCOL, "TCP");
850 /* Clear out the Info column. */
851 if (check_col(pinfo->fd, COL_INFO))
852 col_clear(pinfo->fd, COL_INFO);
854 /* Avoids alignment problems on many architectures. */
855 tvb_memcpy(tvb, (guint8 *)&th, offset, sizeof(e_tcphdr));
856 th.th_sport = ntohs(th.th_sport);
857 th.th_dport = ntohs(th.th_dport);
858 th.th_win = ntohs(th.th_win);
859 th.th_sum = ntohs(th.th_sum);
860 th.th_urp = ntohs(th.th_urp);
861 th.th_seq = ntohl(th.th_seq);
862 th.th_ack = ntohl(th.th_ack);
864 /* Export the urgent pointer, for the benefit of protocols such as
866 tcpinfo.urgent_pointer = th.th_urp;
868 /* Assume we'll pass un-reassembled data to subdissectors. */
869 tcpinfo.is_reassembled = FALSE;
871 pinfo->private = &tcpinfo;
873 if (check_col(pinfo->fd, COL_INFO) || tree) {
874 for (i = 0; i < 8; i++) {
876 if (th.th_flags & bpos) {
878 strcpy(&flags[fpos], ", ");
881 strcpy(&flags[fpos], fstr[i]);
888 hlen = hi_nibble(th.th_off_x2) * 4; /* TCP header length, in bytes */
890 reported_len = tvb_reported_length(tvb);
891 len = tvb_length(tvb);
893 /* Compute the length of data in this segment. */
894 seglen = reported_len - hlen;
896 /* Compute the sequence number of next octet after this segment. */
897 nxtseq = th.th_seq + seglen;
899 if (hlen < TCPH_MIN_LEN) {
900 if (check_col(pinfo->fd, COL_INFO))
901 col_add_fstr(pinfo->fd, COL_INFO, "Bogus TCP header length (%u, must be at least %u)",
903 ti = proto_tree_add_item(tree, proto_tcp, tvb, offset, hlen, FALSE);
904 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
906 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset, 1, hlen,
907 "Header length: %u bytes (bogus, must be at least %u)", hlen,
913 if (check_col(pinfo->fd, COL_INFO)) {
914 if (th.th_flags & TH_URG)
915 col_append_fstr(pinfo->fd, COL_INFO, "%s > %s [%s] Seq=%u Ack=%u Win=%u Urg=%u Len=%d",
916 get_tcp_port(th.th_sport), get_tcp_port(th.th_dport), flags,
917 th.th_seq, th.th_ack, th.th_win, th.th_urp, seglen);
919 col_append_fstr(pinfo->fd, COL_INFO, "%s > %s [%s] Seq=%u Ack=%u Win=%u Len=%d",
920 get_tcp_port(th.th_sport), get_tcp_port(th.th_dport), flags,
921 th.th_seq, th.th_ack, th.th_win, seglen);
925 if (tcp_summary_in_tree && hlen >= TCPH_MIN_LEN) {
926 ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, offset,
928 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u), Seq: %u, Ack: %u",
929 get_tcp_port(th.th_sport), th.th_sport,
930 get_tcp_port(th.th_dport), th.th_dport, th.th_seq, th.th_ack);
933 ti = proto_tree_add_item(tree, proto_tcp, tvb, offset, hlen, FALSE);
935 tcp_tree = proto_item_add_subtree(ti, ett_tcp);
936 proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th.th_sport,
937 "Source port: %s (%u)", get_tcp_port(th.th_sport), th.th_sport);
938 proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th.th_dport,
939 "Destination port: %s (%u)", get_tcp_port(th.th_dport), th.th_dport);
940 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th.th_sport);
941 proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th.th_dport);
942 proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th.th_seq);
943 if (nxtseq != th.th_seq)
944 proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
945 if (th.th_flags & TH_ACK)
946 proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th.th_ack);
947 proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
948 "Header length: %u bytes", hlen);
949 tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
950 th.th_flags, "Flags: 0x%04x (%s)", th.th_flags, flags);
951 field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
952 proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th.th_flags);
953 proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th.th_flags);
954 proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th.th_flags);
955 proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th.th_flags);
956 proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th.th_flags);
957 proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th.th_flags);
958 proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th.th_flags);
959 proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th.th_flags);
960 proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th.th_win);
964 * Assume, initially, that we can't desegment.
966 pinfo->can_desegment = FALSE;
968 if (!pinfo->fragmented && len >= reported_len) {
969 /* The packet isn't part of a fragmented datagram and isn't
970 truncated, so we can checksum it.
971 XXX - make a bigger scatter-gather list once we do fragment
974 /* Set up the fields of the pseudo-header. */
975 cksum_vec[0].ptr = pinfo->src.data;
976 cksum_vec[0].len = pinfo->src.len;
977 cksum_vec[1].ptr = pinfo->dst.data;
978 cksum_vec[1].len = pinfo->dst.len;
979 cksum_vec[2].ptr = (const guint8 *)&phdr;
980 switch (pinfo->src.type) {
983 phdr[0] = htonl((IP_PROTO_TCP<<16) + reported_len);
984 cksum_vec[2].len = 4;
988 phdr[0] = htonl(reported_len);
989 phdr[1] = htonl(IP_PROTO_TCP);
990 cksum_vec[2].len = 8;
994 /* TCP runs only atop IPv4 and IPv6.... */
995 g_assert_not_reached();
998 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, len);
999 cksum_vec[3].len = reported_len;
1000 computed_cksum = in_cksum(&cksum_vec[0], 4);
1001 if (computed_cksum == 0) {
1003 * We have all the data for this TCP segment, and the checksum of
1004 * the header and the data is good, so we can desegment it.
1005 * Is desegmentation enabled?
1007 if (tcp_desegment) {
1008 /* Yes - indicate that we will desegment. */
1009 pinfo->can_desegment = TRUE;
1011 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1012 offset + 16, 2, th.th_sum, "Checksum: 0x%04x (correct)", th.th_sum);
1014 proto_tree_add_boolean_hidden(tcp_tree, hf_tcp_checksum_bad, tvb,
1015 offset + 16, 2, TRUE);
1016 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1017 offset + 16, 2, th.th_sum,
1018 "Checksum: 0x%04x (incorrect, should be 0x%04x)", th.th_sum,
1019 in_cksum_shouldbe(th.th_sum, computed_cksum));
1022 proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
1023 offset + 16, 2, th.th_sum, "Checksum: 0x%04x", th.th_sum);
1025 if (th.th_flags & TH_URG)
1026 proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th.th_urp);
1028 /* Decode TCP options, if any. */
1029 if (tree && hlen > sizeof (e_tcphdr)) {
1030 /* There's more than just the fixed-length header. Decode the
1032 optlen = hlen - sizeof (e_tcphdr); /* length of options, in bytes */
1033 tf = proto_tree_add_text(tcp_tree, tvb, offset + 20, optlen,
1034 "Options: (%d bytes)", optlen);
1035 field_tree = proto_item_add_subtree(tf, ett_tcp_options);
1036 dissect_ip_tcp_options(tvb, offset + 20, optlen,
1037 tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo->fd, field_tree);
1040 /* Skip over header + options */
1043 pinfo->ptype = PT_TCP;
1044 pinfo->srcport = th.th_sport;
1045 pinfo->destport = th.th_dport;
1047 /* Check the packet length to see if there's more data
1048 (it could be an ACK-only packet) */
1049 length_remaining = tvb_length_remaining(tvb, offset);
1050 if (length_remaining != 0) {
1051 if (th.th_flags & TH_RST) {
1055 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
1057 * A TCP SHOULD allow a received RST segment to include data.
1060 * It has been suggested that a RST segment could contain
1061 * ASCII text that encoded and explained the cause of the
1062 * RST. No standard has yet been established for such
1065 * so for segments with RST we just display the data as text.
1067 proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
1069 tvb_format_text(tvb, offset, length_remaining));
1071 /* Can we desegment this segment? */
1072 if (pinfo->can_desegment) {
1074 desegment_tcp(tvb, pinfo, offset, th.th_seq, nxtseq, th.th_sport, th.th_dport, tree, tcp_tree);
1076 /* No - just call the subdissector. */
1077 decode_tcp_ports(tvb, offset, pinfo, tree, th.th_sport, th.th_dport);
1082 if( data_out_file ) {
1083 reassemble_tcp( th.th_seq, /* sequence number */
1084 seglen, /* data length */
1085 tvb_get_ptr(tvb, offset, length_remaining), /* data */
1086 length_remaining, /* captured data length */
1087 ( th.th_flags & TH_SYN ), /* is syn set? */
1096 proto_register_tcp(void)
1098 static hf_register_info hf[] = {
1101 { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
1105 { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
1109 { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
1113 { "Sequence number", "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
1117 { "Next sequence number", "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
1121 { "Acknowledgement number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
1125 { "Header Length", "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
1129 { "Flags", "tcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
1132 { &hf_tcp_flags_cwr,
1133 { "Congestion Window Reduced (CWR)", "tcp.flags.cwr", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_CWR,
1136 { &hf_tcp_flags_ecn,
1137 { "ECN-Echo", "tcp.flags.ecn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ECN,
1140 { &hf_tcp_flags_urg,
1141 { "Urgent", "tcp.flags.urg", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_URG,
1144 { &hf_tcp_flags_ack,
1145 { "Acknowledgment", "tcp.flags.ack", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_ACK,
1148 { &hf_tcp_flags_push,
1149 { "Push", "tcp.flags.push", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_PUSH,
1152 { &hf_tcp_flags_reset,
1153 { "Reset", "tcp.flags.reset", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_RST,
1156 { &hf_tcp_flags_syn,
1157 { "Syn", "tcp.flags.syn", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_SYN,
1160 { &hf_tcp_flags_fin,
1161 { "Fin", "tcp.flags.fin", FT_BOOLEAN, 8, TFS(&flags_set_truth), TH_FIN,
1164 { &hf_tcp_window_size,
1165 { "Window size", "tcp.window_size", FT_UINT16, BASE_DEC, NULL, 0x0,
1169 { "Checksum", "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
1172 { &hf_tcp_checksum_bad,
1173 { "Bad Checksum", "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1176 { &hf_tcp_urgent_pointer,
1177 { "Urgent pointer", "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
1180 static gint *ett[] = {
1184 &ett_tcp_option_sack,
1187 module_t *tcp_module;
1189 proto_tcp = proto_register_protocol("Transmission Control Protocol",
1191 proto_register_field_array(proto_tcp, hf, array_length(hf));
1192 proto_register_subtree_array(ett, array_length(ett));
1194 /* subdissector code */
1195 subdissector_table = register_dissector_table("tcp.port");
1196 register_heur_dissector_list("tcp", &heur_subdissector_list);
1197 register_conv_dissector_list("tcp", &conv_subdissector_list);
1199 /* Register configuration preferences */
1200 tcp_module = prefs_register_protocol(proto_tcp, NULL);
1201 prefs_register_bool_preference(tcp_module, "tcp_summary_in_tree",
1202 "Show TCP summary in protocol tree",
1203 "Whether the TCP summary line should be shown in the protocol tree",
1204 &tcp_summary_in_tree);
1205 prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
1206 "Allow subdissector to desegment TCP streams",
1207 "Whether subdissector can request TCP streams to be desegmented",
1210 register_init_routine(tcp_desegment_init);
1211 register_init_routine(tcp_fragment_init);
1215 proto_reg_handoff_tcp(void)
1217 dissector_add("ip.proto", IP_PROTO_TCP, dissect_tcp, proto_tcp);