5c0873f8377cc2b67ed8dda17ff9e1c543e3906c
[metze/wireshark/wip.git] / epan / dissectors / packet-tcp.c
1 /* packet-tcp.c
2  * Routines for TCP packet disassembly
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <glib.h>
30 #include <epan/in_cksum.h>
31
32 #include <epan/packet.h>
33 #include <epan/exceptions.h>
34 #include <epan/addr_resolv.h>
35 #include <epan/ipproto.h>
36 #include <epan/expert.h>
37 #include <epan/ip_opts.h>
38 #include <epan/follow.h>
39 #include <epan/prefs.h>
40 #include <epan/wmem/wmem.h>
41 #include <epan/show_exception.h>
42 #include <epan/conversation.h>
43 #include <epan/reassemble.h>
44 #include <epan/tap.h>
45 #include <epan/decode_as.h>
46
47 #include "packet-tcp.h"
48 #include "packet-ip.h"
49 #include "packet-icmp.h"
50
51 static int tcp_tap = -1;
52
53 /* Place TCP summary in proto tree */
54 static gboolean tcp_summary_in_tree = TRUE;
55
56 /*
57  * Flag to control whether to check the TCP checksum.
58  *
59  * In at least some Solaris network traces, there are packets with bad
60  * TCP checksums, but the traffic appears to indicate that the packets
61  * *were* received; the packets were probably sent by the host on which
62  * the capture was being done, on a network interface to which
63  * checksumming was offloaded, so that DLPI supplied an un-checksummed
64  * packet to the capture program but a checksummed packet got put onto
65  * the wire.
66  */
67 static gboolean tcp_check_checksum = FALSE;
68
69 /*
70  * Window scaling values to be used when not known (set as a preference) */
71  enum scaling_window_value {
72   WindowScaling_NotKnown=-1,
73   WindowScaling_0=0,
74   WindowScaling_1,
75   WindowScaling_2,
76   WindowScaling_3,
77   WindowScaling_4,
78   WindowScaling_5,
79   WindowScaling_6,
80   WindowScaling_7,
81   WindowScaling_8,
82   WindowScaling_9,
83   WindowScaling_10,
84   WindowScaling_11,
85   WindowScaling_12,
86   WindowScaling_13,
87   WindowScaling_14
88 };
89 static gint tcp_default_window_scaling = (gint)WindowScaling_NotKnown;
90
91
92 extern FILE* data_out_file;
93
94 static int proto_tcp = -1;
95 static int hf_tcp_srcport = -1;
96 static int hf_tcp_dstport = -1;
97 static int hf_tcp_port = -1;
98 static int hf_tcp_stream = -1;
99 static int hf_tcp_seq = -1;
100 static int hf_tcp_nxtseq = -1;
101 static int hf_tcp_ack = -1;
102 static int hf_tcp_hdr_len = -1;
103 static int hf_tcp_flags = -1;
104 static int hf_tcp_flags_res = -1;
105 static int hf_tcp_flags_ns = -1;
106 static int hf_tcp_flags_cwr = -1;
107 static int hf_tcp_flags_ecn = -1;
108 static int hf_tcp_flags_urg = -1;
109 static int hf_tcp_flags_ack = -1;
110 static int hf_tcp_flags_push = -1;
111 static int hf_tcp_flags_reset = -1;
112 static int hf_tcp_flags_syn = -1;
113 static int hf_tcp_flags_fin = -1;
114 static int hf_tcp_window_size_value = -1;
115 static int hf_tcp_window_size = -1;
116 static int hf_tcp_window_size_scalefactor = -1;
117 static int hf_tcp_checksum = -1;
118 static int hf_tcp_checksum_bad = -1;
119 static int hf_tcp_checksum_good = -1;
120 static int hf_tcp_len = -1;
121 static int hf_tcp_urgent_pointer = -1;
122 static int hf_tcp_analysis = -1;
123 static int hf_tcp_analysis_flags = -1;
124 static int hf_tcp_analysis_bytes_in_flight = -1;
125 static int hf_tcp_analysis_acks_frame = -1;
126 static int hf_tcp_analysis_ack_rtt = -1;
127 static int hf_tcp_analysis_rto = -1;
128 static int hf_tcp_analysis_rto_frame = -1;
129 static int hf_tcp_analysis_duplicate_ack = -1;
130 static int hf_tcp_analysis_duplicate_ack_num = -1;
131 static int hf_tcp_analysis_duplicate_ack_frame = -1;
132 static int hf_tcp_continuation_to = -1;
133 static int hf_tcp_pdu_time = -1;
134 static int hf_tcp_pdu_size = -1;
135 static int hf_tcp_pdu_last_frame = -1;
136 static int hf_tcp_reassembled_in = -1;
137 static int hf_tcp_reassembled_length = -1;
138 static int hf_tcp_reassembled_data = -1;
139 static int hf_tcp_segments = -1;
140 static int hf_tcp_segment = -1;
141 static int hf_tcp_segment_overlap = -1;
142 static int hf_tcp_segment_overlap_conflict = -1;
143 static int hf_tcp_segment_multiple_tails = -1;
144 static int hf_tcp_segment_too_long_fragment = -1;
145 static int hf_tcp_segment_error = -1;
146 static int hf_tcp_segment_count = -1;
147 static int hf_tcp_options = -1;
148 static int hf_tcp_option_kind = -1;
149 static int hf_tcp_option_len = -1;
150 static int hf_tcp_option_mss = -1;
151 static int hf_tcp_option_mss_val = -1;
152 static int hf_tcp_option_wscale_shift = -1;
153 static int hf_tcp_option_wscale_multiplier = -1;
154 static int hf_tcp_option_sack_perm = -1;
155 static int hf_tcp_option_sack = -1;
156 static int hf_tcp_option_sack_sle = -1;
157 static int hf_tcp_option_sack_sre = -1;
158 static int hf_tcp_option_sack_range_count = -1;
159 static int hf_tcp_option_echo = -1;
160 static int hf_tcp_option_timestamp_tsval = -1;
161 static int hf_tcp_option_timestamp_tsecr = -1;
162 static int hf_tcp_option_cc = -1;
163 static int hf_tcp_option_qs = -1;
164 static int hf_tcp_option_exp = -1;
165 static int hf_tcp_option_exp_data = -1;
166 static int hf_tcp_option_exp_magic_number = -1;
167
168 static int hf_tcp_option_rvbd_probe = -1;
169 static int hf_tcp_option_rvbd_probe_version1 = -1;
170 static int hf_tcp_option_rvbd_probe_version2 = -1;
171 static int hf_tcp_option_rvbd_probe_type1 = -1;
172 static int hf_tcp_option_rvbd_probe_type2 = -1;
173 static int hf_tcp_option_rvbd_probe_optlen = -1;
174 static int hf_tcp_option_rvbd_probe_prober = -1;
175 static int hf_tcp_option_rvbd_probe_proxy = -1;
176 static int hf_tcp_option_rvbd_probe_client = -1;
177 static int hf_tcp_option_rvbd_probe_proxy_port = -1;
178 static int hf_tcp_option_rvbd_probe_appli_ver = -1;
179 static int hf_tcp_option_rvbd_probe_storeid = -1;
180 static int hf_tcp_option_rvbd_probe_flags = -1;
181 static int hf_tcp_option_rvbd_probe_flag_last_notify = -1;
182 static int hf_tcp_option_rvbd_probe_flag_server_connected = -1;
183 static int hf_tcp_option_rvbd_probe_flag_not_cfe = -1;
184 static int hf_tcp_option_rvbd_probe_flag_sslcert = -1;
185 static int hf_tcp_option_rvbd_probe_flag_probe_cache = -1;
186
187 static int hf_tcp_option_rvbd_trpy = -1;
188 static int hf_tcp_option_rvbd_trpy_flags = -1;
189 static int hf_tcp_option_rvbd_trpy_flag_mode = -1;
190 static int hf_tcp_option_rvbd_trpy_flag_oob = -1;
191 static int hf_tcp_option_rvbd_trpy_flag_chksum = -1;
192 static int hf_tcp_option_rvbd_trpy_flag_fw_rst = -1;
193 static int hf_tcp_option_rvbd_trpy_flag_fw_rst_inner = -1;
194 static int hf_tcp_option_rvbd_trpy_flag_fw_rst_probe = -1;
195 static int hf_tcp_option_rvbd_trpy_src = -1;
196 static int hf_tcp_option_rvbd_trpy_dst = -1;
197 static int hf_tcp_option_rvbd_trpy_src_port = -1;
198 static int hf_tcp_option_rvbd_trpy_dst_port = -1;
199 static int hf_tcp_option_rvbd_trpy_client_port = -1;
200
201 static int hf_tcp_option_mptcp_flags = -1;
202 static int hf_tcp_option_mptcp_B_flag = -1;
203 static int hf_tcp_option_mptcp_C_flag = -1;
204 static int hf_tcp_option_mptcp_S_flag = -1;
205 static int hf_tcp_option_mptcp_F_flag = -1;
206 static int hf_tcp_option_mptcp_m_flag = -1;
207 static int hf_tcp_option_mptcp_M_flag = -1;
208 static int hf_tcp_option_mptcp_a_flag = -1;
209 static int hf_tcp_option_mptcp_A_flag = -1;
210 static int hf_tcp_option_mptcp_subtype = -1;
211 static int hf_tcp_option_mptcp_version = -1;
212 static int hf_tcp_option_mptcp_address_id = -1;
213 static int hf_tcp_option_mptcp_recv_token = -1;
214 static int hf_tcp_option_mptcp_sender_key = -1;
215 static int hf_tcp_option_mptcp_recv_key = -1;
216 static int hf_tcp_option_mptcp_sender_rand = -1;
217 static int hf_tcp_option_mptcp_sender_trunc_mac = -1;
218 static int hf_tcp_option_mptcp_sender_mac = -1;
219 static int hf_tcp_option_mptcp_data_ack = -1;
220 static int hf_tcp_option_mptcp_data_seq_no = -1;
221 static int hf_tcp_option_mptcp_subflow_seq_no = -1;
222 static int hf_tcp_option_mptcp_data_lvl_len = -1;
223 static int hf_tcp_option_mptcp_checksum = -1;
224 static int hf_tcp_option_mptcp_ipver = -1;
225 static int hf_tcp_option_mptcp_ipv4 = -1;
226 static int hf_tcp_option_mptcp_ipv6 = -1;
227 static int hf_tcp_option_mptcp_port = -1;
228 static int hf_tcp_option_fast_open = -1;
229 static int hf_tcp_option_fast_open_cookie_request = -1;
230 static int hf_tcp_option_fast_open_cookie = -1;
231
232 static int hf_tcp_ts_relative = -1;
233 static int hf_tcp_ts_delta = -1;
234 static int hf_tcp_option_type = -1;
235 static int hf_tcp_option_type_copy = -1;
236 static int hf_tcp_option_type_class = -1;
237 static int hf_tcp_option_type_number = -1;
238 static int hf_tcp_option_scps = -1;
239 static int hf_tcp_option_scps_vector = -1;
240 static int hf_tcp_option_scps_binding = -1;
241 static int hf_tcp_option_scps_binding_len = -1;
242 static int hf_tcp_scpsoption_flags_bets = -1;
243 static int hf_tcp_scpsoption_flags_snack1 = -1;
244 static int hf_tcp_scpsoption_flags_snack2 = -1;
245 static int hf_tcp_scpsoption_flags_compress = -1;
246 static int hf_tcp_scpsoption_flags_nlts = -1;
247 static int hf_tcp_scpsoption_flags_reserved = -1;
248 static int hf_tcp_scpsoption_connection_id = -1;
249 static int hf_tcp_option_snack = -1;
250 static int hf_tcp_option_snack_offset = -1;
251 static int hf_tcp_option_snack_size = -1;
252 static int hf_tcp_option_snack_le = -1;
253 static int hf_tcp_option_snack_re = -1;
254 static int hf_tcp_option_user_to = -1;
255 static int hf_tcp_option_user_to_granularity = -1;
256 static int hf_tcp_option_user_to_val = -1;
257 static int hf_tcp_proc_src_uid = -1;
258 static int hf_tcp_proc_src_pid = -1;
259 static int hf_tcp_proc_src_uname = -1;
260 static int hf_tcp_proc_src_cmd = -1;
261 static int hf_tcp_proc_dst_uid = -1;
262 static int hf_tcp_proc_dst_pid = -1;
263 static int hf_tcp_proc_dst_uname = -1;
264 static int hf_tcp_proc_dst_cmd = -1;
265 static int hf_tcp_segment_data = -1;
266
267 static gint ett_tcp = -1;
268 static gint ett_tcp_flags = -1;
269 static gint ett_tcp_option_type = -1;
270 static gint ett_tcp_options = -1;
271 static gint ett_tcp_option_timestamp = -1;
272 static gint ett_tcp_option_mss = -1;
273 static gint ett_tcp_option_wscale = -1;
274 static gint ett_tcp_option_sack = -1;
275 static gint ett_tcp_option_scps = -1;
276 static gint ett_tcp_option_scps_extended = -1;
277 static gint ett_tcp_option_user_to = -1;
278 static gint ett_tcp_option_exp = -1;
279 static gint ett_tcp_option_sack_perm = -1;
280 static gint ett_tcp_analysis = -1;
281 static gint ett_tcp_analysis_faults = -1;
282 static gint ett_tcp_timestamps = -1;
283 static gint ett_tcp_segments = -1;
284 static gint ett_tcp_segment  = -1;
285 static gint ett_tcp_checksum = -1;
286 static gint ett_tcp_process_info = -1;
287 static gint ett_tcp_option_mptcp = -1;
288
289 static gint ett_tcp_opt_rvbd_probe = -1;
290 static gint ett_tcp_opt_rvbd_probe_flags = -1;
291 static gint ett_tcp_opt_rvbd_trpy = -1;
292 static gint ett_tcp_opt_rvbd_trpy_flags = -1;
293
294 static expert_field ei_tcp_opt_len_invalid = EI_INIT;
295 static expert_field ei_tcp_analysis_retransmission = EI_INIT;
296 static expert_field ei_tcp_analysis_fast_retransmission = EI_INIT;
297 static expert_field ei_tcp_analysis_spurious_retransmission = EI_INIT;
298 static expert_field ei_tcp_analysis_out_of_order = EI_INIT;
299 static expert_field ei_tcp_analysis_reused_ports = EI_INIT;
300 static expert_field ei_tcp_analysis_lost_packet = EI_INIT;
301 static expert_field ei_tcp_analysis_ack_lost_packet = EI_INIT;
302 static expert_field ei_tcp_analysis_window_update = EI_INIT;
303 static expert_field ei_tcp_analysis_window_full = EI_INIT;
304 static expert_field ei_tcp_analysis_keep_alive = EI_INIT;
305 static expert_field ei_tcp_analysis_keep_alive_ack = EI_INIT;
306 static expert_field ei_tcp_analysis_duplicate_ack = EI_INIT;
307 static expert_field ei_tcp_analysis_zero_window_probe = EI_INIT;
308 static expert_field ei_tcp_analysis_zero_window = EI_INIT;
309 static expert_field ei_tcp_analysis_zero_window_probe_ack = EI_INIT;
310 static expert_field ei_tcp_scps_capable = EI_INIT;
311 static expert_field ei_tcp_option_snack_sequence = EI_INIT;
312 static expert_field ei_tcp_short_segment = EI_INIT;
313 static expert_field ei_tcp_ack_nonzero = EI_INIT;
314 static expert_field ei_tcp_connection_sack = EI_INIT;
315 static expert_field ei_tcp_connection_syn = EI_INIT;
316 static expert_field ei_tcp_connection_fin = EI_INIT;
317 static expert_field ei_tcp_connection_rst = EI_INIT;
318 static expert_field ei_tcp_checksum_ffff = EI_INIT;
319 static expert_field ei_tcp_checksum_bad = EI_INIT;
320 static expert_field ei_tcp_urgent_pointer_non_zero = EI_INIT;
321
322 /* Some protocols such as encrypted DCE/RPCoverHTTP have dependencies
323  * from one PDU to the next PDU and require that they are called in sequence.
324  * These protocols would not be able to handle PDUs coming out of order
325  * or for example when a PDU is seen twice, like for retransmissions.
326  * This preference can be set for such protocols to make sure that we don't
327  * invoke the subdissectors for retransmitted or out-of-order segments.
328  */
329 static gboolean tcp_no_subdissector_on_error = FALSE;
330
331 /*
332  * FF: (draft-ietf-tcpm-experimental-options-03)
333  * With this flag set we assume the option structure for experimental
334  * codepoints (253, 254) has a magic number field (first field after the
335  * Kind and Length).  The magic number is used to differentiate different
336  * experiments and thus will be used in data dissection.
337  */
338 static gboolean tcp_exp_options_with_magic = TRUE;
339
340 /*
341  *  TCP option
342  */
343 #define TCPOPT_NOP              1       /* Padding */
344 #define TCPOPT_EOL              0       /* End of options */
345 #define TCPOPT_MSS              2       /* Segment size negotiating */
346 #define TCPOPT_WINDOW           3       /* Window scaling */
347 #define TCPOPT_SACK_PERM        4       /* SACK Permitted */
348 #define TCPOPT_SACK             5       /* SACK Block */
349 #define TCPOPT_ECHO             6
350 #define TCPOPT_ECHOREPLY        7
351 #define TCPOPT_TIMESTAMP        8       /* Better RTT estimations/PAWS */
352 #define TCPOPT_CC               11
353 #define TCPOPT_CCNEW            12
354 #define TCPOPT_CCECHO           13
355 #define TCPOPT_MD5              19      /* RFC2385 */
356 #define TCPOPT_MPTCP            0x1e    /* Multipath TCP */
357 #define TCPOPT_SCPS             20      /* SCPS Capabilities */
358 #define TCPOPT_SNACK            21      /* SCPS SNACK */
359 #define TCPOPT_RECBOUND         22      /* SCPS Record Boundary */
360 #define TCPOPT_CORREXP          23      /* SCPS Corruption Experienced */
361 #define TCPOPT_QS               27      /* RFC4782 */
362 #define TCPOPT_USER_TO          28      /* RFC5482 */
363 #define TCPOPT_EXP_FD           0xfd    /* Experimental, reserved */
364 #define TCPOPT_EXP_FE           0xfe    /* Experimental, reserved */
365 /* Non IANA registered option numbers */
366 #define TCPOPT_RVBD_PROBE       76      /* Riverbed probe option */
367 #define TCPOPT_RVBD_TRPY        78      /* Riverbed transparency option */
368
369 /*
370  *     TCP option lengths
371  */
372 #define TCPOLEN_MSS            4
373 #define TCPOLEN_WINDOW         3
374 #define TCPOLEN_SACK_PERM      2
375 #define TCPOLEN_SACK_MIN       2
376 #define TCPOLEN_ECHO           6
377 #define TCPOLEN_ECHOREPLY      6
378 #define TCPOLEN_TIMESTAMP     10
379 #define TCPOLEN_CC             6
380 #define TCPOLEN_CCNEW          6
381 #define TCPOLEN_CCECHO         6
382 #define TCPOLEN_MD5           18
383 #define TCPOLEN_MPTCP_MIN      8
384 #define TCPOLEN_SCPS           4
385 #define TCPOLEN_SNACK          6
386 #define TCPOLEN_RECBOUND       2
387 #define TCPOLEN_CORREXP        2
388 #define TCPOLEN_QS             8
389 #define TCPOLEN_USER_TO        4
390 #define TCPOLEN_RVBD_PROBE_MIN 3
391 #define TCPOLEN_RVBD_TRPY_MIN 16
392 #define TCPOLEN_EXP_MIN        2
393
394 /*
395  *     Multipath TCP subtypes
396  */
397 #define TCPOPT_MPTCP_MP_CAPABLE    0x0    /* Multipath TCP Multipath Capable */
398 #define TCPOPT_MPTCP_MP_JOIN       0x1    /* Multipath TCP Join Connection */
399 #define TCPOPT_MPTCP_DSS           0x2    /* Multipath TCP Data Sequence Signal */
400 #define TCPOPT_MPTCP_ADD_ADDR      0x3    /* Multipath TCP Add Address */
401 #define TCPOPT_MPTCP_REMOVE_ADDR   0x4    /* Multipath TCP Remove Address */
402 #define TCPOPT_MPTCP_MP_PRIO       0x5    /* Multipath TCP Change Subflow Priority */
403 #define TCPOPT_MPTCP_MP_FAIL       0x6    /* Multipath TCP Fallback */
404
405 static const true_false_string tcp_option_user_to_granularity = {
406   "Minutes", "Seconds"
407 };
408
409 static const value_string tcp_option_kind_vs[] = {
410     { TCPOPT_EXP_FD, "Experimental 0xFD" },
411     { TCPOPT_EXP_FE, "Experimental 0xFE" },
412     { TCPOPT_WINDOW, "Window Scale" },
413     { TCPOPT_SACK_PERM, "SACK Permission" },
414     { TCPOPT_MSS, "MSS size" },
415     { TCPOPT_TIMESTAMP, "Timestamp" },
416     { TCPOPT_MPTCP, "Multipath TCP" },
417     { 0, NULL }
418 };
419
420 /* not all of the hf_fields below make sense for TCP but we have to provide
421    them anyways to comply with the API (which was aimed for IP fragment
422    reassembly) */
423 static const fragment_items tcp_segment_items = {
424     &ett_tcp_segment,
425     &ett_tcp_segments,
426     &hf_tcp_segments,
427     &hf_tcp_segment,
428     &hf_tcp_segment_overlap,
429     &hf_tcp_segment_overlap_conflict,
430     &hf_tcp_segment_multiple_tails,
431     &hf_tcp_segment_too_long_fragment,
432     &hf_tcp_segment_error,
433     &hf_tcp_segment_count,
434     &hf_tcp_reassembled_in,
435     &hf_tcp_reassembled_length,
436     &hf_tcp_reassembled_data,
437     "Segments"
438 };
439
440 static const value_string mptcp_subtype_vs[] = {
441     { TCPOPT_MPTCP_MP_CAPABLE, "Multipath Capable" },
442     { TCPOPT_MPTCP_MP_JOIN, "Join Connection" },
443     { TCPOPT_MPTCP_DSS, "Data Sequence Signal" },
444     { TCPOPT_MPTCP_ADD_ADDR, "Add Address"},
445     { TCPOPT_MPTCP_REMOVE_ADDR, "Remove Address" },
446     { TCPOPT_MPTCP_MP_PRIO, "Change Subflow Priority" },
447     { TCPOPT_MPTCP_MP_FAIL, "TCP Fallback" },
448     { 0, NULL }
449 };
450
451 static dissector_table_t subdissector_table;
452 static heur_dissector_list_t heur_subdissector_list;
453 static dissector_handle_t data_handle;
454 static dissector_handle_t sport_handle;
455 static guint32 tcp_stream_count;
456
457 /* XXX - redefined here to not create UI dependencies */
458 #define UTF8_LEFTWARDS_ARROW            "\xe2\x86\x90"      /* 8592 / 0x2190 */
459 #define UTF8_RIGHTWARDS_ARROW           "\xe2\x86\x92"      /* 8594 / 0x2192 */
460 #define UTF8_LEFT_RIGHT_ARROW           "\xe2\x86\x94"      /* 8596 / 0x2194 */
461
462 static void tcp_src_prompt(packet_info *pinfo, gchar* result)
463 {
464     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Source (%u%s)", pinfo->srcport, UTF8_RIGHTWARDS_ARROW);
465 }
466
467 static gpointer tcp_src_value(packet_info *pinfo)
468 {
469     return GUINT_TO_POINTER(pinfo->srcport);
470 }
471
472 static void tcp_dst_prompt(packet_info *pinfo, gchar* result)
473 {
474     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Destination (%s%u)", UTF8_RIGHTWARDS_ARROW, pinfo->destport);
475 }
476
477 static gpointer tcp_dst_value(packet_info *pinfo)
478 {
479     return GUINT_TO_POINTER(pinfo->destport);
480 }
481
482 static void tcp_both_prompt(packet_info *pinfo, gchar* result)
483 {
484     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Both (%u%s%u)", pinfo->srcport,UTF8_LEFT_RIGHT_ARROW, pinfo->destport);
485 }
486
487 /* TCP structs and definitions */
488
489 /* **************************************************************************
490  * RTT, relative sequence numbers, window scaling & etc.
491  * **************************************************************************/
492 static gboolean tcp_analyze_seq           = TRUE;
493 static gboolean tcp_relative_seq          = TRUE;
494 static gboolean tcp_track_bytes_in_flight = TRUE;
495 static gboolean tcp_calculate_ts          = FALSE;
496
497 #define TCP_A_RETRANSMISSION          0x0001
498 #define TCP_A_LOST_PACKET             0x0002
499 #define TCP_A_ACK_LOST_PACKET         0x0004
500 #define TCP_A_KEEP_ALIVE              0x0008
501 #define TCP_A_DUPLICATE_ACK           0x0010
502 #define TCP_A_ZERO_WINDOW             0x0020
503 #define TCP_A_ZERO_WINDOW_PROBE       0x0040
504 #define TCP_A_ZERO_WINDOW_PROBE_ACK   0x0080
505 #define TCP_A_KEEP_ALIVE_ACK          0x0100
506 #define TCP_A_OUT_OF_ORDER            0x0200
507 #define TCP_A_FAST_RETRANSMISSION     0x0400
508 #define TCP_A_WINDOW_UPDATE           0x0800
509 #define TCP_A_WINDOW_FULL             0x1000
510 #define TCP_A_REUSED_PORTS            0x2000
511 #define TCP_A_SPURIOUS_RETRANSMISSION 0x4000
512
513 static void
514 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
515     proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
516     guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
517     struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo);
518
519
520 struct tcp_analysis *
521 init_tcp_conversation_data(packet_info *pinfo)
522 {
523     struct tcp_analysis *tcpd;
524
525     /* Initialize the tcp protocol data structure to add to the tcp conversation */
526     tcpd=wmem_new0(wmem_file_scope(), struct tcp_analysis);
527     tcpd->flow1.win_scale=-1;
528     tcpd->flow1.window = G_MAXUINT32;
529     tcpd->flow1.multisegment_pdus=wmem_tree_new(wmem_file_scope());
530     /*
531     tcpd->flow1.username = NULL;
532     tcpd->flow1.command = NULL;
533     */
534     tcpd->flow2.window = G_MAXUINT32;
535     tcpd->flow2.win_scale=-1;
536     tcpd->flow2.multisegment_pdus=wmem_tree_new(wmem_file_scope());
537     /*
538     tcpd->flow2.username = NULL;
539     tcpd->flow2.command = NULL;
540     */
541     tcpd->acked_table=wmem_tree_new(wmem_file_scope());
542     tcpd->ts_first.secs=pinfo->fd->abs_ts.secs;
543     tcpd->ts_first.nsecs=pinfo->fd->abs_ts.nsecs;
544     tcpd->ts_prev.secs=pinfo->fd->abs_ts.secs;
545     tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs;
546     tcpd->flow1.valid_bif = 1;
547     tcpd->flow2.valid_bif = 1;
548     tcpd->stream = tcp_stream_count++;
549     tcpd->server_port = 0;
550
551     return tcpd;
552 }
553
554 struct tcp_analysis *
555 get_tcp_conversation_data(conversation_t *conv, packet_info *pinfo)
556 {
557     int direction;
558     struct tcp_analysis *tcpd;
559
560     /* Did the caller supply the conversation pointer? */
561     if( conv==NULL )
562             conv = find_or_create_conversation(pinfo);
563
564     /* Get the data for this conversation */
565     tcpd=(struct tcp_analysis *)conversation_get_proto_data(conv, proto_tcp);
566
567     /* If the conversation was just created or it matched a
568      * conversation with template options, tcpd will not
569      * have been initialized. So, initialize
570      * a new tcpd structure for the conversation.
571      */
572     if (!tcpd) {
573         tcpd = init_tcp_conversation_data(pinfo);
574         conversation_add_proto_data(conv, proto_tcp, tcpd);
575     }
576
577     if (!tcpd) {
578       return NULL;
579     }
580
581     /* check direction and get ua lists */
582     direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
583     /* if the addresses are equal, match the ports instead */
584     if(direction==0) {
585         direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
586     }
587     if(direction>=0) {
588         tcpd->fwd=&(tcpd->flow1);
589         tcpd->rev=&(tcpd->flow2);
590     } else {
591         tcpd->fwd=&(tcpd->flow2);
592         tcpd->rev=&(tcpd->flow1);
593     }
594
595     tcpd->ta=NULL;
596     return tcpd;
597 }
598
599 /* Attach process info to a flow */
600 /* XXX - We depend on the TCP dissector finding the conversation first */
601 void
602 add_tcp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, gchar *username, gchar *command) {
603     conversation_t *conv;
604     struct tcp_analysis *tcpd;
605     tcp_flow_t *flow = NULL;
606
607     conv = find_conversation(frame_num, local_addr, remote_addr, PT_TCP, local_port, remote_port, 0);
608     if (!conv) {
609         return;
610     }
611
612     tcpd = (struct tcp_analysis *)conversation_get_proto_data(conv, proto_tcp);
613     if (!tcpd) {
614         return;
615     }
616
617     if (CMP_ADDRESS(local_addr, &conv->key_ptr->addr1) == 0 && local_port == conv->key_ptr->port1) {
618         flow = &tcpd->flow1;
619     } else if (CMP_ADDRESS(remote_addr, &conv->key_ptr->addr1) == 0 && remote_port == conv->key_ptr->port1) {
620         flow = &tcpd->flow2;
621     }
622     if (!flow || flow->command) {
623         return;
624     }
625
626     flow->process_uid = uid;
627     flow->process_pid = pid;
628     flow->username = wmem_strdup(wmem_file_scope(), username);
629     flow->command = wmem_strdup(wmem_file_scope(), command);
630 }
631
632 /* Return the current stream count */
633 guint32 get_tcp_stream_count(void)
634 {
635     return tcp_stream_count;
636 }
637
638 /* Calculate the timestamps relative to this conversation */
639 static void
640 tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd,
641             struct tcp_per_packet_data_t *tcppd)
642 {
643     if( !tcppd ) {
644         tcppd = wmem_new(wmem_file_scope(), struct tcp_per_packet_data_t);
645         p_add_proto_data(wmem_file_scope(), pinfo, proto_tcp, 0, tcppd);
646     }
647
648     if (!tcpd)
649         return;
650
651     nstime_delta(&tcppd->ts_del, &pinfo->fd->abs_ts, &tcpd->ts_prev);
652
653     tcpd->ts_prev.secs=pinfo->fd->abs_ts.secs;
654     tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs;
655 }
656
657 /* Add a subtree with the timestamps relative to this conversation */
658 static void
659 tcp_print_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd, struct tcp_per_packet_data_t *tcppd)
660 {
661     proto_item  *item;
662     proto_tree  *tree;
663     nstime_t    ts;
664
665     if (!tcpd)
666         return;
667
668     item=proto_tree_add_text(parent_tree, tvb, 0, 0, "Timestamps");
669     PROTO_ITEM_SET_GENERATED(item);
670     tree=proto_item_add_subtree(item, ett_tcp_timestamps);
671
672     nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first);
673     item = proto_tree_add_time(tree, hf_tcp_ts_relative, tvb, 0, 0, &ts);
674     PROTO_ITEM_SET_GENERATED(item);
675
676     if( !tcppd )
677         tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, 0);
678
679     if( tcppd ) {
680         item = proto_tree_add_time(tree, hf_tcp_ts_delta, tvb, 0, 0,
681             &tcppd->ts_del);
682         PROTO_ITEM_SET_GENERATED(item);
683     }
684 }
685
686 static void
687 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_multisegment_pdu *msp)
688 {
689     proto_item *item;
690
691     col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", msp->first_frame);
692     item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
693         tvb, 0, 0, msp->first_frame);
694     PROTO_ITEM_SET_GENERATED(item);
695 }
696
697 /* if we know that a PDU starts inside this segment, return the adjusted
698    offset to where that PDU starts or just return offset back
699    and let TCP try to find out what it can about this segment
700 */
701 static int
702 scan_for_next_pdu(tvbuff_t *tvb, proto_tree *tcp_tree, packet_info *pinfo, int offset, guint32 seq, guint32 nxtseq, wmem_tree_t *multisegment_pdus)
703 {
704     struct tcp_multisegment_pdu *msp=NULL;
705
706     if(!pinfo->fd->flags.visited) {
707         msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(multisegment_pdus, seq-1);
708         if(msp) {
709             /* If this is a continuation of a PDU started in a
710              * previous segment we need to update the last_frame
711              * variables.
712             */
713             if(seq>msp->seq && seq<msp->nxtpdu) {
714                 msp->last_frame=pinfo->fd->num;
715                 msp->last_frame_time=pinfo->fd->abs_ts;
716                 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
717             }
718
719             /* If this segment is completely within a previous PDU
720              * then we just skip this packet
721              */
722             if(seq>msp->seq && nxtseq<=msp->nxtpdu) {
723                 return -1;
724             }
725             if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu) {
726                 offset+=msp->nxtpdu-seq;
727                 return offset;
728             }
729
730         }
731     } else {
732         /* First we try to find the start and transfer time for a PDU.
733          * We only print this for the very first segment of a PDU
734          * and only for PDUs spanning multiple segments.
735          * Se we look for if there was any multisegment PDU started
736          * just BEFORE the end of this segment. I.e. either inside this
737          * segment or in a previous segment.
738          * Since this might also match PDUs that are completely within
739          * this segment we also verify that the found PDU does span
740          * beyond the end of this segment.
741          */
742         msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(multisegment_pdus, nxtseq-1);
743         if(msp) {
744             if(pinfo->fd->num==msp->first_frame) {
745                 proto_item *item;
746                 nstime_t ns;
747
748                 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, msp->last_frame);
749                 PROTO_ITEM_SET_GENERATED(item);
750
751                 nstime_delta(&ns, &msp->last_frame_time, &pinfo->fd->abs_ts);
752                 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
753                         tvb, 0, 0, &ns);
754                 PROTO_ITEM_SET_GENERATED(item);
755             }
756         }
757
758         /* Second we check if this segment is part of a PDU started
759          * prior to the segment (seq-1)
760          */
761         msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(multisegment_pdus, seq-1);
762         if(msp) {
763             /* If this segment is completely within a previous PDU
764              * then we just skip this packet
765              */
766             if(seq>msp->seq && nxtseq<=msp->nxtpdu) {
767                 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
768                 return -1;
769             }
770
771             if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu) {
772                 offset+=msp->nxtpdu-seq;
773                 return offset;
774             }
775         }
776
777     }
778     return offset;
779 }
780
781 /* if we saw a PDU that extended beyond the end of the segment,
782    use this function to remember where the next pdu starts
783 */
784 struct tcp_multisegment_pdu *
785 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, wmem_tree_t *multisegment_pdus)
786 {
787     struct tcp_multisegment_pdu *msp;
788
789     msp=wmem_new(wmem_file_scope(), struct tcp_multisegment_pdu);
790     msp->nxtpdu=nxtpdu;
791     msp->seq=seq;
792     msp->first_frame=pinfo->fd->num;
793     msp->last_frame=pinfo->fd->num;
794     msp->last_frame_time=pinfo->fd->abs_ts;
795     msp->flags=0;
796     wmem_tree_insert32(multisegment_pdus, seq, (void *)msp);
797     return msp;
798 }
799
800 /* This is called for SYN and SYN+ACK packets and the purpose is to verify
801  * that we have seen window scaling in both directions.
802  * If we cant find window scaling being set in both directions
803  * that means it was present in the SYN but not in the SYN+ACK
804  * (or the SYN was missing) and then we disable the window scaling
805  * for this tcp session.
806  */
807 static void
808 verify_tcp_window_scaling(gboolean is_synack, struct tcp_analysis *tcpd)
809 {
810     if( tcpd->fwd->win_scale==-1 ) {
811         /* We know window scaling will not be used as:
812          * a) this is the SYN and it does not have the WS option
813          *    (we set the reverse win_scale also in case we miss
814          *    the SYN/ACK)
815          * b) this is the SYN/ACK and either the SYN packet has not
816          *    been seen or it did have the WS option. As the SYN/ACK
817          *    does not have the WS option, window scaling will not be used.
818          *
819          * Setting win_scale to -2 to indicate that we can
820          * trust the window_size value in the TCP header.
821          */
822         tcpd->fwd->win_scale = -2;
823         tcpd->rev->win_scale = -2;
824
825     } else if( is_synack && tcpd->rev->win_scale==-2 ) {
826         /* The SYN/ACK has the WS option, while the SYN did not,
827          * this should not happen, but the endpoints will not
828          * have used window scaling, so we will neither
829          */
830         tcpd->fwd->win_scale = -2;
831     }
832 }
833
834 /* if we saw a window scaling option, store it for future reference
835 */
836 static void
837 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
838 {
839     if (tcpd)
840         tcpd->fwd->win_scale=ws;
841 }
842
843 /* when this function returns, it will (if createflag) populate the ta pointer.
844  */
845 static void
846 tcp_analyze_get_acked_struct(guint32 frame, guint32 seq, guint32 ack, gboolean createflag, struct tcp_analysis *tcpd)
847 {
848     wmem_tree_key_t key[] = {{1, &frame}, {1, &seq}, {1, &ack}, {0, NULL}};
849
850     if (!tcpd) {
851         return;
852     }
853
854     tcpd->ta = (struct tcp_acked *)wmem_tree_lookup32_array(tcpd->acked_table, key);
855     if((!tcpd->ta) && createflag) {
856         tcpd->ta = wmem_new0(wmem_file_scope(), struct tcp_acked);
857         wmem_tree_insert32_array(tcpd->acked_table, key, (void *)tcpd->ta);
858     }
859 }
860
861
862 /* fwd contains a list of all segments processed but not yet ACKed in the
863  *     same direction as the current segment.
864  * rev contains a list of all segments received but not yet ACKed in the
865  *     opposite direction to the current segment.
866  *
867  * New segments are always added to the head of the fwd/rev lists.
868  *
869  */
870 static void
871 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint16 flags, guint32 window, struct tcp_analysis *tcpd)
872 {
873     tcp_unacked_t *ual=NULL;
874     tcp_unacked_t *prevual=NULL;
875     guint32 nextseq;
876     int ackcount;
877
878 #if 0
879     printf("\nanalyze_sequence numbers   frame:%u\n",pinfo->fd->num);
880     printf("FWD list lastflags:0x%04x base_seq:%u:\n",tcpd->fwd->lastsegmentflags,tcpd->fwd->base_seq);
881     for(ual=tcpd->fwd->segments; ual; ual=ual->next)
882             printf("Frame:%d Seq:%u Nextseq:%u\n",ual->frame,ual->seq,ual->nextseq);
883     printf("REV list lastflags:0x%04x base_seq:%u:\n",tcpd->rev->lastsegmentflags,tcpd->rev->base_seq);
884     for(ual=tcpd->rev->segments; ual; ual=ual->next)
885             printf("Frame:%d Seq:%u Nextseq:%u\n",ual->frame,ual->seq,ual->nextseq);
886 #endif
887
888     if (!tcpd) {
889         return;
890     }
891
892     /* if this is the first segment for this list we need to store the
893      * base_seq
894      *
895      * Start relative seq and ack numbers at 1 if this
896      * is not a SYN packet. This makes the relative
897      * seq/ack numbers to be displayed correctly in the
898      * event that the SYN or SYN/ACK packet is not seen
899      * (this solves bug 1542)
900      */
901     if(tcpd->fwd->base_seq==0) {
902         tcpd->fwd->base_seq = (flags & TH_SYN) ? seq : seq-1;
903     }
904
905     /* Only store reverse sequence if this isn't the SYN
906      * There's no guarantee that the ACK field of a SYN
907      * contains zeros; get the ISN from the first segment
908      * with the ACK bit set instead (usually the SYN/ACK).
909      *
910      * If the SYN and SYN/ACK were received out-of-order,
911      * the ISN is ack-1. If we missed the SYN/ACK, but got
912      * the last ACK of the 3WHS, the ISN is ack-1. For all
913      * other packets the ISN is unknown, so ack-1 is
914      * as good a guess as ack.
915      */
916     if( (tcpd->rev->base_seq==0) && (flags & TH_ACK) ) {
917         tcpd->rev->base_seq = ack-1;
918     }
919
920     if( flags & TH_ACK ) {
921         tcpd->rev->valid_bif = 1;
922     }
923
924     /* ZERO WINDOW PROBE
925      * it is a zero window probe if
926      *  the sequence number is the next expected one
927      *  the window in the other direction is 0
928      *  the segment is exactly 1 byte
929      */
930 /*QQQ tested*/
931     if( seglen==1
932     &&  seq==tcpd->fwd->nextseq
933     &&  tcpd->rev->window==0 ) {
934         if(!tcpd->ta) {
935             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
936         }
937         tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
938         goto finished_fwd;
939     }
940
941
942     /* ZERO WINDOW
943      * a zero window packet has window == 0   but none of the SYN/FIN/RST set
944      */
945 /*QQQ tested*/
946     if( window==0
947     && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ) {
948         if(!tcpd->ta) {
949             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
950         }
951         tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
952     }
953
954
955     /* LOST PACKET
956      * If this segment is beyond the last seen nextseq we must
957      * have missed some previous segment
958      *
959      * We only check for this if we have actually seen segments prior to this
960      * one.
961      * RST packets are not checked for this.
962      */
963     if( tcpd->fwd->nextseq
964     &&  GT_SEQ(seq, tcpd->fwd->nextseq)
965     &&  (flags&(TH_RST))==0 ) {
966         if(!tcpd->ta) {
967             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
968         }
969         tcpd->ta->flags|=TCP_A_LOST_PACKET;
970
971         /* Disable BiF until an ACK is seen in the other direction */
972         tcpd->fwd->valid_bif = 0;
973     }
974
975
976     /* KEEP ALIVE
977      * a keepalive contains 0 or 1 bytes of data and starts one byte prior
978      * to what should be the next sequence number.
979      * SYN/FIN/RST segments are never keepalives
980      */
981 /*QQQ tested */
982     if( (seglen==0||seglen==1)
983     &&  seq==(tcpd->fwd->nextseq-1)
984     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
985         if(!tcpd->ta) {
986             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
987         }
988         tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
989     }
990
991     /* WINDOW UPDATE
992      * A window update is a 0 byte segment with the same SEQ/ACK numbers as
993      * the previous seen segment and with a new window value
994      */
995     if( seglen==0
996     &&  window
997     &&  window!=tcpd->fwd->window
998     &&  seq==tcpd->fwd->nextseq
999     &&  ack==tcpd->fwd->lastack
1000     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
1001         if(!tcpd->ta) {
1002             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1003         }
1004         tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
1005     }
1006
1007
1008     /* WINDOW FULL
1009      * If we know the window scaling
1010      * and if this segment contains data and goes all the way to the
1011      * edge of the advertised window
1012      * then we mark it as WINDOW FULL
1013      * SYN/RST/FIN packets are never WINDOW FULL
1014      */
1015 /*QQQ tested*/
1016     if( seglen>0
1017     &&  tcpd->rev->win_scale!=-1
1018     &&  (seq+seglen)==(tcpd->rev->lastack+(tcpd->rev->window<<(tcpd->rev->win_scale==-2?0:tcpd->rev->win_scale)))
1019     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
1020         if(!tcpd->ta) {
1021             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1022         }
1023         tcpd->ta->flags|=TCP_A_WINDOW_FULL;
1024     }
1025
1026
1027     /* KEEP ALIVE ACK
1028      * It is a keepalive ack if it repeats the previous ACK and if
1029      * the last segment in the reverse direction was a keepalive
1030      */
1031 /*QQQ tested*/
1032     if( seglen==0
1033     &&  window
1034     &&  window==tcpd->fwd->window
1035     &&  seq==tcpd->fwd->nextseq
1036     &&  ack==tcpd->fwd->lastack
1037     && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
1038     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
1039         if(!tcpd->ta) {
1040             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1041         }
1042         tcpd->ta->flags|=TCP_A_KEEP_ALIVE_ACK;
1043         goto finished_fwd;
1044     }
1045
1046
1047     /* ZERO WINDOW PROBE ACK
1048      * It is a zerowindowprobe ack if it repeats the previous ACK and if
1049      * the last segment in the reverse direction was a zerowindowprobe
1050      * It also repeats the previous zero window indication
1051      */
1052 /*QQQ tested*/
1053     if( seglen==0
1054     &&  window==0
1055     &&  window==tcpd->fwd->window
1056     &&  seq==tcpd->fwd->nextseq
1057     &&  ack==tcpd->fwd->lastack
1058     && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
1059     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
1060         if(!tcpd->ta) {
1061             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1062         }
1063         tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
1064         goto finished_fwd;
1065     }
1066
1067
1068     /* DUPLICATE ACK
1069      * It is a duplicate ack if window/seq/ack is the same as the previous
1070      * segment and if the segment length is 0
1071      */
1072     if( seglen==0
1073     &&  window
1074     &&  window==tcpd->fwd->window
1075     &&  seq==tcpd->fwd->nextseq
1076     &&  ack==tcpd->fwd->lastack
1077     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
1078         tcpd->fwd->dupacknum++;
1079         if(!tcpd->ta) {
1080             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1081         }
1082         tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
1083         tcpd->ta->dupack_num=tcpd->fwd->dupacknum;
1084         tcpd->ta->dupack_frame=tcpd->fwd->lastnondupack;
1085     }
1086
1087
1088
1089 finished_fwd:
1090     /* If this was NOT a dupack we must reset the dupack counters */
1091     if( (!tcpd->ta) || !(tcpd->ta->flags&TCP_A_DUPLICATE_ACK) ) {
1092         tcpd->fwd->lastnondupack=pinfo->fd->num;
1093         tcpd->fwd->dupacknum=0;
1094     }
1095
1096
1097     /* ACKED LOST PACKET
1098      * If this segment acks beyond the 'max seq to be acked' in the other direction
1099      * then that means we have missed packets going in the
1100      * other direction
1101      *
1102      * We only check this if we have actually seen some seq numbers
1103      * in the other direction.
1104      */
1105     if( tcpd->rev->maxseqtobeacked
1106     &&  GT_SEQ(ack, tcpd->rev->maxseqtobeacked )
1107     &&  (flags&(TH_ACK))!=0 ) {
1108 /*QQQ tested*/
1109         if(!tcpd->ta) {
1110             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1111         }
1112         tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
1113         /* update 'max seq to be acked' in the other direction so we don't get
1114          * this indication again.
1115          */
1116         tcpd->rev->maxseqtobeacked=tcpd->rev->nextseq;
1117     }
1118
1119
1120     /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
1121      * If the segment contains data (or is a SYN or a FIN) and
1122      * if it does not advance the sequence number, it must be one
1123      * of these three.
1124      * Only test for this if we know what the seq number should be
1125      * (tcpd->fwd->nextseq)
1126      *
1127      * Note that a simple KeepAlive is not a retransmission
1128      */
1129     if( (seglen>0 || flags&(TH_SYN|TH_FIN))
1130     &&  tcpd->fwd->nextseq
1131     &&  (LT_SEQ(seq, tcpd->fwd->nextseq)) ) {
1132         guint64 t;
1133
1134         if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ) {
1135             goto finished_checking_retransmission_type;
1136         }
1137
1138         /* If there were >=2 duplicate ACKs in the reverse direction
1139          * (there might be duplicate acks missing from the trace)
1140          * and if this sequence number matches those ACKs
1141          * and if the packet occurs within 20ms of the last
1142          * duplicate ack
1143          * then this is a fast retransmission
1144          */
1145         t=(pinfo->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
1146         t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;
1147         if( tcpd->rev->dupacknum>=2
1148         &&  tcpd->rev->lastack==seq
1149         &&  t<20000000 ) {
1150             if(!tcpd->ta) {
1151                 tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1152             }
1153             tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
1154             goto finished_checking_retransmission_type;
1155         }
1156
1157         /* If the segment came <3ms since the segment with the highest
1158          * seen sequence number and it doesn't look like a retransmission
1159          * then it is an OUT-OF-ORDER segment.
1160          *   (3ms is an arbitrary number)
1161          */
1162         t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
1163         t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
1164         if( t<3000000
1165         && tcpd->fwd->nextseq != seq + seglen ) {
1166             if(!tcpd->ta) {
1167                 tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1168             }
1169             tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
1170             goto finished_checking_retransmission_type;
1171         }
1172
1173         /* Check for spurious retransmission. If the current seq + segment length
1174          * is less then the receivers lastask, the packet contains duplicated
1175          * data and may be considered spurious.
1176          */
1177         if ( seq + seglen < tcpd->rev->lastack ) {
1178             if(!tcpd->ta){
1179                 tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1180             }
1181             tcpd->ta->flags|=TCP_A_SPURIOUS_RETRANSMISSION;
1182             goto finished_checking_retransmission_type;
1183         }
1184
1185         /* Then it has to be a generic retransmission */
1186         if(!tcpd->ta) {
1187             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1188         }
1189         tcpd->ta->flags|=TCP_A_RETRANSMISSION;
1190         nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
1191         tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
1192     }
1193
1194 finished_checking_retransmission_type:
1195
1196     nextseq = seq+seglen;
1197     if (seglen || flags&(TH_SYN|TH_FIN)) {
1198         /* add this new sequence number to the fwd list */
1199         ual = wmem_new(wmem_file_scope(), tcp_unacked_t);
1200         ual->next=tcpd->fwd->segments;
1201         tcpd->fwd->segments=ual;
1202         ual->frame=pinfo->fd->num;
1203         ual->seq=seq;
1204         ual->ts=pinfo->fd->abs_ts;
1205
1206         /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
1207         if( (flags&(TH_SYN|TH_FIN)) ) {
1208             nextseq+=1;
1209         }
1210         ual->nextseq=nextseq;
1211     }
1212
1213     /* Store the highest number seen so far for nextseq so we can detect
1214      * when we receive segments that arrive with a "hole"
1215      * If we don't have anything since before, just store what we got.
1216      * ZeroWindowProbes are special and don't really advance the nextseq
1217      */
1218     if(GT_SEQ(nextseq, tcpd->fwd->nextseq) || !tcpd->fwd->nextseq) {
1219         if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ) {
1220             tcpd->fwd->nextseq=nextseq;
1221             tcpd->fwd->nextseqframe=pinfo->fd->num;
1222             tcpd->fwd->nextseqtime.secs=pinfo->fd->abs_ts.secs;
1223             tcpd->fwd->nextseqtime.nsecs=pinfo->fd->abs_ts.nsecs;
1224         }
1225     }
1226
1227     /* Store the highest continuous seq number seen so far for 'max seq to be acked',
1228      so we can detect TCP_A_ACK_LOST_PACKET condition
1229      */
1230     if(EQ_SEQ(seq, tcpd->fwd->maxseqtobeacked) || !tcpd->fwd->maxseqtobeacked) {
1231         if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ) {
1232             tcpd->fwd->maxseqtobeacked=tcpd->fwd->nextseq;
1233         }
1234     }
1235
1236
1237     /* remember what the ack/window is so we can track window updates and retransmissions */
1238     tcpd->fwd->window=window;
1239     tcpd->fwd->lastack=ack;
1240     tcpd->fwd->lastacktime.secs=pinfo->fd->abs_ts.secs;
1241     tcpd->fwd->lastacktime.nsecs=pinfo->fd->abs_ts.nsecs;
1242
1243
1244     /* if there were any flags set for this segment we need to remember them
1245      * we only remember the flags for the very last segment though.
1246      */
1247     if(tcpd->ta) {
1248         tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
1249     } else {
1250         tcpd->fwd->lastsegmentflags=0;
1251     }
1252
1253
1254     /* remove all segments this ACKs and we don't need to keep around any more
1255      */
1256     ackcount=0;
1257     prevual = NULL;
1258     ual = tcpd->rev->segments;
1259     while(ual) {
1260         tcp_unacked_t *tmpual;
1261
1262         /* If this ack matches the segment, process accordingly */
1263         if(ack==ual->nextseq) {
1264             tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1265             tcpd->ta->frame_acked=ual->frame;
1266             nstime_delta(&tcpd->ta->ts, &pinfo->fd->abs_ts, &ual->ts);
1267         }
1268         /* If this acknowledges part of the segment, adjust the segment info for the acked part */
1269         else if (GT_SEQ(ack, ual->seq) && LE_SEQ(ack, ual->nextseq)) {
1270             ual->seq = ack;
1271             continue;
1272         }
1273         /* If this acknowledges a segment prior to this one, leave this segment alone and move on */
1274         else if (GT_SEQ(ual->nextseq,ack)) {
1275             prevual = ual;
1276             ual = ual->next;
1277             continue;
1278         }
1279
1280         /* This segment is old, or an exact match.  Delete the segment from the list */
1281         ackcount++;
1282         tmpual=ual->next;
1283
1284         if (tcpd->rev->scps_capable) {
1285           /* Track largest segment successfully sent for SNACK analysis*/
1286           if ((ual->nextseq - ual->seq) > tcpd->fwd->maxsizeacked) {
1287             tcpd->fwd->maxsizeacked = (ual->nextseq - ual->seq);
1288           }
1289         }
1290
1291         if (!prevual) {
1292             tcpd->rev->segments = tmpual;
1293         }
1294         else{
1295             prevual->next = tmpual;
1296         }
1297         wmem_free(wmem_file_scope(), ual);
1298         ual = tmpual;
1299     }
1300
1301     /* how many bytes of data are there in flight after this frame
1302      * was sent
1303      */
1304     ual=tcpd->fwd->segments;
1305     if (tcp_track_bytes_in_flight && seglen!=0 && ual && tcpd->fwd->valid_bif) {
1306         guint32 first_seq, last_seq, in_flight;
1307
1308         first_seq = ual->seq - tcpd->fwd->base_seq;
1309         last_seq = ual->nextseq - tcpd->fwd->base_seq;
1310         while (ual) {
1311             if ((ual->nextseq-tcpd->fwd->base_seq)>last_seq) {
1312                 last_seq = ual->nextseq-tcpd->fwd->base_seq;
1313             }
1314             if ((ual->seq-tcpd->fwd->base_seq)<first_seq) {
1315                 first_seq = ual->seq-tcpd->fwd->base_seq;
1316             }
1317             ual = ual->next;
1318         }
1319         in_flight = last_seq-first_seq;
1320
1321         if (in_flight>0 && in_flight<2000000000) {
1322             if(!tcpd->ta) {
1323                 tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
1324             }
1325             tcpd->ta->bytes_in_flight = in_flight;
1326         }
1327     }
1328
1329 }
1330
1331 /*
1332  * Prints results of the sequence number analysis concerning tcp segments
1333  * retransmitted or out-of-order
1334  */
1335 static void
1336 tcp_sequence_number_analysis_print_retransmission(packet_info * pinfo,
1337                           tvbuff_t * tvb,
1338                           proto_tree * flags_tree, proto_item * flags_item,
1339                           struct tcp_acked *ta
1340                           )
1341 {
1342     /* TCP Retransmission */
1343     if (ta->flags & TCP_A_RETRANSMISSION) {
1344         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_retransmission);
1345
1346         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
1347
1348         if (ta->rto_ts.secs || ta->rto_ts.nsecs) {
1349             flags_item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
1350                                              tvb, 0, 0, &ta->rto_ts);
1351             PROTO_ITEM_SET_GENERATED(flags_item);
1352             flags_item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame,
1353                                            tvb, 0, 0, ta->rto_frame);
1354             PROTO_ITEM_SET_GENERATED(flags_item);
1355         }
1356     }
1357     /* TCP Fast Retransmission */
1358     if (ta->flags & TCP_A_FAST_RETRANSMISSION) {
1359         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_fast_retransmission);
1360         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_retransmission);
1361         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1362                                "[TCP Fast Retransmission] ");
1363     }
1364     /* TCP Spurious Retransmission */
1365     if (ta->flags & TCP_A_SPURIOUS_RETRANSMISSION) {
1366         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_spurious_retransmission);
1367         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_retransmission);
1368         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1369                                "[TCP Spurious Retransmission] ");
1370     }
1371
1372     /* TCP Out-Of-Order */
1373     if (ta->flags & TCP_A_OUT_OF_ORDER) {
1374         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_out_of_order);
1375         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
1376     }
1377 }
1378
1379 /* Prints results of the sequence number analysis concerning reused ports */
1380 static void
1381 tcp_sequence_number_analysis_print_reused(packet_info * pinfo,
1382                       proto_item * flags_item,
1383                       struct tcp_acked *ta
1384                       )
1385 {
1386     /* TCP Ports Reused */
1387     if (ta->flags & TCP_A_REUSED_PORTS) {
1388         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_reused_ports);
1389         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1390                                "[TCP Port numbers reused] ");
1391     }
1392 }
1393
1394 /* Prints results of the sequence number analysis concerning lost tcp segments */
1395 static void
1396 tcp_sequence_number_analysis_print_lost(packet_info * pinfo,
1397                     proto_item * flags_item,
1398                     struct tcp_acked *ta
1399                     )
1400 {
1401     /* TCP Lost Segment */
1402     if (ta->flags & TCP_A_LOST_PACKET) {
1403         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_lost_packet);
1404         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1405                                "[TCP Previous segment not captured] ");
1406     }
1407     /* TCP Ack lost segment */
1408     if (ta->flags & TCP_A_ACK_LOST_PACKET) {
1409         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_ack_lost_packet);
1410         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1411                                "[TCP ACKed unseen segment] ");
1412     }
1413 }
1414
1415 /* Prints results of the sequence number analysis concerning tcp window */
1416 static void
1417 tcp_sequence_number_analysis_print_window(packet_info * pinfo,
1418                       proto_item * flags_item,
1419                       struct tcp_acked *ta
1420                       )
1421 {
1422     /* TCP Window Update */
1423     if (ta->flags & TCP_A_WINDOW_UPDATE) {
1424         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_window_update);
1425         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
1426     }
1427     /* TCP Full Window */
1428     if (ta->flags & TCP_A_WINDOW_FULL) {
1429         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_window_full);
1430         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
1431     }
1432 }
1433
1434 /* Prints results of the sequence number analysis concerning tcp keepalive */
1435 static void
1436 tcp_sequence_number_analysis_print_keepalive(packet_info * pinfo,
1437                       proto_item * flags_item,
1438                       struct tcp_acked *ta
1439                       )
1440 {
1441     /*TCP Keep Alive */
1442     if (ta->flags & TCP_A_KEEP_ALIVE) {
1443         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_keep_alive);
1444         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
1445     }
1446     /* TCP Ack Keep Alive */
1447     if (ta->flags & TCP_A_KEEP_ALIVE_ACK) {
1448         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_keep_alive_ack);
1449         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
1450     }
1451 }
1452
1453 /* Prints results of the sequence number analysis concerning tcp duplicate ack */
1454 static void
1455 tcp_sequence_number_analysis_print_duplicate(packet_info * pinfo,
1456                           tvbuff_t * tvb,
1457                           proto_tree * flags_tree,
1458                           struct tcp_acked *ta,
1459                           proto_tree * tree
1460                         )
1461 {
1462     proto_item * flags_item;
1463
1464     /* TCP Duplicate ACK */
1465     if (ta->dupack_num) {
1466         if (ta->flags & TCP_A_DUPLICATE_ACK ) {
1467             flags_item=proto_tree_add_none_format(flags_tree,
1468                                                   hf_tcp_analysis_duplicate_ack,
1469                                                   tvb, 0, 0,
1470                                                   "This is a TCP duplicate ack"
1471                 );
1472             PROTO_ITEM_SET_GENERATED(flags_item);
1473             col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1474                                    "[TCP Dup ACK %u#%u] ",
1475                                    ta->dupack_frame,
1476                                    ta->dupack_num
1477                 );
1478
1479         }
1480         flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
1481                                        tvb, 0, 0, ta->dupack_num);
1482         PROTO_ITEM_SET_GENERATED(flags_item);
1483         flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
1484                                        tvb, 0, 0, ta->dupack_frame);
1485         PROTO_ITEM_SET_GENERATED(flags_item);
1486         expert_add_info_format(pinfo, flags_item, &ei_tcp_analysis_duplicate_ack, "Duplicate ACK (#%u)", ta->dupack_num);
1487     }
1488 }
1489
1490 /* Prints results of the sequence number analysis concerning tcp zero window */
1491 static void
1492 tcp_sequence_number_analysis_print_zero_window(packet_info * pinfo,
1493                           proto_item * flags_item,
1494                           struct tcp_acked *ta
1495                         )
1496 {
1497     /* TCP Zero Window Probe */
1498     if (ta->flags & TCP_A_ZERO_WINDOW_PROBE) {
1499         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_zero_window_probe);
1500         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
1501     }
1502     /* TCP Zero Window */
1503     if (ta->flags&TCP_A_ZERO_WINDOW) {
1504         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_zero_window);
1505         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
1506     }
1507     /* TCP Zero Window Probe Ack */
1508     if (ta->flags & TCP_A_ZERO_WINDOW_PROBE_ACK) {
1509         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_zero_window_probe_ack);
1510         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
1511                                "[TCP ZeroWindowProbeAck] ");
1512     }
1513 }
1514
1515
1516 /* Prints results of the sequence number analysis concerning how many bytes of data are in flight */
1517 static void
1518 tcp_sequence_number_analysis_print_bytes_in_flight(packet_info * pinfo _U_,
1519                           tvbuff_t * tvb _U_,
1520                           proto_tree * flags_tree _U_,
1521                           struct tcp_acked *ta
1522                         )
1523 {
1524     proto_item * flags_item;
1525
1526     if (tcp_track_bytes_in_flight) {
1527         flags_item=proto_tree_add_uint(flags_tree,
1528                                        hf_tcp_analysis_bytes_in_flight,
1529                                        tvb, 0, 0, ta->bytes_in_flight);
1530
1531         PROTO_ITEM_SET_GENERATED(flags_item);
1532     }
1533 }
1534
1535 static void
1536 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree,
1537                           struct tcp_analysis *tcpd, guint32 seq, guint32 ack)
1538 {
1539     struct tcp_acked *ta = NULL;
1540     proto_item *item;
1541     proto_tree *tree;
1542     proto_tree *flags_tree=NULL;
1543
1544     if (!tcpd) {
1545         return;
1546     }
1547     if(!tcpd->ta) {
1548         tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, FALSE, tcpd);
1549     }
1550     ta=tcpd->ta;
1551     if(!ta) {
1552         return;
1553     }
1554
1555     item=proto_tree_add_item(parent_tree, hf_tcp_analysis, tvb, 0, 0, ENC_NA);
1556     PROTO_ITEM_SET_GENERATED(item);
1557     tree=proto_item_add_subtree(item, ett_tcp_analysis);
1558
1559     /* encapsulate all proto_tree_add_xxx in ifs so we only print what
1560        data we actually have */
1561     if(ta->frame_acked) {
1562         item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
1563             tvb, 0, 0, ta->frame_acked);
1564             PROTO_ITEM_SET_GENERATED(item);
1565
1566         /* only display RTT if we actually have something we are acking */
1567         if( ta->ts.secs || ta->ts.nsecs ) {
1568             item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
1569             tvb, 0, 0, &ta->ts);
1570                 PROTO_ITEM_SET_GENERATED(item);
1571         }
1572     }
1573
1574     if(ta->bytes_in_flight) {
1575         /* print results for amount of data in flight */
1576         tcp_sequence_number_analysis_print_bytes_in_flight(pinfo, tvb, tree, ta);
1577     }
1578
1579     if(ta->flags) {
1580         item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, 0, ENC_NA);
1581         PROTO_ITEM_SET_GENERATED(item);
1582         flags_tree=proto_item_add_subtree(item, ett_tcp_analysis);
1583
1584         /* print results for reused tcp ports */
1585         tcp_sequence_number_analysis_print_reused(pinfo, item, ta);
1586
1587         /* print results for retransmission and out-of-order segments */
1588         tcp_sequence_number_analysis_print_retransmission(pinfo, tvb, flags_tree, item, ta);
1589
1590         /* print results for lost tcp segments */
1591         tcp_sequence_number_analysis_print_lost(pinfo, item, ta);
1592
1593         /* print results for tcp window information */
1594         tcp_sequence_number_analysis_print_window(pinfo, item, ta);
1595
1596         /* print results for tcp keep alive information */
1597         tcp_sequence_number_analysis_print_keepalive(pinfo, item, ta);
1598
1599         /* print results for tcp duplicate acks */
1600         tcp_sequence_number_analysis_print_duplicate(pinfo, tvb, flags_tree, ta, tree);
1601
1602         /* print results for tcp zero window  */
1603         tcp_sequence_number_analysis_print_zero_window(pinfo, item, ta);
1604
1605     }
1606
1607 }
1608
1609 static void
1610 print_tcp_fragment_tree(fragment_head *ipfd_head, proto_tree *tree, proto_tree *tcp_tree, packet_info *pinfo, tvbuff_t *next_tvb)
1611 {
1612     proto_item *tcp_tree_item, *frag_tree_item;
1613
1614     /*
1615      * The subdissector thought it was completely
1616      * desegmented (although the stuff at the
1617      * end may, in turn, require desegmentation),
1618      * so we show a tree with all segments.
1619      */
1620     show_fragment_tree(ipfd_head, &tcp_segment_items,
1621         tree, pinfo, next_tvb, &frag_tree_item);
1622     /*
1623      * The toplevel fragment subtree is now
1624      * behind all desegmented data; move it
1625      * right behind the TCP tree.
1626      */
1627     tcp_tree_item = proto_tree_get_parent(tcp_tree);
1628     if(frag_tree_item && tcp_tree_item) {
1629         proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
1630     }
1631 }
1632
1633 /* **************************************************************************
1634  * End of tcp sequence number analysis
1635  * **************************************************************************/
1636
1637
1638 /* Minimum TCP header length. */
1639 #define TCPH_MIN_LEN            20
1640
1641 /* Desegmentation of TCP streams */
1642 static reassembly_table tcp_reassembly_table;
1643
1644 /* functions to trace tcp segments */
1645 /* Enable desegmenting of TCP streams */
1646 static gboolean tcp_desegment = TRUE;
1647
1648 static void
1649 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
1650               guint32 seq, guint32 nxtseq,
1651               guint32 sport, guint32 dport,
1652               proto_tree *tree, proto_tree *tcp_tree,
1653               struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
1654 {
1655     fragment_head *ipfd_head;
1656     int last_fragment_len;
1657     gboolean must_desegment;
1658     gboolean called_dissector;
1659     int another_pdu_follows;
1660     int deseg_offset;
1661     guint32 deseg_seq;
1662     gint nbytes;
1663     proto_item *item;
1664     struct tcp_multisegment_pdu *msp;
1665     gboolean cleared_writable = col_get_writable(pinfo->cinfo);
1666
1667 again:
1668     ipfd_head = NULL;
1669     last_fragment_len = 0;
1670     must_desegment = FALSE;
1671     called_dissector = FALSE;
1672     another_pdu_follows = 0;
1673     msp = NULL;
1674
1675     /*
1676      * Initialize these to assume no desegmentation.
1677      * If that's not the case, these will be set appropriately
1678      * by the subdissector.
1679      */
1680     pinfo->desegment_offset = 0;
1681     pinfo->desegment_len = 0;
1682
1683     /*
1684      * Initialize this to assume that this segment will just be
1685      * added to the middle of a desegmented chunk of data, so
1686      * that we should show it all as data.
1687      * If that's not the case, it will be set appropriately.
1688      */
1689     deseg_offset = offset;
1690
1691     if (tcpd) {
1692         /* Have we seen this PDU before (and is it the start of a multi-
1693          * segment PDU)?
1694          */
1695         if ((msp = (struct tcp_multisegment_pdu *)wmem_tree_lookup32(tcpd->fwd->multisegment_pdus, seq))) {
1696             const char* str;
1697
1698             /* Yes.  This could be because we've dissected this frame before
1699              * or because this is a retransmission of a previously-seen
1700              * segment.  Either way, we don't need to hand it off to the
1701              * subdissector and we certainly don't want to re-add it to the
1702              * multisegment_pdus list: if we did, subsequent lookups would
1703              * find this retransmission instead of the original transmission
1704              * (breaking desegmentation if we'd already linked other segments
1705              * to the original transmission's entry).
1706              */
1707
1708             if (msp->first_frame == PINFO_FD_NUM(pinfo)) {
1709                 str = "";
1710                 col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
1711             } else {
1712                 str = "Retransmitted ";
1713                 /* TCP analysis already flags this (in COL_INFO) as a retransmission--if it's enabled */
1714             }
1715
1716             nbytes = MAX(0, tvb_reported_length_remaining(tvb, offset));
1717             proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, offset,
1718                 nbytes, NULL, "%sTCP segment data (%u byte%s)", str, nbytes,
1719                 plurality(nbytes, "", "s"));
1720             return;
1721         }
1722
1723         /* Else, find the most previous PDU starting before this sequence number */
1724         msp = (struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
1725     }
1726
1727     if (msp && msp->seq <= seq && msp->nxtpdu > seq) {
1728         int len;
1729
1730         if (!PINFO_FD_VISITED(pinfo)) {
1731             msp->last_frame=pinfo->fd->num;
1732             msp->last_frame_time=pinfo->fd->abs_ts;
1733         }
1734
1735         /* OK, this PDU was found, which means the segment continues
1736          * a higher-level PDU and that we must desegment it.
1737          */
1738         if (msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
1739             /* The dissector asked for the entire segment */
1740             len = MAX(0, tvb_length_remaining(tvb, offset));
1741         } else {
1742             len = MIN(nxtseq, msp->nxtpdu) - seq;
1743         }
1744         last_fragment_len = len;
1745
1746         ipfd_head = fragment_add(&tcp_reassembly_table, tvb, offset,
1747                                  pinfo, msp->first_frame, NULL,
1748                                  seq - msp->seq, len,
1749                                  (LT_SEQ (nxtseq,msp->nxtpdu)) );
1750
1751         if (!PINFO_FD_VISITED(pinfo)
1752         && msp->flags & MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
1753             msp->flags &= (~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT);
1754
1755             /* If we consumed the entire segment there is no
1756              * other pdu starting anywhere inside this segment.
1757              * So update nxtpdu to point at least to the start
1758              * of the next segment.
1759              * (If the subdissector asks for even more data we
1760              * will advance nxtpdu even further later down in
1761              * the code.)
1762              */
1763             msp->nxtpdu = nxtseq;
1764         }
1765
1766         if( (msp->nxtpdu < nxtseq)
1767         &&  (msp->nxtpdu >= seq)
1768         &&  (len > 0)) {
1769             another_pdu_follows=msp->nxtpdu - seq;
1770         }
1771     } else {
1772         /* This segment was not found in our table, so it doesn't
1773          * contain a continuation of a higher-level PDU.
1774          * Call the normal subdissector.
1775          */
1776
1777         /*
1778          * Supply the sequence number of this segment. We set this here
1779          * because this segment could be after another in the same packet,
1780          * in which case seq was incremented at the end of the loop.
1781          */
1782         tcpinfo->seq = seq;
1783
1784         process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
1785                             sport, dport, 0, 0, FALSE, tcpd, tcpinfo);
1786         called_dissector = TRUE;
1787
1788         /* Did the subdissector ask us to desegment some more data
1789          * before it could handle the packet?
1790          * If so we have to create some structures in our table but
1791          * this is something we only do the first time we see this
1792          * packet.
1793          */
1794         if(pinfo->desegment_len) {
1795             if (!PINFO_FD_VISITED(pinfo))
1796                 must_desegment = TRUE;
1797
1798             /*
1799              * Set "deseg_offset" to the offset in "tvb"
1800              * of the first byte of data that the
1801              * subdissector didn't process.
1802              */
1803             deseg_offset = offset + pinfo->desegment_offset;
1804         }
1805
1806         /* Either no desegmentation is necessary, or this is
1807          * segment contains the beginning but not the end of
1808          * a higher-level PDU and thus isn't completely
1809          * desegmented.
1810          */
1811         ipfd_head = NULL;
1812     }
1813
1814
1815     /* is it completely desegmented? */
1816     if (ipfd_head) {
1817         /*
1818          * Yes, we think it is.
1819          * We only call subdissector for the last segment.
1820          * Note that the last segment may include more than what
1821          * we needed.
1822          */
1823         if(ipfd_head->reassembled_in == pinfo->fd->num) {
1824             /*
1825              * OK, this is the last segment.
1826              * Let's call the subdissector with the desegmented
1827              * data.
1828              */
1829             tvbuff_t *next_tvb;
1830             int old_len;
1831
1832             /* create a new TVB structure for desegmented data */
1833             next_tvb = tvb_new_chain(tvb, ipfd_head->tvb_data);
1834
1835             /* add desegmented data to the data source list */
1836             add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
1837
1838             /*
1839              * Supply the sequence number of the first of the
1840              * reassembled bytes.
1841              */
1842             tcpinfo->seq = msp->seq;
1843
1844             /* indicate that this is reassembled data */
1845             tcpinfo->is_reassembled = TRUE;
1846
1847             /* call subdissector */
1848             process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, sport,
1849                                 dport, 0, 0, FALSE, tcpd, tcpinfo);
1850             called_dissector = TRUE;
1851
1852             /*
1853              * OK, did the subdissector think it was completely
1854              * desegmented, or does it think we need even more
1855              * data?
1856              */
1857             old_len = (int)(tvb_reported_length(next_tvb) - last_fragment_len);
1858             if (pinfo->desegment_len &&
1859                 pinfo->desegment_offset<=old_len) {
1860                 /*
1861                  * "desegment_len" isn't 0, so it needs more
1862                  * data for something - and "desegment_offset"
1863                  * is before "old_len", so it needs more data
1864                  * to dissect the stuff we thought was
1865                  * completely desegmented (as opposed to the
1866                  * stuff at the beginning being completely
1867                  * desegmented, but the stuff at the end
1868                  * being a new higher-level PDU that also
1869                  * needs desegmentation).
1870                  */
1871                 fragment_set_partial_reassembly(&tcp_reassembly_table,
1872                                                 pinfo, msp->first_frame, NULL);
1873
1874                 /* Update msp->nxtpdu to point to the new next
1875                  * pdu boundary.
1876                  */
1877                 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
1878                     /* We want reassembly of at least one
1879                      * more segment so set the nxtpdu
1880                      * boundary to one byte into the next
1881                      * segment.
1882                      * This means that the next segment
1883                      * will complete reassembly even if it
1884                      * is only one single byte in length.
1885                      */
1886                     msp->nxtpdu = seq + MAX(0, tvb_reported_length_remaining(tvb, offset)) + 1;
1887                     msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1888                 } else if (pinfo->desegment_len == DESEGMENT_UNTIL_FIN) {
1889                     tcpd->fwd->flags |= TCP_FLOW_REASSEMBLE_UNTIL_FIN;
1890                 } else {
1891                     msp->nxtpdu=seq + last_fragment_len + pinfo->desegment_len;
1892                 }
1893
1894                 /* Since we need at least some more data
1895                  * there can be no pdu following in the
1896                  * tail of this segment.
1897                  */
1898                 another_pdu_follows = 0;
1899                 offset += last_fragment_len;
1900                 seq += last_fragment_len;
1901                 if (tvb_length_remaining(tvb, offset) > 0)
1902                     goto again;
1903             } else {
1904                 /*
1905                  * Show the stuff in this TCP segment as
1906                  * just raw TCP segment data.
1907                  */
1908                 nbytes = another_pdu_follows > 0
1909                     ? another_pdu_follows
1910                     : MAX(0, tvb_reported_length_remaining(tvb, offset));
1911                 proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, offset,
1912                     nbytes, NULL, "TCP segment data (%u byte%s)", nbytes,
1913                     plurality(nbytes, "", "s"));
1914
1915                 print_tcp_fragment_tree(ipfd_head, tree, tcp_tree, pinfo, next_tvb);
1916
1917                 /* Did the subdissector ask us to desegment
1918                  * some more data?  This means that the data
1919                  * at the beginning of this segment completed
1920                  * a higher-level PDU, but the data at the
1921                  * end of this segment started a higher-level
1922                  * PDU but didn't complete it.
1923                  *
1924                  * If so, we have to create some structures
1925                  * in our table, but this is something we
1926                  * only do the first time we see this packet.
1927                  */
1928                 if(pinfo->desegment_len) {
1929                     if (!PINFO_FD_VISITED(pinfo))
1930                         must_desegment = TRUE;
1931
1932                     /* The stuff we couldn't dissect
1933                      * must have come from this segment,
1934                      * so it's all in "tvb".
1935                      *
1936                      * "pinfo->desegment_offset" is
1937                      * relative to the beginning of
1938                      * "next_tvb"; we want an offset
1939                      * relative to the beginning of "tvb".
1940                      *
1941                      * First, compute the offset relative
1942                      * to the *end* of "next_tvb" - i.e.,
1943                      * the number of bytes before the end
1944                      * of "next_tvb" at which the
1945                      * subdissector stopped.  That's the
1946                      * length of "next_tvb" minus the
1947                      * offset, relative to the beginning
1948                      * of "next_tvb, at which the
1949                      * subdissector stopped.
1950                      */
1951                     deseg_offset = ipfd_head->datalen - pinfo->desegment_offset;
1952
1953                     /* "tvb" and "next_tvb" end at the
1954                      * same byte of data, so the offset
1955                      * relative to the end of "next_tvb"
1956                      * of the byte at which we stopped
1957                      * is also the offset relative to
1958                      * the end of "tvb" of the byte at
1959                      * which we stopped.
1960                      *
1961                      * Convert that back into an offset
1962                      * relative to the beginning of
1963                      * "tvb", by taking the length of
1964                      * "tvb" and subtracting the offset
1965                      * relative to the end.
1966                      */
1967                     deseg_offset = tvb_reported_length(tvb) - deseg_offset;
1968                 }
1969             }
1970         }
1971     }
1972
1973     if (must_desegment) {
1974         /* If the dissector requested "reassemble until FIN"
1975          * just set this flag for the flow and let reassembly
1976          * proceed at normal.  We will check/pick up these
1977          * reassembled PDUs later down in dissect_tcp() when checking
1978          * for the FIN flag.
1979          */
1980         if (tcpd && pinfo->desegment_len == DESEGMENT_UNTIL_FIN) {
1981             tcpd->fwd->flags |= TCP_FLOW_REASSEMBLE_UNTIL_FIN;
1982         }
1983         /*
1984          * The sequence number at which the stuff to be desegmented
1985          * starts is the sequence number of the byte at an offset
1986          * of "deseg_offset" into "tvb".
1987          *
1988          * The sequence number of the byte at an offset of "offset"
1989          * is "seq", i.e. the starting sequence number of this
1990          * segment, so the sequence number of the byte at
1991          * "deseg_offset" is "seq + (deseg_offset - offset)".
1992          */
1993         deseg_seq = seq + (deseg_offset - offset);
1994
1995         if (tcpd && ((nxtseq - deseg_seq) <= 1024*1024)
1996             && (!PINFO_FD_VISITED(pinfo))) {
1997             if(pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
1998                 /* The subdissector asked to reassemble using the
1999                  * entire next segment.
2000                  * Just ask reassembly for one more byte
2001                  * but set this msp flag so we can pick it up
2002                  * above.
2003                  */
2004                 msp = pdu_store_sequencenumber_of_next_pdu(pinfo, deseg_seq,
2005                     nxtseq+1, tcpd->fwd->multisegment_pdus);
2006                 msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
2007             } else {
2008                 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
2009                     deseg_seq, nxtseq+pinfo->desegment_len, tcpd->fwd->multisegment_pdus);
2010             }
2011
2012             /* add this segment as the first one for this new pdu */
2013             fragment_add(&tcp_reassembly_table, tvb, deseg_offset,
2014                          pinfo, msp->first_frame, NULL,
2015                          0, nxtseq - deseg_seq,
2016                          LT_SEQ(nxtseq, msp->nxtpdu));
2017         }
2018     }
2019
2020     if (!called_dissector || pinfo->desegment_len != 0) {
2021         if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
2022             !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
2023             /*
2024              * We know what frame this PDU is reassembled in;
2025              * let the user know.
2026              */
2027             item = proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in, tvb, 0,
2028                                        0, ipfd_head->reassembled_in);
2029             PROTO_ITEM_SET_GENERATED(item);
2030         }
2031
2032         /*
2033          * Either we didn't call the subdissector at all (i.e.,
2034          * this is a segment that contains the middle of a
2035          * higher-level PDU, but contains neither the beginning
2036          * nor the end), or the subdissector couldn't dissect it
2037          * all, as some data was missing (i.e., it set
2038          * "pinfo->desegment_len" to the amount of additional
2039          * data it needs).
2040          */
2041         if (pinfo->desegment_offset == 0) {
2042             /*
2043              * It couldn't, in fact, dissect any of it (the
2044              * first byte it couldn't dissect is at an offset
2045              * of "pinfo->desegment_offset" from the beginning
2046              * of the payload, and that's 0).
2047              * Just mark this as TCP.
2048              */
2049             col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
2050             col_set_str(pinfo->cinfo, COL_INFO, "[TCP segment of a reassembled PDU]");
2051         }
2052
2053         /*
2054          * Show what's left in the packet as just raw TCP segment
2055          * data.
2056          * XXX - remember what protocol the last subdissector
2057          * was, and report it as a continuation of that, instead?
2058          */
2059         nbytes = MAX(0, tvb_reported_length_remaining(tvb, deseg_offset));
2060         proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, deseg_offset,
2061             -1, NULL, "TCP segment data (%u byte%s)", nbytes,
2062             plurality(nbytes, "", "s"));
2063     }
2064     pinfo->can_desegment = 0;
2065     pinfo->desegment_offset = 0;
2066     pinfo->desegment_len = 0;
2067
2068     if(another_pdu_follows) {
2069         /* there was another pdu following this one. */
2070         pinfo->can_desegment = 2;
2071         /* we also have to prevent the dissector from changing the
2072          * PROTOCOL and INFO columns since what follows may be an
2073          * incomplete PDU and we don't want it be changed back from
2074          *  <Protocol>   to <TCP>
2075          * XXX There is no good way to block the PROTOCOL column
2076          * from being changed yet so we set the entire row unwritable.
2077          * The flag cleared_writable stores the initial state.
2078          */
2079         col_set_fence(pinfo->cinfo, COL_INFO);
2080         cleared_writable |= col_get_writable(pinfo->cinfo);
2081         col_set_writable(pinfo->cinfo, FALSE);
2082         offset += another_pdu_follows;
2083         seq += another_pdu_follows;
2084         goto again;
2085     } else {
2086         /* remove any blocking set above otherwise the
2087          * proto,colinfo tap will break
2088          */
2089         if(cleared_writable) {
2090             col_set_writable(pinfo->cinfo, TRUE);
2091         }
2092     }
2093 }
2094
2095 /*
2096  * Loop for dissecting PDUs within a TCP stream; assumes that a PDU
2097  * consists of a fixed-length chunk of data that contains enough information
2098  * to determine the length of the PDU, followed by rest of the PDU.
2099  *
2100  * The first three arguments are the arguments passed to the dissector
2101  * that calls this routine.
2102  *
2103  * "proto_desegment" is the dissector's flag controlling whether it should
2104  * desegment PDUs that cross TCP segment boundaries.
2105  *
2106  * "fixed_len" is the length of the fixed-length part of the PDU.
2107  *
2108  * "get_pdu_len()" is a routine called to get the length of the PDU from
2109  * the fixed-length part of the PDU; it's passed "pinfo", "tvb" and "offset".
2110  *
2111  * "dissect_pdu()" is the routine to dissect a PDU.
2112  */
2113 void
2114 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2115                  gboolean proto_desegment, guint fixed_len,
2116                  guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
2117                  new_dissector_t dissect_pdu, void* dissector_data)
2118 {
2119     volatile int offset = 0;
2120     int offset_before;
2121     guint length_remaining;
2122     guint plen;
2123     guint length;
2124     tvbuff_t *next_tvb;
2125     proto_item *item=NULL;
2126     void *pd_save;
2127
2128     while (tvb_reported_length_remaining(tvb, offset) > 0) {
2129         /*
2130          * We use "tvb_ensure_length_remaining()" to make sure there actually
2131          * *is* data remaining.  The protocol we're handling could conceivably
2132          * consists of a sequence of fixed-length PDUs, and therefore the
2133          * "get_pdu_len" routine might not actually fetch anything from
2134          * the tvbuff, and thus might not cause an exception to be thrown if
2135          * we've run past the end of the tvbuff.
2136          *
2137          * This means we're guaranteed that "length_remaining" is positive.
2138          */
2139         length_remaining = tvb_ensure_length_remaining(tvb, offset);
2140
2141         /*
2142          * Can we do reassembly?
2143          */
2144         if (proto_desegment && pinfo->can_desegment) {
2145             /*
2146              * Yes - is the fixed-length part of the PDU split across segment
2147              * boundaries?
2148              */
2149             if (length_remaining < fixed_len) {
2150                 /*
2151                  * Yes.  Tell the TCP dissector where the data for this message
2152                  * starts in the data it handed us and that we need "some more
2153                  * data."  Don't tell it exactly how many bytes we need because
2154                  * if/when we ask for even more (after the header) that will
2155                  * break reassembly.
2156                  */
2157                 pinfo->desegment_offset = offset;
2158                 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2159                 return;
2160             }
2161         }
2162
2163         /*
2164          * Get the length of the PDU.
2165          */
2166         plen = (*get_pdu_len)(pinfo, tvb, offset);
2167         if (plen < fixed_len) {
2168             /*
2169              * Either:
2170              *
2171              *  1) the length value extracted from the fixed-length portion
2172              *     doesn't include the fixed-length portion's length, and
2173              *     was so large that, when the fixed-length portion's
2174              *     length was added to it, the total length overflowed;
2175              *
2176              *  2) the length value extracted from the fixed-length portion
2177              *     includes the fixed-length portion's length, and the value
2178              *     was less than the fixed-length portion's length, i.e. it
2179              *     was bogus.
2180              *
2181              * Report this as a bounds error.
2182              */
2183             show_reported_bounds_error(tvb, pinfo, tree);
2184             return;
2185         }
2186
2187         /* give a hint to TCP where the next PDU starts
2188          * so that it can attempt to find it in case it starts
2189          * somewhere in the middle of a segment.
2190          */
2191         if(!pinfo->fd->flags.visited && tcp_analyze_seq) {
2192             guint remaining_bytes;
2193             remaining_bytes = MAX(0, tvb_reported_length_remaining(tvb, offset));
2194             if(plen>remaining_bytes) {
2195                 pinfo->want_pdu_tracking=2;
2196                 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
2197             }
2198         }
2199
2200         /*
2201          * Can we do reassembly?
2202          */
2203         if (proto_desegment && pinfo->can_desegment) {
2204             /*
2205              * Yes - is the PDU split across segment boundaries?
2206              */
2207             if (length_remaining < plen) {
2208                 /*
2209                  * Yes.  Tell the TCP dissector where the data for this message
2210                  * starts in the data it handed us, and how many more bytes we
2211                  * need, and return.
2212                  */
2213                 pinfo->desegment_offset = offset;
2214                 pinfo->desegment_len = plen - length_remaining;
2215                 return;
2216             }
2217         }
2218
2219         /*
2220          * Do not display the the PDU length if it crosses the boundary of the
2221          * packet and no more packets are available.
2222          *
2223          * XXX - we don't necessarily know whether more packets are
2224          * available; we might be doing a one-pass read through the
2225          * capture in TShark, or we might be doing a live capture in
2226          * Wireshark.
2227          */
2228 #if 0
2229         if (length_remaining >= plen || there are more packets)
2230         {
2231 #endif
2232                 /*
2233                  * Display the PDU length as a field
2234                  */
2235                 item=proto_tree_add_uint(tree ? tree->last_child : NULL,
2236                                          hf_tcp_pdu_size,
2237                                          tvb, offset, plen, plen);
2238                 PROTO_ITEM_SET_GENERATED(item);
2239 #if 0
2240         } else {
2241                 item = proto_tree_add_text(tree ? tree->last_child : NULL, tvb, offset, -1,
2242                     "PDU Size: %u cut short at %u",plen,length_remaining);
2243                 PROTO_ITEM_SET_GENERATED(item);
2244         }
2245 #endif
2246
2247         /*
2248          * Construct a tvbuff containing the amount of the payload we have
2249          * available.  Make its reported length the amount of data in the PDU.
2250          */
2251         length = length_remaining;
2252         if (length > plen)
2253             length = plen;
2254         next_tvb = tvb_new_subset(tvb, offset, length, plen);
2255
2256         /*
2257          * Dissect the PDU.
2258          *
2259          * If it gets an error that means there's no point in
2260          * dissecting any more PDUs, rethrow the exception in
2261          * question.
2262          *
2263          * If it gets any other error, report it and continue, as that
2264          * means that PDU got an error, but that doesn't mean we should
2265          * stop dissecting PDUs within this frame or chunk of reassembled
2266          * data.
2267          */
2268         pd_save = pinfo->private_data;
2269         TRY {
2270             (*dissect_pdu)(next_tvb, pinfo, tree, dissector_data);
2271         }
2272         CATCH_NONFATAL_ERRORS {
2273             /*  Restore the private_data structure in case one of the
2274              *  called dissectors modified it (and, due to the exception,
2275              *  was unable to restore it).
2276              */
2277             pinfo->private_data = pd_save;
2278             show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
2279         }
2280         ENDTRY;
2281
2282         /*
2283          * Step to the next PDU.
2284          * Make sure we don't overflow.
2285          */
2286         offset_before = offset;
2287         offset += plen;
2288         if (offset <= offset_before)
2289             break;
2290     }
2291 }
2292
2293 static void
2294 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
2295 {
2296     col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%u", abbrev, val);
2297 }
2298
2299 static void
2300 dissect_tcpopt_exp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
2301     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2302 {
2303     proto_item *item;
2304     proto_tree *exp_tree;
2305     proto_item *hidden_item;
2306     guint16 magic;
2307
2308     item = proto_tree_add_item(opt_tree, hf_tcp_option_exp, tvb,
2309                                offset, optlen, ENC_NA);
2310     exp_tree = proto_item_add_subtree(item, ett_tcp_option_exp);
2311     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
2312     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
2313     if (tcp_exp_options_with_magic && ((optlen - 2) > 0)) {
2314         magic = tvb_get_ntohs(tvb, offset + 2);
2315         proto_tree_add_item(exp_tree, hf_tcp_option_exp_magic_number, tvb,
2316                             offset + 2, 2, ENC_BIG_ENDIAN);
2317         switch (magic) {
2318         case 0xf989:
2319             /* FF: draft-ietf-tcpm-fastopen-02, TCP Fast Open */
2320             hidden_item = proto_tree_add_item(exp_tree, hf_tcp_option_fast_open,
2321                                               tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2322             PROTO_ITEM_SET_HIDDEN(hidden_item);
2323             if ((optlen - 2) == 2) {
2324                 /* Fast Open Cookie Request */
2325                 proto_tree_add_item(exp_tree, hf_tcp_option_fast_open_cookie_request,
2326                                     tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2327                 col_append_str(pinfo->cinfo, COL_INFO, " TFO=R");
2328             } else if ((optlen - 2) > 2) {
2329                 /* Fast Open Cookie */
2330                 proto_tree_add_item(exp_tree, hf_tcp_option_fast_open_cookie,
2331                                     tvb, offset + 4, optlen - 4, ENC_NA);
2332                 col_append_str(pinfo->cinfo, COL_INFO, " TFO=C");
2333             }
2334             break;
2335         default:
2336             /* Unknown magic number */
2337             break;
2338         }
2339     } else {
2340         proto_tree_add_item(exp_tree, hf_tcp_option_exp_data, tvb,
2341                             offset + 2, optlen - 2, ENC_NA);
2342         tcp_info_append_uint(pinfo, "Expxx", TRUE);
2343     }
2344 }
2345
2346 static void
2347 dissect_tcpopt_sack_perm(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
2348     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2349 {
2350     proto_item *item;
2351     proto_tree *exp_tree;
2352
2353     item = proto_tree_add_boolean(opt_tree, hf_tcp_option_sack_perm, tvb, offset,
2354                            optlen, TRUE);
2355     exp_tree = proto_item_add_subtree(item, ett_tcp_option_sack_perm);
2356     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
2357     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
2358     tcp_info_append_uint(pinfo, "SACK_PERM", TRUE);
2359 }
2360
2361 static void
2362 dissect_tcpopt_mss(const ip_tcp_opt *optp, tvbuff_t *tvb,
2363     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2364 {
2365     proto_item *item;
2366     proto_tree *exp_tree;
2367     guint16 mss;
2368
2369     mss = tvb_get_ntohs(tvb, offset + 2);
2370     item = proto_tree_add_none_format(opt_tree, hf_tcp_option_mss, tvb, offset,
2371         optlen, "%s: %u bytes", optp->name, mss);
2372     exp_tree = proto_item_add_subtree(item, ett_tcp_option_mss);
2373     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
2374     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
2375     proto_tree_add_item(exp_tree, hf_tcp_option_mss_val, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2376     tcp_info_append_uint(pinfo, "MSS", mss);
2377 }
2378
2379 /* The window scale extension is defined in RFC 1323 */
2380 static void
2381 dissect_tcpopt_wscale(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
2382     int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2383 {
2384     guint8 val, shift;
2385     proto_item *wscale_pi, *gen_pi;
2386     proto_tree *wscale_tree;
2387     struct tcp_analysis *tcpd=NULL;
2388
2389     tcpd=get_tcp_conversation_data(NULL,pinfo);
2390
2391     wscale_pi = proto_tree_add_text(opt_tree, tvb, offset, 3, "Window scale: ");
2392     wscale_tree = proto_item_add_subtree(wscale_pi, ett_tcp_option_wscale);
2393
2394     proto_tree_add_item(wscale_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_NA);
2395     offset += 1;
2396
2397     proto_tree_add_item(wscale_tree, hf_tcp_option_len, tvb, offset, 1, ENC_NA);
2398     offset += 1;
2399
2400     proto_tree_add_item(wscale_tree, hf_tcp_option_wscale_shift, tvb, offset, 1,
2401                         ENC_NA);
2402     shift = tvb_get_guint8(tvb, offset);
2403
2404     gen_pi = proto_tree_add_uint(wscale_tree, hf_tcp_option_wscale_multiplier, tvb,
2405                                  offset, 1, 1 << shift);
2406     PROTO_ITEM_SET_GENERATED(gen_pi);
2407     val = tvb_get_guint8(tvb, offset);
2408
2409     proto_item_append_text(wscale_pi, "%u (multiply by %u)", val, 1 << shift);
2410
2411     tcp_info_append_uint(pinfo, "WS", 1 << shift);
2412
2413     if(!pinfo->fd->flags.visited) {
2414         pdu_store_window_scale_option(shift, tcpd);
2415     }
2416 }
2417
2418 static void
2419 dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
2420     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data)
2421 {
2422     proto_tree *field_tree = NULL;
2423     proto_item *tf=NULL;
2424     proto_item *hidden_item;
2425     guint32 leftedge, rightedge;
2426     struct tcp_analysis *tcpd=NULL;
2427     struct tcpheader *tcph = (struct tcpheader *)data;
2428     guint32 base_ack=0;
2429     guint  num_sack_ranges = 0;
2430
2431     if(tcp_analyze_seq && tcp_relative_seq) {
2432         /* find(or create if needed) the conversation for this tcp session */
2433         tcpd=get_tcp_conversation_data(NULL,pinfo);
2434
2435         if (tcpd) {
2436             base_ack=tcpd->rev->base_seq;
2437         }
2438     }
2439
2440     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
2441                         offset, 1, ENC_BIG_ENDIAN);
2442     PROTO_ITEM_SET_HIDDEN(hidden_item);
2443     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
2444                         offset + 1, 1, ENC_BIG_ENDIAN);
2445     PROTO_ITEM_SET_HIDDEN(hidden_item);
2446
2447     tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
2448     offset += 2;    /* skip past type and length */
2449     optlen -= 2;    /* subtract size of type and length */
2450     while (optlen > 0) {
2451         if (field_tree == NULL) {
2452             /* Haven't yet made a subtree out of this option.  Do so. */
2453             field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2454             hidden_item = proto_tree_add_boolean(field_tree, hf_tcp_option_sack, tvb,
2455                                                  offset, optlen, TRUE);
2456             PROTO_ITEM_SET_HIDDEN(hidden_item);
2457         }
2458         if (optlen < 4) {
2459             proto_tree_add_text(field_tree, tvb, offset,      optlen,
2460                                 "(suboption would go past end of option)");
2461             break;
2462         }
2463         leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
2464         proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
2465                                    offset, 4, leftedge,
2466                                    "left edge = %u%s", leftedge,
2467                                    tcp_relative_seq ? " (relative)" : "");
2468
2469         optlen -= 4;
2470         if (optlen < 4) {
2471             proto_tree_add_text(field_tree, tvb, offset,      optlen,
2472                                 "(suboption would go past end of option)");
2473             break;
2474         }
2475         /* XXX - check whether it goes past end of packet */
2476         rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
2477         optlen -= 4;
2478         proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
2479                                    offset+4, 4, rightedge,
2480                                    "right edge = %u%s", rightedge,
2481                                    tcp_relative_seq ? " (relative)" : "");
2482         tcp_info_append_uint(pinfo, "SLE", leftedge);
2483         tcp_info_append_uint(pinfo, "SRE", rightedge);
2484         num_sack_ranges++;
2485
2486         /* Update tap info */
2487         if (tcph != NULL && (tcph->num_sack_ranges < MAX_TCP_SACK_RANGES)) {
2488             tcph->sack_left_edge[tcph->num_sack_ranges] = leftedge;
2489             tcph->sack_right_edge[tcph->num_sack_ranges] = rightedge;
2490             tcph->num_sack_ranges++;
2491         }
2492
2493         proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
2494         offset += 8;
2495     }
2496
2497     /* Show number of SACK ranges in this option as a generated field */
2498     tf = proto_tree_add_uint(field_tree, hf_tcp_option_sack_range_count,
2499                              tvb, 0, 0, num_sack_ranges);
2500     PROTO_ITEM_SET_GENERATED(tf);
2501 }
2502
2503 static void
2504 dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
2505     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2506 {
2507     proto_item *hidden_item;
2508     guint32 echo;
2509
2510     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
2511                         offset, 1, ENC_BIG_ENDIAN);
2512     PROTO_ITEM_SET_HIDDEN(hidden_item);
2513     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
2514                         offset + 1, 1, ENC_BIG_ENDIAN);
2515     PROTO_ITEM_SET_HIDDEN(hidden_item);
2516
2517     echo = tvb_get_ntohl(tvb, offset + 2);
2518     hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_echo, tvb, offset,
2519                                          optlen, TRUE);
2520     PROTO_ITEM_SET_HIDDEN(hidden_item);
2521     proto_tree_add_text(opt_tree, tvb, offset,      optlen,
2522                         "%s: %u", optp->name, echo);
2523     tcp_info_append_uint(pinfo, "ECHO", echo);
2524 }
2525
2526 /* If set, do not put the TCP timestamp information on the summary line */
2527 static gboolean tcp_ignore_timestamps = FALSE;
2528
2529 static void
2530 dissect_tcpopt_timestamp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
2531     int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2532 {
2533     proto_item *ti;
2534     proto_tree *ts_tree;
2535     guint32 ts_val, ts_ecr;
2536
2537     ti = proto_tree_add_text(opt_tree, tvb, offset, 10, "Timestamps: ");
2538     ts_tree = proto_item_add_subtree(ti, ett_tcp_option_timestamp);
2539
2540     proto_tree_add_item(ts_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_NA);
2541     offset += 1;
2542
2543     proto_tree_add_item(ts_tree, hf_tcp_option_len, tvb, offset, 1, ENC_NA);
2544     offset += 1;
2545
2546     proto_tree_add_item(ts_tree,  hf_tcp_option_timestamp_tsval, tvb, offset,
2547                         4, ENC_BIG_ENDIAN);
2548     ts_val = tvb_get_ntohl(tvb, offset);
2549     offset += 4;
2550
2551     proto_tree_add_item(ts_tree,  hf_tcp_option_timestamp_tsecr, tvb, offset,
2552                         4, ENC_BIG_ENDIAN);
2553     ts_ecr = tvb_get_ntohl(tvb, offset);
2554     /* offset += 4; */
2555
2556     proto_item_append_text(ti, "TSval %u, TSecr %u", ts_val, ts_ecr);
2557     if (tcp_ignore_timestamps == FALSE) {
2558         tcp_info_append_uint(pinfo, "TSval", ts_val);
2559         tcp_info_append_uint(pinfo, "TSecr", ts_ecr);
2560     }
2561 }
2562
2563 /*
2564  * The TCP Extensions for Multipath Operation with Multiple Addresses
2565  * are defined in draft-ietf-mptcp-multiaddressed-04
2566  *
2567  * <http://tools.ietf.org/html/draft-ief-mptcp-multiaddressed-04>
2568  *
2569  * Author: Andrei Maruseac <andrei.maruseac@intel.com>
2570  */
2571 static void
2572 dissect_tcpopt_mptcp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
2573     int offset, guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree, void *data _U_)
2574 {
2575     proto_item *ti;
2576     proto_tree *mptcp_tree;
2577
2578     proto_tree *mptcp_flags_tree;
2579     guint8 subtype;
2580     guint8 indx;
2581     guint8 flags;
2582     guint8 ipver;
2583
2584     ti = proto_tree_add_text(opt_tree, tvb, offset, optlen, "Multipath TCP");
2585     mptcp_tree = proto_item_add_subtree(ti, ett_tcp_option_mptcp);
2586
2587     proto_tree_add_item(mptcp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
2588     offset += 1;
2589
2590     proto_tree_add_item(mptcp_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2591     offset += 1;
2592
2593     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_subtype, tvb,
2594                         offset, 1, ENC_BIG_ENDIAN);
2595
2596     subtype = tvb_get_guint8(tvb, offset) >> 4;
2597     proto_item_append_text(ti, ": %s", val_to_str(subtype, mptcp_subtype_vs, "Unknown (%d)"));
2598     switch (subtype) {
2599         case TCPOPT_MPTCP_MP_CAPABLE:
2600             proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_version, tvb,
2601                         offset, 1, ENC_BIG_ENDIAN);
2602             offset += 1;
2603
2604             flags = tvb_get_guint8(tvb, offset);
2605             ti = proto_tree_add_uint(mptcp_tree, hf_tcp_option_mptcp_flags, tvb,
2606                         offset, 1, flags);
2607             mptcp_flags_tree = proto_item_add_subtree(ti, ett_tcp_option_mptcp);
2608
2609             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_C_flag,
2610                         tvb, offset, 1, ENC_BIG_ENDIAN);
2611             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_S_flag,
2612                         tvb, offset, 1, ENC_BIG_ENDIAN);
2613             offset += 1;
2614
2615             if (optlen == 12 || optlen == 20) {
2616                 proto_tree_add_item(mptcp_tree,
2617                         hf_tcp_option_mptcp_sender_key, tvb, offset, 8, ENC_BIG_ENDIAN);
2618                 offset += 8;
2619             }
2620
2621             if (optlen == 20) {
2622                 proto_tree_add_item(mptcp_tree,
2623                         hf_tcp_option_mptcp_recv_key, tvb, offset, 8, ENC_BIG_ENDIAN);
2624             }
2625             break;
2626
2627         case TCPOPT_MPTCP_MP_JOIN:
2628             switch (optlen) {
2629                 case 12:
2630                     flags = tvb_get_guint8(tvb, offset) & 0x01;
2631                     ti = proto_tree_add_uint(mptcp_tree,
2632                             hf_tcp_option_mptcp_flags, tvb,
2633                             offset, 1, flags);
2634                     mptcp_flags_tree = proto_item_add_subtree(ti,
2635                             ett_tcp_option_mptcp);
2636
2637                     proto_tree_add_item(mptcp_flags_tree,
2638                             hf_tcp_option_mptcp_B_flag, tvb, offset,
2639                             1, ENC_BIG_ENDIAN);
2640                     offset += 1;
2641
2642                     proto_tree_add_item(mptcp_tree,
2643                             hf_tcp_option_mptcp_address_id, tvb, offset,
2644                             1, ENC_BIG_ENDIAN);
2645                     offset += 1;
2646
2647                     proto_tree_add_item(mptcp_tree,
2648                             hf_tcp_option_mptcp_recv_token, tvb, offset,
2649                             4, ENC_BIG_ENDIAN);
2650                     offset += 4;
2651
2652                     proto_tree_add_item(mptcp_tree,
2653                             hf_tcp_option_mptcp_sender_rand, tvb, offset,
2654                             4, ENC_BIG_ENDIAN);
2655                     break;
2656
2657                 case 16:
2658                     flags = tvb_get_guint8(tvb, offset) & 0x01;
2659                     ti = proto_tree_add_uint(mptcp_tree,
2660                             hf_tcp_option_mptcp_flags, tvb,
2661                             offset, 1, flags);
2662                     mptcp_flags_tree = proto_item_add_subtree(ti,
2663                             ett_tcp_option_mptcp);
2664
2665                     proto_tree_add_item(mptcp_flags_tree,
2666                             hf_tcp_option_mptcp_B_flag, tvb, offset,
2667                             1, ENC_BIG_ENDIAN);
2668                     offset += 1;
2669
2670                     proto_tree_add_item(mptcp_tree,
2671                             hf_tcp_option_mptcp_address_id, tvb, offset,
2672                             1, ENC_BIG_ENDIAN);
2673                     offset += 1;
2674
2675                     proto_tree_add_item(mptcp_tree,
2676                             hf_tcp_option_mptcp_sender_trunc_mac, tvb, offset,
2677                             8, ENC_BIG_ENDIAN);
2678                     offset += 8;
2679
2680                     proto_tree_add_item(mptcp_tree,
2681                             hf_tcp_option_mptcp_sender_rand, tvb, offset,
2682                             4, ENC_BIG_ENDIAN);
2683                     break;
2684
2685                 case 24:
2686                     offset += 2;
2687                     for (indx = 0; indx < 5; indx++) {
2688                         proto_tree_add_item(mptcp_tree,
2689                                 hf_tcp_option_mptcp_sender_mac, tvb, offset,
2690                                 4, ENC_BIG_ENDIAN);
2691                         offset += 4;
2692                     }
2693                     break;
2694
2695                 default:
2696                     break;
2697             }
2698             break;
2699
2700         case TCPOPT_MPTCP_DSS:
2701             offset += 1;
2702             flags = tvb_get_guint8(tvb, offset) & 0x1F;
2703             ti = proto_tree_add_uint(mptcp_tree, hf_tcp_option_mptcp_flags, tvb,
2704                             offset, 1, flags);
2705             mptcp_flags_tree = proto_item_add_subtree(ti, ett_tcp_option_mptcp);
2706
2707             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_F_flag,
2708                             tvb, offset, 1, ENC_BIG_ENDIAN);
2709             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_m_flag,
2710                             tvb, offset, 1, ENC_BIG_ENDIAN);
2711             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_M_flag,
2712                             tvb, offset, 1, ENC_BIG_ENDIAN);
2713             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_a_flag,
2714                             tvb, offset, 1, ENC_BIG_ENDIAN);
2715             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_A_flag,
2716                             tvb, offset, 1, ENC_BIG_ENDIAN);
2717             offset += 1;
2718
2719             if (flags & 1) {
2720                 if (flags & 2) {
2721                     proto_tree_add_item(mptcp_tree,
2722                             hf_tcp_option_mptcp_data_ack, tvb, offset,
2723                             8, ENC_BIG_ENDIAN);
2724                     offset += 8;
2725                 } else {
2726                     proto_tree_add_item(mptcp_tree,
2727                             hf_tcp_option_mptcp_data_ack, tvb, offset,
2728                             4, ENC_BIG_ENDIAN);
2729                     offset += 4;
2730                 }
2731             }
2732
2733             if (flags & 4) {
2734                 if (flags & 8) {
2735                     proto_tree_add_item(mptcp_tree,
2736                             hf_tcp_option_mptcp_data_seq_no, tvb, offset,
2737                             8, ENC_BIG_ENDIAN);
2738                     offset += 8;
2739                 } else {
2740                     proto_tree_add_item(mptcp_tree,
2741                             hf_tcp_option_mptcp_data_seq_no, tvb, offset,
2742                             4, ENC_BIG_ENDIAN);
2743                     offset += 4;
2744                 }
2745
2746                 proto_tree_add_item(mptcp_tree,
2747                             hf_tcp_option_mptcp_subflow_seq_no, tvb, offset,
2748                             4, ENC_BIG_ENDIAN);
2749                 offset += 4;
2750
2751                 proto_tree_add_item(mptcp_tree,
2752                             hf_tcp_option_mptcp_data_lvl_len, tvb, offset,
2753                             2, ENC_BIG_ENDIAN);
2754                 offset += 2;
2755
2756                 proto_tree_add_item(mptcp_tree,
2757                             hf_tcp_option_mptcp_checksum, tvb, offset,
2758                             2, ENC_BIG_ENDIAN);
2759             }
2760             break;
2761
2762         case TCPOPT_MPTCP_ADD_ADDR:
2763             proto_tree_add_item(mptcp_tree,
2764                             hf_tcp_option_mptcp_ipver, tvb, offset, 1, ENC_BIG_ENDIAN);
2765             ipver = tvb_get_guint8(tvb, offset) & 0x0F;
2766             offset += 1;
2767
2768             proto_tree_add_item(mptcp_tree,
2769                     hf_tcp_option_mptcp_address_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2770             offset += 1;
2771
2772             switch (ipver) {
2773                 case 4:
2774                     proto_tree_add_item(mptcp_tree,
2775                             hf_tcp_option_mptcp_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
2776                     offset += 4;
2777                     break;
2778
2779                 case 6:
2780                     proto_tree_add_item(mptcp_tree,
2781                             hf_tcp_option_mptcp_ipv6, tvb, offset, 16, ENC_NA);
2782                     offset += 16;
2783                     break;
2784
2785                 default:
2786                     break;
2787             }
2788
2789             if (optlen % 4 == 2) {
2790                 proto_tree_add_item(mptcp_tree,
2791                             hf_tcp_option_mptcp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
2792             }
2793             break;
2794
2795         case TCPOPT_MPTCP_REMOVE_ADDR:
2796             offset += 1;
2797             proto_tree_add_item(mptcp_tree,
2798                             hf_tcp_option_mptcp_address_id, tvb, offset,
2799                             1, ENC_BIG_ENDIAN);
2800             break;
2801
2802         case TCPOPT_MPTCP_MP_PRIO:
2803             flags = tvb_get_guint8(tvb, offset) & 0x01;
2804             ti = proto_tree_add_uint(mptcp_tree, hf_tcp_option_mptcp_flags, tvb,
2805                             offset, 1, flags);
2806             mptcp_flags_tree = proto_item_add_subtree(ti, ett_tcp_option_mptcp);
2807
2808             proto_tree_add_item(mptcp_flags_tree, hf_tcp_option_mptcp_B_flag,
2809                             tvb, offset, 1, ENC_BIG_ENDIAN);
2810             offset += 1;
2811
2812             if (optlen == 4) {
2813                 proto_tree_add_item(mptcp_tree,
2814                         hf_tcp_option_mptcp_address_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2815             }
2816             break;
2817
2818         case TCPOPT_MPTCP_MP_FAIL:
2819             offset += 1;
2820             offset += 1;
2821             proto_tree_add_item(mptcp_tree,
2822                     hf_tcp_option_mptcp_data_seq_no, tvb, offset, 8, ENC_BIG_ENDIAN);
2823             break;
2824
2825         default:
2826             break;
2827     }
2828 }
2829
2830 static void
2831 dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
2832     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2833 {
2834     proto_item *hidden_item;
2835     guint32 cc;
2836
2837     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
2838                         offset, 1, ENC_BIG_ENDIAN);
2839     PROTO_ITEM_SET_HIDDEN(hidden_item);
2840     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
2841                         offset + 1, 1, ENC_BIG_ENDIAN);
2842     PROTO_ITEM_SET_HIDDEN(hidden_item);
2843
2844     cc = tvb_get_ntohl(tvb, offset + 2);
2845     hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_cc, tvb, offset,
2846                                          optlen, TRUE);
2847     PROTO_ITEM_SET_HIDDEN(hidden_item);
2848     proto_tree_add_text(opt_tree, tvb, offset,      optlen,
2849                         "%s: %u", optp->name, cc);
2850     tcp_info_append_uint(pinfo, "CC", cc);
2851 }
2852
2853 static void
2854 dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
2855     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
2856 {
2857
2858     proto_item *hidden_item;
2859
2860     guint8 rate = tvb_get_guint8(tvb, offset + 2) & 0x0f;
2861
2862     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
2863                         offset, 1, ENC_BIG_ENDIAN);
2864     PROTO_ITEM_SET_HIDDEN(hidden_item);
2865     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
2866                         offset + 1, 1, ENC_BIG_ENDIAN);
2867     PROTO_ITEM_SET_HIDDEN(hidden_item);
2868
2869     hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_qs, tvb, offset,
2870                                          optlen, TRUE);
2871     PROTO_ITEM_SET_HIDDEN(hidden_item);
2872     proto_tree_add_text(opt_tree, tvb, offset,      optlen,
2873                         "%s: Rate response, %s, TTL diff %u ", optp->name,
2874                         val_to_str_ext_const(rate, &qs_rate_vals_ext, "Unknown"),
2875                         tvb_get_guint8(tvb, offset + 3));
2876     col_append_fstr(pinfo->cinfo, COL_INFO, " QSresp=%s", val_to_str_ext_const(rate, &qs_rate_vals_ext, "Unknown"));
2877 }
2878
2879
2880 static void
2881 dissect_tcpopt_scps(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
2882             int offset, guint optlen, packet_info *pinfo,
2883             proto_tree *opt_tree, void *data _U_)
2884 {
2885     struct tcp_analysis *tcpd;
2886     proto_tree *field_tree = NULL;
2887     tcp_flow_t *flow;
2888     int         direction;
2889     proto_item *tf = NULL, *hidden_item;
2890     guint8      capvector;
2891     guint8      connid;
2892
2893     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
2894         offset, 1, ENC_BIG_ENDIAN);
2895     PROTO_ITEM_SET_HIDDEN(hidden_item);
2896     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
2897         offset + 1, 1, ENC_BIG_ENDIAN);
2898     PROTO_ITEM_SET_HIDDEN(hidden_item);
2899
2900     tcpd = get_tcp_conversation_data(NULL,pinfo);
2901
2902     /* check direction and get ua lists */
2903     direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
2904
2905     /* if the addresses are equal, match the ports instead */
2906     if(direction==0) {
2907         direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
2908     }
2909
2910     if(direction>=0)
2911         flow =&(tcpd->flow1);
2912     else
2913         flow =&(tcpd->flow2);
2914
2915     /* If the option length == 4, this is a real SCPS capability option
2916      * See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS Transport Protocol
2917      * (SCPS-TP)" Section 3.2.3 for definition.
2918      */
2919     if (optlen == 4) {
2920         hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_scps,
2921                                              tvb, offset, optlen, TRUE);
2922         PROTO_ITEM_SET_HIDDEN(hidden_item);
2923
2924         capvector = tvb_get_guint8(tvb, offset + 2);
2925         connid = tvb_get_guint8(tvb, offset + 3);
2926
2927         tf = proto_tree_add_item(opt_tree, hf_tcp_option_scps_vector, tvb,
2928                                  offset + 2, 1, ENC_BIG_ENDIAN);
2929         field_tree = proto_item_add_subtree(tf, ett_tcp_option_scps);
2930         proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_bets, tvb,
2931                             offset + 2, 1, ENC_BIG_ENDIAN);
2932         proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_snack1, tvb,
2933                             offset + 2, 1, ENC_BIG_ENDIAN);
2934         proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_snack2, tvb,
2935                             offset + 2, 1, ENC_BIG_ENDIAN);
2936         proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_compress, tvb,
2937                             offset + 2, 1, ENC_BIG_ENDIAN);
2938         proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_nlts, tvb,
2939                             offset + 2, 1, ENC_BIG_ENDIAN);
2940         proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_reserved, tvb,
2941                             offset + 2, 1, ENC_BIG_ENDIAN);
2942
2943         if (capvector) {
2944             struct capvec
2945             {
2946                 guint8 mask;
2947                 const gchar *str;
2948             } capvecs[] = {
2949                 {0x80, "BETS"},
2950                 {0x40, "SNACK1"},
2951                 {0x20, "SNACK2"},
2952                 {0x10, "COMP"},
2953                 {0x08, "NLTS"},
2954                 {0x07, "RESERVED"}
2955             };
2956             gboolean anyflag = FALSE;
2957             guint i;
2958
2959             col_append_str(pinfo->cinfo, COL_INFO, " SCPS[");
2960             for (i = 0; i < sizeof(capvecs)/sizeof(struct capvec); i++) {
2961                 if (capvector & capvecs[i].mask) {
2962                     proto_item_append_text(tf, "%s%s", anyflag ? ", " : " (",
2963                                            capvecs[i].str);
2964                     col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
2965                                     anyflag ? ", " : "", capvecs[i].str);
2966                     anyflag = TRUE;
2967                 }
2968             }
2969             col_append_str(pinfo->cinfo, COL_INFO, "]");
2970             proto_item_append_text(tf, ")");
2971         }
2972
2973         proto_tree_add_item(field_tree, hf_tcp_scpsoption_connection_id, tvb,
2974                             offset + 3, 1, ENC_BIG_ENDIAN);
2975         flow->scps_capable = 1;
2976
2977         if (connid)
2978             tcp_info_append_uint(pinfo, "Connection ID", connid);
2979     } else {
2980         /* The option length != 4, so this is an infamous "extended capabilities
2981          * option. See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
2982          * Transport Protocol (SCPS-TP)" Section 3.2.5 for definition.
2983          *
2984          *  As the format of this option is only partially defined (it is
2985          * a community (or more likely vendor) defined format beyond that, so
2986          * at least for now, we only parse the standardized portion of the option.
2987          */
2988         guint8 local_offset = 2;
2989         guint8 binding_space;
2990         guint8 extended_cap_length;
2991
2992         if (flow->scps_capable != 1) {
2993             /* There was no SCPS capabilities option preceding this */
2994             proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector,
2995                                        tvb, offset, optlen, 0,
2996                                        "Illegal SCPS Extended Capabilities (%d bytes)",
2997                                        optlen);
2998         } else {
2999             tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_scps_vector,
3000                                             tvb, offset, optlen, 0,
3001                                             "SCPS Extended Capabilities (%d bytes)",
3002                                             optlen);
3003             field_tree=proto_item_add_subtree(tf, ett_tcp_option_scps_extended);
3004
3005             /* There may be multiple binding spaces included in a single option,
3006              * so we will semi-parse each of the stacked binding spaces - skipping
3007              * over the octets following the binding space identifier and length.
3008              */
3009             while (optlen > local_offset) {
3010
3011                 /* 1st octet is Extended Capability Binding Space */
3012                 binding_space = tvb_get_guint8(tvb, (offset + local_offset));
3013
3014                 /* 2nd octet (upper 4-bits) has binding space length in 16-bit words.
3015                  * As defined by the specification, this length is exclusive of the
3016                  * octets containing the extended capability type and length
3017                  */
3018                 extended_cap_length =
3019                     (tvb_get_guint8(tvb, (offset + local_offset + 1)) >> 4);
3020
3021                 /* Convert the extended capabilities length into bytes for display */
3022                 extended_cap_length = (extended_cap_length << 1);
3023
3024                 proto_tree_add_item(field_tree, hf_tcp_option_scps_binding, tvb, offset + local_offset, 1, ENC_BIG_ENDIAN);
3025                 proto_tree_add_uint(field_tree, hf_tcp_option_scps_binding_len, tvb, offset + local_offset + 1, 1, extended_cap_length);
3026
3027                 /* Step past the binding space and length octets */
3028                 local_offset += 2;
3029
3030                 proto_tree_add_text(field_tree, tvb, offset + local_offset,
3031                                     extended_cap_length,
3032                                     "Binding Space Data (%u bytes)",
3033                                     extended_cap_length);
3034
3035                 tcp_info_append_uint(pinfo, "EXCAP", binding_space);
3036
3037                 /* Step past the Extended capability data
3038                  * Treat the extended capability data area as opaque;
3039                  * If one desires to parse the extended capability data
3040                  * (say, in a vendor aware build of wireshark), it would
3041                  * be triggered here.
3042                  */
3043                 local_offset += extended_cap_length;
3044             }
3045         }
3046     }
3047 }
3048
3049 static void
3050 dissect_tcpopt_user_to(const ip_tcp_opt *optp, tvbuff_t *tvb,
3051     int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
3052 {
3053     proto_item *hidden_item, *tf;
3054     proto_tree *field_tree;
3055     gboolean g;
3056     guint16 to;
3057
3058     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
3059                         offset, 1, ENC_BIG_ENDIAN);
3060     PROTO_ITEM_SET_HIDDEN(hidden_item);
3061     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
3062                         offset + 1, 1, ENC_BIG_ENDIAN);
3063     PROTO_ITEM_SET_HIDDEN(hidden_item);
3064
3065     g = tvb_get_ntohs(tvb, offset + 2) & 0x8000;
3066     to = tvb_get_ntohs(tvb, offset + 2) & 0x7FFF;
3067     hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_user_to, tvb, offset,
3068                                          optlen, TRUE);
3069     PROTO_ITEM_SET_HIDDEN(hidden_item);
3070
3071     tf = proto_tree_add_uint_format(opt_tree, hf_tcp_option_user_to_val, tvb, offset,
3072                                optlen, to, "%s: %u %s", optp->name, to, g ? "minutes" : "seconds");
3073     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3074     proto_tree_add_item(field_tree, hf_tcp_option_user_to_granularity, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
3075     proto_tree_add_item(field_tree, hf_tcp_option_user_to_val, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
3076
3077     tcp_info_append_uint(pinfo, "USER_TO", to);
3078 }
3079
3080 /* This is called for SYN+ACK packets and the purpose is to verify that
3081  * the SCPS capabilities option has been successfully negotiated for the flow.
3082  * If the SCPS capabilities option was offered by only one party, the
3083  * proactively set scps_capable attribute of the flow (set upon seeing
3084  * the first instance of the SCPS option) is revoked.
3085  */
3086 static void
3087 verify_scps(packet_info *pinfo,  proto_item *tf_syn, struct tcp_analysis *tcpd)
3088 {
3089     tf_syn = 0x0;
3090
3091     if(tcpd) {
3092         if ((!(tcpd->flow1.scps_capable)) || (!(tcpd->flow2.scps_capable))) {
3093             tcpd->flow1.scps_capable = 0;
3094             tcpd->flow2.scps_capable = 0;
3095         } else {
3096             expert_add_info(pinfo, tf_syn, &ei_tcp_scps_capable);
3097         }
3098     }
3099 }
3100
3101 /* See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
3102  * Transport Protocol (SCPS-TP)" Section 3.5 for definition of the SNACK option
3103  */
3104 static void
3105 dissect_tcpopt_snack(const ip_tcp_opt *optp, tvbuff_t *tvb,
3106             int offset, guint optlen, packet_info *pinfo,
3107             proto_tree *opt_tree, void *data _U_)
3108 {
3109     struct tcp_analysis *tcpd=NULL;
3110     guint16 relative_hole_offset;
3111     guint16 relative_hole_size;
3112     guint16 base_mss = 0;
3113     guint32 ack;
3114     guint32 hole_start;
3115     guint32 hole_end;
3116     char    null_modifier[] = "\0";
3117     char    relative_modifier[] = "(relative)";
3118     char   *modifier = null_modifier;
3119     proto_item *hidden_item;
3120
3121     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_kind, tvb,
3122                         offset, 1, ENC_BIG_ENDIAN);
3123     PROTO_ITEM_SET_HIDDEN(hidden_item);
3124     hidden_item = proto_tree_add_item(opt_tree, hf_tcp_option_len, tvb,
3125                         offset + 1, 1, ENC_BIG_ENDIAN);
3126     PROTO_ITEM_SET_HIDDEN(hidden_item);
3127
3128     tcpd = get_tcp_conversation_data(NULL,pinfo);
3129
3130     /* The SNACK option reports missing data with a granularity of segments. */
3131     relative_hole_offset = tvb_get_ntohs(tvb, offset + 2);
3132     relative_hole_size = tvb_get_ntohs(tvb, offset + 4);
3133
3134     hidden_item = proto_tree_add_boolean(opt_tree, hf_tcp_option_snack, tvb,
3135                                          offset, optlen, TRUE);
3136     PROTO_ITEM_SET_HIDDEN(hidden_item);
3137
3138     hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_offset,
3139                                       tvb, offset, optlen, relative_hole_offset);
3140     PROTO_ITEM_SET_HIDDEN(hidden_item);
3141
3142     hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_size,
3143                                       tvb, offset, optlen, relative_hole_size);
3144     PROTO_ITEM_SET_HIDDEN(hidden_item);
3145     proto_tree_add_text(opt_tree, tvb, offset, optlen,
3146                         "%s: Offset %u, Size %u", optp->name,
3147                         relative_hole_offset, relative_hole_size);
3148
3149     ack   = tvb_get_ntohl(tvb, 8);
3150
3151     if (tcp_relative_seq) {
3152         ack -= tcpd->rev->base_seq;
3153         modifier = relative_modifier;
3154     }
3155
3156     /* To aid analysis, we can use a simple but generally effective heuristic
3157      * to report the most likely boundaries of the missing data.  If the
3158      * flow is scps_capable, we track the maximum sized segment that was
3159      * acknowledged by the receiver and use that as the reporting granularity.
3160      * This may be different from the negotiated MTU due to PMTUD or flows
3161      * that do not send max-sized segments.
3162      */
3163     base_mss = tcpd->fwd->maxsizeacked;
3164
3165     if (base_mss) {
3166         /* Scale the reported offset and hole size by the largest segment acked */
3167         hole_start = ack + (base_mss * relative_hole_offset);
3168         hole_end   = hole_start + (base_mss * relative_hole_size);
3169
3170         hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_le,
3171                                           tvb, offset, optlen, hole_start);
3172         PROTO_ITEM_SET_HIDDEN(hidden_item);
3173
3174         hidden_item = proto_tree_add_uint(opt_tree, hf_tcp_option_snack_re,
3175                                           tvb, offset, optlen, hole_end);
3176         PROTO_ITEM_SET_HIDDEN(hidden_item);
3177         proto_tree_add_text(opt_tree, tvb, offset, optlen,
3178                             "\tMissing Sequence %u - %u %s",
3179                             hole_start, hole_end, modifier);
3180
3181         tcp_info_append_uint(pinfo, "SNLE", hole_start);
3182         tcp_info_append_uint(pinfo, "SNRE", hole_end);
3183
3184         expert_add_info_format(pinfo, NULL, &ei_tcp_option_snack_sequence, "SNACK Sequence %u - %u %s", hole_start, hole_end, modifier);
3185     }
3186 }
3187
3188 enum
3189 {
3190     PROBE_VERSION_UNSPEC = 0,
3191     PROBE_VERSION_1      = 1,
3192     PROBE_VERSION_2      = 2,
3193     PROBE_VERSION_MAX
3194 };
3195
3196 /* Probe type definition. */
3197 enum
3198 {
3199     PROBE_QUERY          = 0,
3200     PROBE_RESPONSE       = 1,
3201     PROBE_INTERNAL       = 2,
3202     PROBE_TRACE          = 3,
3203     PROBE_QUERY_SH       = 4,
3204     PROBE_RESPONSE_SH    = 5,
3205     PROBE_QUERY_INFO     = 6,
3206     PROBE_RESPONSE_INFO  = 7,
3207     PROBE_QUERY_INFO_SH  = 8,
3208     PROBE_QUERY_INFO_SID = 9,
3209     PROBE_RST            = 10,
3210     PROBE_TYPE_MAX
3211 };
3212
3213 static const value_string rvbd_probe_type_vs[] = {
3214     { PROBE_QUERY,          "Probe Query" },
3215     { PROBE_RESPONSE,       "Probe Response" },
3216     { PROBE_INTERNAL,       "Probe Internal" },
3217     { PROBE_TRACE,          "Probe Trace" },
3218     { PROBE_QUERY_SH,       "Probe Query SH" },
3219     { PROBE_RESPONSE_SH,    "Probe Response SH" },
3220     { PROBE_QUERY_INFO,     "Probe Query Info" },
3221     { PROBE_RESPONSE_INFO,  "Probe Response Info" },
3222     { PROBE_QUERY_INFO_SH,  "Probe Query Info SH" },
3223     { PROBE_QUERY_INFO_SID, "Probe Query Info Store ID" },
3224     { PROBE_RST,            "Probe Reset" },
3225     { 0, NULL }
3226 };
3227
3228
3229 #define PROBE_OPTLEN_OFFSET            1
3230
3231 #define PROBE_VERSION_TYPE_OFFSET      2
3232 #define PROBE_V1_RESERVED_OFFSET       3
3233 #define PROBE_V1_PROBER_OFFSET         4
3234 #define PROBE_V1_APPLI_VERSION_OFFSET  8
3235 #define PROBE_V1_PROXY_ADDR_OFFSET     8
3236 #define PROBE_V1_PROXY_PORT_OFFSET    12
3237 #define PROBE_V1_SH_CLIENT_ADDR_OFFSET 8
3238 #define PROBE_V1_SH_PROXY_ADDR_OFFSET 12
3239 #define PROBE_V1_SH_PROXY_PORT_OFFSET 16
3240
3241 #define PROBE_V2_INFO_OFFSET           3
3242
3243 #define PROBE_V2_INFO_CLIENT_ADDR_OFFSET 4
3244 #define PROBE_V2_INFO_STOREID_OFFSET   4
3245
3246 #define PROBE_VERSION_MASK          0x01
3247
3248 /* Probe Query Extra Info flags */
3249 #define RVBD_FLAGS_PROBE_LAST       0x01
3250 #define RVBD_FLAGS_PROBE_NCFE       0x04
3251
3252 /* Probe Response Extra Info flags */
3253 #define RVBD_FLAGS_PROBE_SERVER     0x01
3254 #define RVBD_FLAGS_PROBE_SSLCERT    0x02
3255 #define RVBD_FLAGS_PROBE            0x10
3256
3257 static void
3258 rvbd_probe_decode_version_type(const guint8 vt, guint8 *ver, guint8 *type)
3259 {
3260     if (vt & PROBE_VERSION_MASK) {
3261         *ver = PROBE_VERSION_1;
3262         *type = vt >> 4;
3263     } else {
3264         *ver = PROBE_VERSION_2;
3265         *type = vt >> 1;
3266     }
3267 }
3268
3269 static void
3270 rvbd_probe_resp_add_info(proto_item *pitem, packet_info *pinfo, guint32 ip, guint16 port)
3271 {
3272     proto_item_append_text(pitem, ", Server Steelhead: %s:%u", ip_to_str((guint8 *)&ip), port);
3273
3274     col_prepend_fstr(pinfo->cinfo, COL_INFO, "SA+, ");
3275 }
3276
3277 static void
3278 dissect_tcpopt_rvbd_probe(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3279                           guint optlen, packet_info *pinfo, proto_tree *opt_tree,
3280                           void *data _U_)
3281 {
3282     guint8 ver, type;
3283     proto_tree *field_tree;
3284     proto_item *pitem;
3285
3286     rvbd_probe_decode_version_type(
3287         tvb_get_guint8(tvb, offset + PROBE_VERSION_TYPE_OFFSET),
3288         &ver, &type);
3289
3290     pitem = proto_tree_add_boolean_format_value(
3291         opt_tree, hf_tcp_option_rvbd_probe, tvb, offset, optlen, 1,
3292         "%s", val_to_str_const(type, rvbd_probe_type_vs, "Probe Unknown"));
3293
3294     if (type >= PROBE_TYPE_MAX)
3295         return;
3296
3297     /* optlen, type, ver are common for all probes */
3298     field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_probe);
3299     pitem = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
3300                         offset + PROBE_OPTLEN_OFFSET, 1, ENC_BIG_ENDIAN);
3301     PROTO_ITEM_SET_HIDDEN(pitem);
3302     pitem = proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
3303                         offset, 1, ENC_BIG_ENDIAN);
3304     PROTO_ITEM_SET_HIDDEN(pitem);
3305     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_optlen, tvb,
3306                         offset + PROBE_OPTLEN_OFFSET, 1, ENC_BIG_ENDIAN);
3307
3308     if (ver == PROBE_VERSION_1) {
3309         guint32 ip;
3310         guint16 port;
3311
3312         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_type1, tvb,
3313                             offset + PROBE_VERSION_TYPE_OFFSET, 1, ENC_BIG_ENDIAN);
3314         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_version1, tvb,
3315                             offset + PROBE_VERSION_TYPE_OFFSET, 1, ENC_BIG_ENDIAN);
3316
3317         if (type == PROBE_INTERNAL)
3318             return;
3319
3320         proto_tree_add_text(field_tree, tvb, offset + PROBE_V1_RESERVED_OFFSET,
3321                             1, "Reserved");
3322
3323         ip = tvb_get_ipv4(tvb, offset + PROBE_V1_PROBER_OFFSET);
3324         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_prober, tvb,
3325                             offset + PROBE_V1_PROBER_OFFSET, 4, ENC_BIG_ENDIAN);
3326
3327         switch (type) {
3328
3329         case PROBE_QUERY:
3330         case PROBE_QUERY_SH:
3331         case PROBE_TRACE:
3332             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_appli_ver, tvb,
3333                                 offset + PROBE_V1_APPLI_VERSION_OFFSET, 2,
3334                                 ENC_BIG_ENDIAN);
3335
3336             proto_item_append_text(pitem, ", CSH IP: %s", ip_to_str((guint8 *)&ip));
3337
3338             {
3339                 /* Small look-ahead hack to distinguish S+ from S+* */
3340 #define PROBE_V1_QUERY_LEN    10
3341                 const guint8 qinfo_hdr[] = { 0x4c, 0x04, 0x0c };
3342                 int not_cfe = 0;
3343                 /* tvb_memeql seems to be the only API that doesn't throw
3344                    an exception in case of an error */
3345                 if (tvb_memeql(tvb, offset + PROBE_V1_QUERY_LEN,
3346                                qinfo_hdr, sizeof(qinfo_hdr)) == 0) {
3347                         not_cfe = tvb_get_guint8(tvb, offset + PROBE_V1_QUERY_LEN +
3348                                                  (int)sizeof(qinfo_hdr)) & RVBD_FLAGS_PROBE_NCFE;
3349                 }
3350                 col_prepend_fstr(pinfo->cinfo, COL_INFO, "S%s, ",
3351                                  type == PROBE_TRACE ? "#" :
3352                                  not_cfe ? "+*" : "+");
3353            }
3354            break;
3355
3356         case PROBE_RESPONSE:
3357             ip = tvb_get_ipv4(tvb, offset + PROBE_V1_PROXY_ADDR_OFFSET);
3358             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy, tvb,
3359                                 offset + PROBE_V1_PROXY_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
3360
3361             port = tvb_get_ntohs(tvb, offset + PROBE_V1_PROXY_PORT_OFFSET);
3362             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy_port, tvb,
3363                                 offset + PROBE_V1_PROXY_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
3364
3365             rvbd_probe_resp_add_info(pitem, pinfo, ip, port);
3366             break;
3367
3368         case PROBE_RESPONSE_SH:
3369             proto_tree_add_item(field_tree,
3370                                 hf_tcp_option_rvbd_probe_client, tvb,
3371                                 offset + PROBE_V1_SH_CLIENT_ADDR_OFFSET, 4,
3372                                 ENC_BIG_ENDIAN);
3373
3374             ip = tvb_get_ipv4(tvb, offset + PROBE_V1_SH_PROXY_ADDR_OFFSET);
3375             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy, tvb,
3376                                 offset + PROBE_V1_SH_PROXY_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
3377
3378             port = tvb_get_ntohs(tvb, offset + PROBE_V1_SH_PROXY_PORT_OFFSET);
3379             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy_port, tvb,
3380                                 offset + PROBE_V1_SH_PROXY_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
3381
3382             rvbd_probe_resp_add_info(pitem, pinfo, ip, port);
3383             break;
3384         }
3385     }
3386     else if (ver == PROBE_VERSION_2) {
3387         proto_item *ver_pi;
3388         proto_item *flag_pi;
3389         proto_tree *flag_tree;
3390         guint8 flags;
3391
3392         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_type2, tvb,
3393                             offset + PROBE_VERSION_TYPE_OFFSET, 1, ENC_BIG_ENDIAN);
3394
3395         proto_tree_add_uint_format_value(
3396             field_tree, hf_tcp_option_rvbd_probe_version2, tvb,
3397             offset + PROBE_VERSION_TYPE_OFFSET, 1, ver, "%u", ver);
3398         /* Use version1 for filtering purposes because version2 packet
3399            value is 0, but filtering is usually done for value 2 */
3400         ver_pi = proto_tree_add_uint(field_tree, hf_tcp_option_rvbd_probe_version1, tvb,
3401                                      offset + PROBE_VERSION_TYPE_OFFSET, 1, ver);
3402         PROTO_ITEM_SET_HIDDEN(ver_pi);
3403
3404         switch (type) {
3405
3406         case PROBE_QUERY_INFO:
3407         case PROBE_QUERY_INFO_SH:
3408         case PROBE_QUERY_INFO_SID:
3409             flags = tvb_get_guint8(tvb, offset + PROBE_V2_INFO_OFFSET);
3410             flag_pi = proto_tree_add_uint(field_tree, hf_tcp_option_rvbd_probe_flags,
3411                                           tvb, offset + PROBE_V2_INFO_OFFSET,
3412                                           1, flags);
3413
3414             flag_tree = proto_item_add_subtree(flag_pi, ett_tcp_opt_rvbd_probe_flags);
3415             proto_tree_add_item(flag_tree,
3416                                 hf_tcp_option_rvbd_probe_flag_not_cfe,
3417                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
3418             proto_tree_add_item(flag_tree,
3419                                 hf_tcp_option_rvbd_probe_flag_last_notify,
3420                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
3421
3422             if (type == PROBE_QUERY_INFO_SH)
3423                 proto_tree_add_item(flag_tree,
3424                                     hf_tcp_option_rvbd_probe_client, tvb,
3425                                     offset + PROBE_V2_INFO_CLIENT_ADDR_OFFSET,
3426                                     4, ENC_BIG_ENDIAN);
3427             else if (type == PROBE_QUERY_INFO_SID)
3428                 proto_tree_add_item(flag_tree,
3429                                     hf_tcp_option_rvbd_probe_storeid, tvb,
3430                                     offset + PROBE_V2_INFO_STOREID_OFFSET,
3431                                     4, ENC_BIG_ENDIAN);
3432
3433             if (type != PROBE_QUERY_INFO_SID &&
3434                 (tvb_get_guint8(tvb, 13) & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK) &&
3435                 (flags & RVBD_FLAGS_PROBE_LAST)) {
3436                 col_prepend_fstr(pinfo->cinfo, COL_INFO, "SA++, ");
3437             }
3438
3439             break;
3440
3441         case PROBE_RESPONSE_INFO:
3442             flag_pi = proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_flags,
3443                                           tvb, offset + PROBE_V2_INFO_OFFSET,
3444                                           1, ENC_BIG_ENDIAN);
3445
3446             flag_tree = proto_item_add_subtree(flag_pi, ett_tcp_opt_rvbd_probe_flags);
3447             proto_tree_add_item(flag_tree,
3448                                 hf_tcp_option_rvbd_probe_flag_probe_cache,
3449                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
3450             proto_tree_add_item(flag_tree,
3451                                 hf_tcp_option_rvbd_probe_flag_sslcert,
3452                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
3453             proto_tree_add_item(flag_tree,
3454                                 hf_tcp_option_rvbd_probe_flag_server_connected,
3455                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
3456             break;
3457
3458         case PROBE_RST:
3459             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_flags,
3460                                   tvb, offset + PROBE_V2_INFO_OFFSET,
3461                                   1, ENC_BIG_ENDIAN);
3462             break;
3463         }
3464     }
3465 }
3466
3467 enum {
3468     TRPY_OPTNUM_OFFSET        = 0,
3469     TRPY_OPTLEN_OFFSET        = 1,
3470
3471     TRPY_OPTIONS_OFFSET       = 2,
3472     TRPY_SRC_ADDR_OFFSET      = 4,
3473     TRPY_DST_ADDR_OFFSET      = 8,
3474     TRPY_SRC_PORT_OFFSET      = 12,
3475     TRPY_DST_PORT_OFFSET      = 14,
3476     TRPY_CLIENT_PORT_OFFSET   = 16
3477 };
3478
3479 /* Trpy Flags */
3480 #define RVBD_FLAGS_TRPY_MODE         0x0001
3481 #define RVBD_FLAGS_TRPY_OOB          0x0002
3482 #define RVBD_FLAGS_TRPY_CHKSUM       0x0004
3483 #define RVBD_FLAGS_TRPY_FW_RST       0x0100
3484 #define RVBD_FLAGS_TRPY_FW_RST_INNER 0x0200
3485 #define RVBD_FLAGS_TRPY_FW_RST_PROBE 0x0400
3486
3487 static const true_false_string trpy_mode_str = {
3488     "Port Transparency",
3489     "Full Transparency"
3490 };
3491
3492 static void
3493 dissect_tcpopt_rvbd_trpy(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
3494                         int offset, guint optlen, packet_info *pinfo,
3495                         proto_tree *opt_tree, void *data _U_)
3496 {
3497     proto_tree *field_tree;
3498     proto_tree *flag_tree;
3499     proto_item *pitem;
3500     proto_item *flag_pi;
3501     guint32 src, dst;
3502     guint16 sport, dport, flags;
3503
3504     col_prepend_fstr(pinfo->cinfo, COL_INFO, "TRPY, ");
3505
3506     pitem = proto_tree_add_boolean_format_value(
3507         opt_tree, hf_tcp_option_rvbd_trpy, tvb, offset, optlen, 1,
3508         "%s", "");
3509
3510     field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_trpy);
3511     pitem = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
3512                         offset + PROBE_OPTLEN_OFFSET, 1, ENC_BIG_ENDIAN);
3513     PROTO_ITEM_SET_HIDDEN(pitem);
3514     pitem = proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
3515                         offset, 1, ENC_BIG_ENDIAN);
3516     PROTO_ITEM_SET_HIDDEN(pitem);
3517     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_optlen, tvb,
3518                         offset + PROBE_OPTLEN_OFFSET, 1, ENC_BIG_ENDIAN);
3519
3520     flags = tvb_get_ntohs(tvb, offset + TRPY_OPTIONS_OFFSET);
3521     flag_pi = proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_flags,
3522                                   tvb, offset + TRPY_OPTIONS_OFFSET,
3523                                   2, ENC_BIG_ENDIAN);
3524
3525     flag_tree = proto_item_add_subtree(flag_pi, ett_tcp_opt_rvbd_trpy_flags);
3526     proto_tree_add_item(flag_tree, hf_tcp_option_rvbd_trpy_flag_fw_rst_probe,
3527                         tvb, offset + TRPY_OPTIONS_OFFSET, 2, ENC_BIG_ENDIAN);
3528     proto_tree_add_item(flag_tree, hf_tcp_option_rvbd_trpy_flag_fw_rst_inner,
3529                         tvb, offset + TRPY_OPTIONS_OFFSET, 2, ENC_BIG_ENDIAN);
3530     proto_tree_add_item(flag_tree, hf_tcp_option_rvbd_trpy_flag_fw_rst,
3531                         tvb, offset + TRPY_OPTIONS_OFFSET, 2, ENC_BIG_ENDIAN);
3532     proto_tree_add_item(flag_tree, hf_tcp_option_rvbd_trpy_flag_chksum,
3533                         tvb, offset + TRPY_OPTIONS_OFFSET, 2, ENC_BIG_ENDIAN);
3534     proto_tree_add_item(flag_tree, hf_tcp_option_rvbd_trpy_flag_oob,
3535                         tvb, offset + TRPY_OPTIONS_OFFSET, 2, ENC_BIG_ENDIAN);
3536     proto_tree_add_item(flag_tree, hf_tcp_option_rvbd_trpy_flag_mode,
3537                         tvb, offset + TRPY_OPTIONS_OFFSET, 2, ENC_BIG_ENDIAN);
3538
3539     src = tvb_get_ipv4(tvb, offset + TRPY_SRC_ADDR_OFFSET);
3540     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_src,
3541                         tvb, offset + TRPY_SRC_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
3542
3543     dst = tvb_get_ipv4(tvb, offset + TRPY_DST_ADDR_OFFSET);
3544     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_dst,
3545                         tvb, offset + TRPY_DST_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
3546
3547     sport = tvb_get_ntohs(tvb, offset + TRPY_SRC_PORT_OFFSET);
3548     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_src_port,
3549                         tvb, offset + TRPY_SRC_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
3550
3551     dport = tvb_get_ntohs(tvb, offset + TRPY_DST_PORT_OFFSET);
3552     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_dst_port,
3553                         tvb, offset + TRPY_DST_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
3554
3555     proto_item_append_text(pitem, "%s:%u -> %s:%u",
3556                            ip_to_str((guint8 *)&src), sport,
3557                            ip_to_str((guint8 *)&dst), dport);
3558
3559     /* Client port only set on SYN: optlen == 18 */
3560     if ((flags & RVBD_FLAGS_TRPY_OOB) && (optlen > TCPOLEN_RVBD_TRPY_MIN))
3561         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_client_port,
3562                             tvb, offset + TRPY_CLIENT_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
3563
3564     /* Despite that we have the right TCP ports for other protocols,
3565      * the data is related to the Riverbed Optimization Protocol and
3566      * not understandable by normal protocol dissectors. If the sport
3567      * protocol is available then use that, otherwise just output it
3568      * as a hex-dump.
3569      */
3570     if (sport_handle != NULL) {
3571         conversation_t *conversation;
3572         conversation = find_conversation(pinfo->fd->num,
3573             &pinfo->src, &pinfo->dst, pinfo->ptype,
3574             pinfo->srcport, pinfo->destport, 0);
3575         if (conversation == NULL) {
3576             conversation = conversation_new(pinfo->fd->num,
3577                 &pinfo->src, &pinfo->dst, pinfo->ptype,
3578                 pinfo->srcport, pinfo->destport, 0);
3579         }
3580         if (conversation->dissector_handle != sport_handle) {
3581             conversation_set_dissector(conversation, sport_handle);
3582         }
3583     } else if (data_handle != NULL) {
3584         conversation_t *conversation;
3585         conversation = find_conversation(pinfo->fd->num,
3586             &pinfo->src, &pinfo->dst, pinfo->ptype,
3587             pinfo->srcport, pinfo->destport, 0);
3588         if (conversation == NULL) {
3589             conversation = conversation_new(pinfo->fd->num,
3590                 &pinfo->src, &pinfo->dst, pinfo->ptype,
3591                 pinfo->srcport, pinfo->destport, 0);
3592         }
3593         if (conversation->dissector_handle != data_handle) {
3594             conversation_set_dissector(conversation, data_handle);
3595         }
3596     }
3597 }
3598
3599 static const ip_tcp_opt tcpopts[] = {
3600     {
3601         TCPOPT_EOL,
3602         "End of Option List (EOL)",
3603         NULL,
3604         OPT_LEN_NO_LENGTH,
3605         0,
3606         NULL,
3607     },
3608     {
3609         TCPOPT_NOP,
3610         "No-Operation (NOP)",
3611         NULL,
3612         OPT_LEN_NO_LENGTH,
3613         0,
3614         NULL,
3615     },
3616     {
3617         TCPOPT_MSS,
3618         "Maximum segment size",
3619         NULL,
3620         OPT_LEN_FIXED_LENGTH,
3621         TCPOLEN_MSS,
3622         dissect_tcpopt_mss
3623     },
3624     {
3625         TCPOPT_WINDOW,
3626         "Window scale",
3627         NULL,
3628         OPT_LEN_FIXED_LENGTH,
3629         TCPOLEN_WINDOW,
3630         dissect_tcpopt_wscale
3631     },
3632     {
3633         TCPOPT_SACK_PERM,
3634         "SACK permitted",
3635         NULL,
3636         OPT_LEN_FIXED_LENGTH,
3637         TCPOLEN_SACK_PERM,
3638         dissect_tcpopt_sack_perm,
3639     },
3640     {
3641         TCPOPT_SACK,
3642         "SACK",
3643         &ett_tcp_option_sack,
3644         OPT_LEN_VARIABLE_LENGTH,
3645         TCPOLEN_SACK_MIN,
3646         dissect_tcpopt_sack
3647     },
3648     {
3649         TCPOPT_ECHO,
3650         "Echo",
3651         NULL,
3652         OPT_LEN_FIXED_LENGTH,
3653         TCPOLEN_ECHO,
3654         dissect_tcpopt_echo
3655     },
3656     {
3657         TCPOPT_ECHOREPLY,
3658         "Echo reply",
3659         NULL,
3660         OPT_LEN_FIXED_LENGTH,
3661         TCPOLEN_ECHOREPLY,
3662         dissect_tcpopt_echo
3663     },
3664     {
3665         TCPOPT_TIMESTAMP,
3666         "Timestamps",
3667         NULL,
3668         OPT_LEN_FIXED_LENGTH,
3669         TCPOLEN_TIMESTAMP,
3670         dissect_tcpopt_timestamp
3671     },
3672     {
3673         TCPOPT_MPTCP,
3674         "Multipath TCP",
3675         NULL,
3676         OPT_LEN_VARIABLE_LENGTH,
3677         TCPOLEN_MPTCP_MIN,
3678         dissect_tcpopt_mptcp
3679     },
3680     {
3681         TCPOPT_CC,
3682         "CC",
3683         NULL,
3684         OPT_LEN_FIXED_LENGTH,
3685         TCPOLEN_CC,
3686         dissect_tcpopt_cc
3687     },
3688     {
3689         TCPOPT_CCNEW,
3690         "CC.NEW",
3691         NULL,
3692         OPT_LEN_FIXED_LENGTH,
3693         TCPOLEN_CCNEW,
3694         dissect_tcpopt_cc
3695     },
3696     {
3697         TCPOPT_CCECHO,
3698         "CC.ECHO",
3699         NULL,
3700         OPT_LEN_FIXED_LENGTH,
3701         TCPOLEN_CCECHO,
3702         dissect_tcpopt_cc
3703     },
3704     {
3705         TCPOPT_MD5,
3706         "TCP MD5 signature",
3707         NULL,
3708         OPT_LEN_FIXED_LENGTH,
3709         TCPOLEN_MD5,
3710         NULL
3711     },
3712     {
3713         TCPOPT_SCPS,
3714         "SCPS capabilities",
3715         &ett_tcp_option_scps,
3716         OPT_LEN_VARIABLE_LENGTH,
3717         TCPOLEN_SCPS,
3718         dissect_tcpopt_scps
3719     },
3720     {
3721         TCPOPT_SNACK,
3722         "Selective Negative Acknowledgment",
3723         NULL,
3724         OPT_LEN_FIXED_LENGTH,
3725         TCPOLEN_SNACK,
3726         dissect_tcpopt_snack
3727     },
3728     {
3729         TCPOPT_RECBOUND,
3730         "SCPS record boundary",
3731         NULL,
3732         OPT_LEN_FIXED_LENGTH,
3733         TCPOLEN_RECBOUND,
3734         NULL
3735     },
3736     {
3737         TCPOPT_CORREXP,
3738         "SCPS corruption experienced",
3739         NULL,
3740         OPT_LEN_FIXED_LENGTH,
3741         TCPOLEN_CORREXP,
3742         NULL
3743     },
3744     {
3745         TCPOPT_QS,
3746         "Quick-Start",
3747         NULL,
3748         OPT_LEN_FIXED_LENGTH,
3749         TCPOLEN_QS,
3750         dissect_tcpopt_qs
3751     },
3752     {
3753         TCPOPT_USER_TO,
3754         "User Timeout",
3755         &ett_tcp_option_user_to,
3756         OPT_LEN_FIXED_LENGTH,
3757         TCPOLEN_USER_TO,
3758         dissect_tcpopt_user_to
3759   },
3760   {
3761         TCPOPT_RVBD_PROBE,
3762         "Riverbed Probe",
3763         NULL,
3764         OPT_LEN_VARIABLE_LENGTH,
3765         TCPOLEN_RVBD_PROBE_MIN,
3766         dissect_tcpopt_rvbd_probe
3767   },
3768   {
3769         TCPOPT_RVBD_TRPY,
3770         "Riverbed Transparency",
3771         NULL,
3772         OPT_LEN_FIXED_LENGTH,
3773         TCPOLEN_RVBD_TRPY_MIN,
3774         dissect_tcpopt_rvbd_trpy
3775   },
3776   {
3777         TCPOPT_EXP_FD,
3778         "Experimental",
3779         NULL,
3780         OPT_LEN_VARIABLE_LENGTH,
3781         TCPOLEN_EXP_MIN,
3782         dissect_tcpopt_exp
3783   },
3784   {
3785         TCPOPT_EXP_FE,
3786         "Experimental",
3787         NULL,
3788         OPT_LEN_VARIABLE_LENGTH,
3789         TCPOLEN_EXP_MIN,
3790         dissect_tcpopt_exp
3791   }
3792 };
3793
3794 #define N_TCP_OPTS  array_length(tcpopts)
3795
3796 static ip_tcp_opt_type TCP_OPT_TYPES = {&hf_tcp_option_type, &ett_tcp_option_type,
3797     &hf_tcp_option_type_copy, &hf_tcp_option_type_class, &hf_tcp_option_type_number};
3798
3799 /* Determine if there is a sub-dissector and call it; return TRUE
3800    if there was a sub-dissector, FALSE otherwise.
3801
3802    This has been separated into a stand alone routine to other protocol
3803    dissectors can call to it, e.g., SOCKS. */
3804
3805 static gboolean try_heuristic_first = FALSE;
3806
3807
3808 /* this function can be called with tcpd==NULL as from the msproxy dissector */
3809 gboolean
3810 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
3811     proto_tree *tree, int src_port, int dst_port,
3812     struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
3813 {
3814     tvbuff_t *next_tvb;
3815     int low_port, high_port;
3816     int save_desegment_offset;
3817     guint32 save_desegment_len;
3818
3819     /* Don't call subdissectors for keepalives.  Even though they do contain
3820      * payload "data", it's just garbage.  Display any data the keepalive
3821      * packet might contain though.
3822      */
3823     if(tcpd && tcpd->ta) {
3824         if(tcpd->ta->flags&TCP_A_KEEP_ALIVE) {
3825             next_tvb = tvb_new_subset_remaining(tvb, offset);
3826             call_dissector(data_handle, next_tvb, pinfo, tree);
3827             return TRUE;
3828         }
3829     }
3830
3831     if (tcp_no_subdissector_on_error && tcpd && tcpd->ta && tcpd->ta->flags & (TCP_A_RETRANSMISSION | TCP_A_OUT_OF_ORDER)) {
3832         /* Don't try to dissect a retransmission high chance that it will mess
3833          * subdissectors for protocols that require in-order delivery of the
3834          * PDUs. (i.e. DCE/RPCoverHTTP and encryption)
3835          */
3836         return FALSE;
3837     }
3838     next_tvb = tvb_new_subset_remaining(tvb, offset);
3839
3840 /* determine if this packet is part of a conversation and call dissector */
3841 /* for the conversation if available */
3842
3843     if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
3844                                    src_port, dst_port, next_tvb, pinfo, tree, tcpinfo)) {
3845         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3846         return TRUE;
3847     }
3848
3849     if (try_heuristic_first) {
3850         /* do lookup with the heuristic subdissector table */
3851         save_desegment_offset = pinfo->desegment_offset;
3852         save_desegment_len = pinfo->desegment_len;
3853         if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, tcpinfo)) {
3854             pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3855             return TRUE;
3856         }
3857         /*
3858          * They rejected the packet; make sure they didn't also request
3859          * desegmentation (we could just override the request, but
3860          * rejecting a packet *and* requesting desegmentation is a sign
3861          * of the dissector's code needing clearer thought, so we fail
3862          * so that the problem is made more obvious).
3863          */
3864         DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
3865                          save_desegment_len == pinfo->desegment_len);
3866     }
3867
3868     /* Do lookups with the subdissector table.
3869        Try the server port captured on the SYN or SYN|ACK packet.  After that
3870        try the port number with the lower value first, followed by the
3871        port number with the higher value.  This means that, for packets
3872        where a dissector is registered for *both* port numbers:
3873
3874        1) we pick the same dissector for traffic going in both directions;
3875
3876        2) we prefer the port number that's more likely to be the right
3877        one (as that prefers well-known ports to reserved ports);
3878
3879        although there is, of course, no guarantee that any such strategy
3880        will always pick the right port number.
3881
3882        XXX - we ignore port numbers of 0, as some dissectors use a port
3883        number of 0 to disable the port. */
3884
3885     if (tcpd && tcpd->server_port != 0 &&
3886         dissector_try_uint_new(subdissector_table, tcpd->server_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
3887         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3888         return TRUE;
3889     }
3890
3891     if (src_port > dst_port) {
3892         low_port = dst_port;
3893         high_port = src_port;
3894     } else {
3895         low_port = src_port;
3896         high_port = dst_port;
3897     }
3898
3899     if (low_port != 0 &&
3900         dissector_try_uint_new(subdissector_table, low_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
3901         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3902         return TRUE;
3903     }
3904     if (high_port != 0 &&
3905         dissector_try_uint_new(subdissector_table, high_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
3906         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3907         return TRUE;
3908     }
3909
3910     if (!try_heuristic_first) {
3911         /* do lookup with the heuristic subdissector table */
3912         save_desegment_offset = pinfo->desegment_offset;
3913         save_desegment_len = pinfo->desegment_len;
3914         if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, tcpinfo)) {
3915             pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3916             return TRUE;
3917         }
3918         /*
3919          * They rejected the packet; make sure they didn't also request
3920          * desegmentation (we could just override the request, but
3921          * rejecting a packet *and* requesting desegmentation is a sign
3922          * of the dissector's code needing clearer thought, so we fail
3923          * so that the problem is made more obvious).
3924          */
3925         DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
3926                          save_desegment_len == pinfo->desegment_len);
3927     }
3928
3929     /* Oh, well, we don't know this; dissect it as data. */
3930     call_dissector(data_handle,next_tvb, pinfo, tree);
3931
3932     pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
3933     return FALSE;
3934 }
3935
3936 static void
3937 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
3938     proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
3939     guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
3940     struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
3941 {
3942     pinfo->want_pdu_tracking=0;
3943
3944     TRY {
3945         if(is_tcp_segment) {
3946             /*qqq   see if it is an unaligned PDU */
3947             if(tcpd && tcp_analyze_seq && (!tcp_desegment)) {
3948                 if(seq || nxtseq) {
3949                     offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
3950                         seq, nxtseq, tcpd->fwd->multisegment_pdus);
3951                 }
3952             }
3953         }
3954         /* if offset is -1 this means that this segment is known
3955          * to be fully inside a previously detected pdu
3956          * so we don't even need to try to dissect it either.
3957          */
3958         if( (offset!=-1) &&
3959             decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
3960                 dst_port, tcpd, tcpinfo) ) {
3961             /*
3962              * We succeeded in handing off to a subdissector.
3963              *
3964              * Is this a TCP segment or a reassembled chunk of
3965              * TCP payload?
3966              */
3967             if(is_tcp_segment) {
3968                 /* if !visited, check want_pdu_tracking and
3969                    store it in table */
3970                 if(tcpd && (!pinfo->fd->flags.visited) &&
3971                     tcp_analyze_seq && pinfo->want_pdu_tracking) {
3972                     if(seq || nxtseq) {
3973                         pdu_store_sequencenumber_of_next_pdu(
3974                             pinfo,
3975                             seq,
3976                             nxtseq+pinfo->bytes_until_next_pdu,
3977                             tcpd->fwd->multisegment_pdus);
3978                     }
3979                 }
3980             }
3981         }
3982     }
3983     CATCH_ALL {
3984         /* We got an exception. At this point the dissection is
3985          * completely aborted and execution will be transferred back
3986          * to (probably) the frame dissector.
3987          * Here we have to place whatever we want the dissector
3988          * to do before aborting the tcp dissection.
3989          */
3990         /*
3991          * Is this a TCP segment or a reassembled chunk of TCP
3992          * payload?
3993          */
3994         if(is_tcp_segment) {
3995             /*
3996              * It's from a TCP segment.
3997              *
3998              * if !visited, check want_pdu_tracking and store it
3999              * in table
4000              */
4001             if(tcpd && (!pinfo->fd->flags.visited) && tcp_analyze_seq && pinfo->want_pdu_tracking) {
4002                 if(seq || nxtseq) {
4003                     pdu_store_sequencenumber_of_next_pdu(pinfo,
4004                         seq,
4005                         nxtseq+pinfo->bytes_until_next_pdu,
4006                         tcpd->fwd->multisegment_pdus);
4007                 }
4008             }
4009         }
4010         RETHROW;
4011     }
4012     ENDTRY;
4013 }
4014
4015 void
4016 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
4017             guint32 nxtseq, guint32 sport, guint32 dport,
4018             proto_tree *tree, proto_tree *tcp_tree,
4019             struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
4020 {
4021     gboolean save_fragmented;
4022
4023     /* Can we desegment this segment? */
4024     if (pinfo->can_desegment) {
4025         /* Yes. */
4026         desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
4027                       tcp_tree, tcpd, tcpinfo);
4028     } else {
4029         /* No - just call the subdissector.
4030            Mark this as fragmented, so if somebody throws an exception,
4031            we don't report it as a malformed frame. */
4032         save_fragmented = pinfo->fragmented;
4033         pinfo->fragmented = TRUE;
4034         process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
4035                             seq, nxtseq, TRUE, tcpd, tcpinfo);
4036         pinfo->fragmented = save_fragmented;
4037     }
4038 }
4039
4040 static void
4041 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4042 {
4043     guint8  th_off_x2; /* combines th_off and th_x2 */
4044     guint16 th_sum;
4045     guint16 th_urp;
4046     proto_tree *tcp_tree = NULL, *field_tree = NULL;
4047     proto_item *ti = NULL, *tf, *hidden_item;
4048     int        offset = 0;
4049     wmem_strbuf_t *flags_strbuf = wmem_strbuf_new_label(wmem_packet_scope());
4050     static const gchar *flags[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR", "NS"};
4051     gint       i;
4052     guint      bpos;
4053     guint      optlen;
4054     guint32    nxtseq = 0;
4055     guint      reported_len;
4056     vec_t      cksum_vec[4];
4057     guint32    phdr[2];
4058     guint16    computed_cksum;
4059     guint16    real_window;
4060     guint      length_remaining;
4061     gboolean   desegment_ok;
4062     struct tcpinfo tcpinfo;
4063     struct tcpheader *tcph;
4064     proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL, *scaled_pi;
4065     conversation_t *conv=NULL;
4066     struct tcp_analysis *tcpd=NULL;
4067     struct tcp_per_packet_data_t *tcppd=NULL;
4068     proto_item *item;
4069     proto_tree *checksum_tree;
4070
4071     wmem_strbuf_append(flags_strbuf, "<None>");
4072
4073     tcph=wmem_new(wmem_packet_scope(), struct tcpheader);
4074     SET_ADDRESS(&tcph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
4075     SET_ADDRESS(&tcph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
4076
4077     col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
4078
4079     /* Clear out the Info column. */
4080     col_clear(pinfo->cinfo, COL_INFO);
4081
4082     tcph->th_sport = tvb_get_ntohs(tvb, offset);
4083     tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
4084     col_add_fstr(pinfo->cinfo, COL_INFO, "%s \xe2\x86\x92 %s", /* UTF8_RIGHTWARDS_ARROW */
4085                     get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
4086     if (tree) {
4087         if (tcp_summary_in_tree) {
4088             ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
4089                                                 "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
4090                                                 get_tcp_port(tcph->th_sport), tcph->th_sport,
4091                                                 get_tcp_port(tcph->th_dport), tcph->th_dport);
4092         }
4093         else {
4094             ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, ENC_NA);
4095         }
4096         tcp_tree = proto_item_add_subtree(ti, ett_tcp);
4097
4098         proto_tree_add_uint_format_value(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
4099                                    "%s (%u)", get_tcp_port(tcph->th_sport), tcph->th_sport);
4100         proto_tree_add_uint_format_value(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
4101                                    "%s (%u)", get_tcp_port(tcph->th_dport), tcph->th_dport);
4102         hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
4103         PROTO_ITEM_SET_HIDDEN(hidden_item);
4104         hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
4105         PROTO_ITEM_SET_HIDDEN(hidden_item);
4106
4107         /*  If we're dissecting the headers of a TCP packet in an ICMP packet
4108          *  then go ahead and put the sequence numbers in the tree now (because
4109          *  they won't be put in later because the ICMP packet only contains up
4110          *  to the sequence number).
4111          *  We should only need to do this for IPv4 since IPv6 will hopefully
4112          *  carry enough TCP payload for this dissector to put the sequence
4113          *  numbers in via the regular code path.
4114          */
4115         {
4116             wmem_list_frame_t *frame;
4117             frame = wmem_list_frame_prev(wmem_list_tail(pinfo->layers));
4118             if (proto_ip == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame))) {
4119                 frame = wmem_list_frame_prev(frame);
4120                 if (proto_icmp == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame))) {
4121                     proto_tree_add_item(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
4122                 }
4123             }
4124         }
4125     }
4126
4127     /* Set the source and destination port numbers as soon as we get them,
4128        so that they're available to the "Follow TCP Stream" code even if
4129        we throw an exception dissecting the rest of the TCP header. */
4130     pinfo->ptype = PT_TCP;
4131     pinfo->srcport = tcph->th_sport;
4132     pinfo->destport = tcph->th_dport;
4133
4134     tcph->th_seq = tvb_get_ntohl(tvb, offset + 4);
4135     tcph->th_ack = tvb_get_ntohl(tvb, offset + 8);
4136     th_off_x2 = tvb_get_guint8(tvb, offset + 12);
4137     tcph->th_flags = tvb_get_ntohs(tvb, offset + 12) & 0x0FFF;
4138     tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
4139     real_window = tcph->th_win;
4140     tcph->th_hlen = hi_nibble(th_off_x2) * 4;  /* TCP header length, in bytes */
4141
4142     /* find(or create if needed) the conversation for this tcp session */
4143     conv=find_or_create_conversation(pinfo);
4144     tcpd=get_tcp_conversation_data(conv,pinfo);
4145
4146     /* If this is a SYN packet, then check if its seq-nr is different
4147      * from the base_seq of the retrieved conversation. If this is the
4148      * case, create a new conversation with the same addresses and ports
4149      * and set the TA_PORTS_REUSED flag. If the seq-nr is the same as
4150      * the base_seq, then do nothing so it will be marked as a retrans-
4151      * mission later.
4152      */
4153     if(tcpd && ((tcph->th_flags&(TH_SYN|TH_ACK))==TH_SYN) &&
4154        (tcpd->fwd->base_seq!=0) &&
4155        (tcph->th_seq!=tcpd->fwd->base_seq) ) {
4156         if (!(pinfo->fd->flags.visited)) {
4157             conv=conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
4158             tcpd=get_tcp_conversation_data(conv,pinfo);
4159         }
4160         if(!tcpd->ta)
4161             tcp_analyze_get_acked_struct(pinfo->fd->num, tcph->th_seq, tcph->th_ack, TRUE, tcpd);
4162         tcpd->ta->flags|=TCP_A_REUSED_PORTS;
4163     }
4164
4165     if (tcpd) {
4166         item = proto_tree_add_uint(tcp_tree, hf_tcp_stream, tvb, offset, 0, tcpd->stream);
4167         PROTO_ITEM_SET_GENERATED(item);
4168
4169         /* Copy the stream index into the header as well to make it available
4170          * to tap listeners.
4171          */
4172         tcph->th_stream = tcpd->stream;
4173     }
4174
4175     /* Do we need to calculate timestamps relative to the tcp-stream? */
4176     if (tcp_calculate_ts) {
4177         tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, 0);
4178
4179         /*
4180          * Calculate the timestamps relative to this conversation (but only on the
4181          * first run when frames are accessed sequentially)
4182          */
4183         if (!(pinfo->fd->flags.visited))
4184             tcp_calculate_timestamps(pinfo, tcpd, tcppd);
4185     }
4186
4187     /*
4188      * If we've been handed an IP fragment, we don't know how big the TCP
4189      * segment is, so don't do anything that requires that we know that.
4190      *
4191      * The same applies if we're part of an error packet.  (XXX - if the
4192      * ICMP and ICMPv6 dissectors could set a "this is how big the IP
4193      * header says it is" length in the tvbuff, we could use that; such
4194      * a length might also be useful for handling packets where the IP
4195      * length is bigger than the actual data available in the frame; the
4196      * dissectors should trust that length, and then throw a
4197      * ReportedBoundsError exception when they go past the end of the frame.)
4198      *
4199      * We also can't determine the segment length if the reported length
4200      * of the TCP packet is less than the TCP header length.
4201      */
4202     reported_len = tvb_reported_length(tvb);
4203
4204     if (!pinfo->fragmented && !pinfo->flags.in_error_pkt) {
4205         if (reported_len < tcph->th_hlen) {
4206             proto_item *pi;
4207             pi = proto_tree_add_text(tcp_tree, tvb, offset, 0,
4208                                      "Short segment. Segment/fragment does not contain a full TCP header"
4209                                      " (might be NMAP or someone else deliberately sending unusual packets)");
4210             PROTO_ITEM_SET_GENERATED(pi);
4211             expert_add_info(pinfo, pi, &ei_tcp_short_segment);
4212             tcph->th_have_seglen = FALSE;
4213         } else {
4214             /* Compute the length of data in this segment. */
4215             tcph->th_seglen = reported_len - tcph->th_hlen;
4216             tcph->th_have_seglen = TRUE;
4217
4218             if (tree) {
4219                 proto_item *pi;
4220
4221                 pi = proto_tree_add_uint(ti, hf_tcp_len, tvb, offset+12, 1, tcph->th_seglen);
4222                 PROTO_ITEM_SET_GENERATED(pi);
4223
4224             }
4225
4226
4227             /* handle TCP seq# analysis parse all new segments we see */
4228             if(tcp_analyze_seq) {
4229                 if(!(pinfo->fd->flags.visited)) {
4230                     tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
4231                 }
4232                 if(tcpd && tcp_relative_seq) {
4233                     (tcph->th_seq) -= tcpd->fwd->base_seq;
4234                     if (tcph->th_flags & TH_ACK) {
4235                         (tcph->th_ack) -= tcpd->rev->base_seq;
4236                     }
4237                 }
4238             }
4239
4240             /* re-calculate window size, based on scaling factor */
4241             if (!(tcph->th_flags&TH_SYN)) {   /* SYNs are never scaled */
4242                 if (tcpd && (tcpd->fwd->win_scale>=0)) {
4243                     (tcph->th_win)<<=tcpd->fwd->win_scale;
4244                 }
4245                 else {
4246                     /* Don't have it stored, so use preference setting instead! */
4247                     if (tcp_default_window_scaling>=0) {
4248                         (tcph->th_win)<<=tcp_default_window_scaling;
4249                     }
4250                 }
4251             }
4252
4253             /* Compute the sequence number of next octet after this segment. */
4254             nxtseq = tcph->th_seq + tcph->th_seglen;
4255         }
4256     } else
4257         tcph->th_have_seglen = FALSE;
4258
4259     {
4260         gboolean first_flag = TRUE;
4261         for (i = 0; i < 9; i++) {
4262             bpos = 1 << i;
4263             if (tcph->th_flags & bpos) {
4264                 if (first_flag) {
4265                     wmem_strbuf_truncate(flags_strbuf, 0);
4266                 }
4267                 wmem_strbuf_append_printf(flags_strbuf, "%s%s", first_flag ? "" : ", ", flags[i]);
4268                 first_flag = FALSE;
4269             }
4270         }
4271         if (tcph->th_flags & 0x0E00) {
4272             if (first_flag) {
4273                 wmem_strbuf_truncate(flags_strbuf, 0);
4274             }
4275             wmem_strbuf_append_printf(flags_strbuf, "%sReserved", first_flag ? "" : ", ");
4276         }
4277     }
4278
4279     col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] Seq=%u", wmem_strbuf_get_str(flags_strbuf), tcph->th_seq);
4280     if (tcph->th_flags&TH_ACK) {
4281         col_append_fstr(pinfo->cinfo, COL_INFO, " Ack=%u", tcph->th_ack);
4282     }
4283     col_append_fstr(pinfo->cinfo, COL_INFO, " Win=%u", tcph->th_win);
4284
4285     if (tree) {
4286         if (tcp_summary_in_tree) {
4287             proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
4288         }
4289         if(tcp_relative_seq) {
4290             proto_tree_add_uint_format_value(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq, "%u    (relative sequence number)", tcph->th_seq);
4291         } else {
4292             proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
4293         }
4294     }
4295
4296     if (tcph->th_hlen < TCPH_MIN_LEN) {
4297         /* Give up at this point; we put the source and destination port in
4298            the tree, before fetching the header length, so that they'll
4299            show up if this is in the failing packet in an ICMP error packet,
4300            but it's now time to give up if the header length is bogus. */
4301         col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
4302                         tcph->th_hlen, TCPH_MIN_LEN);
4303         if (tree) {
4304             proto_tree_add_uint_format_value(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
4305                                        "%u bytes (bogus, must be at least %u)", tcph->th_hlen,
4306                                        TCPH_MIN_LEN);
4307         }
4308         return;
4309     }
4310
4311     if (tree) {
4312         if (tcp_summary_in_tree) {
4313             if(tcph->th_flags&TH_ACK) {
4314                 proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
4315             }
4316             if (tcph->th_have_seglen)
4317                 proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
4318         }
4319         proto_item_set_len(ti, tcph->th_hlen);
4320         if (tcph->th_have_seglen) {
4321             if (nxtseq != tcph->th_seq) {
4322                 if(tcp_relative_seq) {
4323                     tf=proto_tree_add_uint_format_value(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "%u    (relative sequence number)", nxtseq);
4324                 } else {
4325                     tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
4326                 }
4327                 PROTO_ITEM_SET_GENERATED(tf);
4328             }
4329         }
4330     }
4331
4332     tf = proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
4333     if (tcph->th_flags & TH_ACK) {
4334         if (tcp_relative_seq) {
4335             proto_item_append_text(tf, "    (relative ack number)");
4336         }
4337     } else {
4338         /* Note if the ACK field is non-zero */
4339         if (tvb_get_ntohl(tvb, offset+8) != 0) {
4340             expert_add_info(pinfo, tf, &ei_tcp_ack_nonzero);
4341         }
4342     }
4343
4344     if (tree) {
4345         proto_tree_add_uint_format_value(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, tcph->th_hlen,
4346                                    "%u bytes", tcph->th_hlen);
4347         tf = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_flags, tvb, offset + 12, 2,
4348                                         tcph->th_flags, "0x%03x (%s)", tcph->th_flags, wmem_strbuf_get_str(flags_strbuf));
4349         field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
4350         proto_tree_add_boolean(field_tree, hf_tcp_flags_res, tvb, offset + 12, 1, tcph->th_flags);
4351         proto_tree_add_boolean(field_tree, hf_tcp_flags_ns, tvb, offset + 12, 1, tcph->th_flags);
4352         proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
4353         proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
4354         proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
4355         proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
4356         proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
4357         tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
4358         tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
4359         tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
4360
4361         /* As discussed in bug 5541, it is better to use two separate
4362          * fields for the real and calculated window size.
4363          */
4364         proto_tree_add_uint(tcp_tree, hf_tcp_window_size_value, tvb, offset + 14, 2, real_window);
4365         scaled_pi = proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
4366         PROTO_ITEM_SET_GENERATED(scaled_pi);
4367
4368         if( !(tcph->th_flags&TH_SYN) && tcpd ) {
4369             switch (tcpd->fwd->win_scale) {
4370
4371             case -1:
4372                 {
4373                     gint16 win_scale = tcpd->fwd->win_scale;
4374                     gboolean override_with_pref = FALSE;
4375
4376                     /* Use preference setting (if set) */
4377                     if (tcp_default_window_scaling != WindowScaling_NotKnown) {
4378                         win_scale = tcp_default_window_scaling;
4379                         override_with_pref = TRUE;
4380                     }
4381
4382                     scaled_pi = proto_tree_add_int_format_value(tcp_tree, hf_tcp_window_size_scalefactor, tvb, offset + 14, 2,
4383                                                           win_scale, "%d (%s)",
4384                                                           win_scale,
4385                                                           (override_with_pref) ? "missing - taken from preference" : "unknown");
4386                     PROTO_ITEM_SET_GENERATED(scaled_pi);
4387                 }
4388                 break;
4389
4390             case -2:
4391                 scaled_pi = proto_tree_add_int_format_value(tcp_tree, hf_tcp_window_size_scalefactor, tvb, offset + 14, 2, tcpd->fwd->win_scale, "%d (no window scaling used)", tcpd->fwd->win_scale);
4392                 PROTO_ITEM_SET_GENERATED(scaled_pi);
4393                 break;
4394
4395             default:
4396                 scaled_pi = proto_tree_add_int_format_value(tcp_tree, hf_tcp_window_size_scalefactor, tvb, offset + 14, 2, 1<<tcpd->fwd->win_scale, "%d", 1<<tcpd->fwd->win_scale);
4397                 PROTO_ITEM_SET_GENERATED(scaled_pi);
4398             }
4399         }
4400     }
4401
4402     if(tcph->th_flags & TH_SYN) {
4403         if(tcph->th_flags & TH_ACK) {
4404            expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_sack, "Connection establish acknowledge (SYN+ACK): server port %s", get_tcp_port(tcph->th_sport));
4405            /* Save the server port to help determine dissector used */
4406            tcpd->server_port = tcph->th_sport;
4407         }
4408         else {
4409            expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_syn, "Connection establish request (SYN): server port %s",
4410                                    get_tcp_port(tcph->th_dport));
4411            /* Save the server port to help determine dissector used */
4412            tcpd->server_port = tcph->th_dport;
4413         }
4414     }
4415     if(tcph->th_flags & TH_FIN)
4416         /* XXX - find a way to know the server port and output only that one */
4417         expert_add_info(pinfo, tf_fin, &ei_tcp_connection_fin);
4418     if(tcph->th_flags & TH_RST)
4419         /* XXX - find a way to know the server port and output only that one */
4420         expert_add_info(pinfo, tf_rst, &ei_tcp_connection_rst);
4421
4422     /* Supply the sequence number of the first byte and of the first byte
4423        after the segment. */
4424     tcpinfo.seq = tcph->th_seq;
4425     tcpinfo.nxtseq = nxtseq;
4426     tcpinfo.lastackseq = tcph->th_ack;
4427
4428     /* Assume we'll pass un-reassembled data to subdissectors. */
4429     tcpinfo.is_reassembled = FALSE;
4430
4431     /*
4432      * Assume, initially, that we can't desegment.
4433      */
4434     pinfo->can_desegment = 0;
4435     th_sum = tvb_get_ntohs(tvb, offset + 16);
4436     if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
4437         /* The packet isn't part of an un-reassembled fragmented datagram
4438            and isn't truncated.  This means we have all the data, and thus
4439            can checksum it and, unless it's being returned in an error
4440            packet, are willing to allow subdissectors to request reassembly
4441            on it. */
4442
4443         if (tcp_check_checksum) {
4444             /* We haven't turned checksum checking off; checksum it. */
4445
4446             /* Set up the fields of the pseudo-header. */
4447             cksum_vec[0].ptr = (guint8 *)pinfo->src.data;
4448             cksum_vec[0].len = pinfo->src.len;
4449             cksum_vec[1].ptr = (guint8 *)pinfo->dst.data;
4450             cksum_vec[1].len = pinfo->dst.len;
4451             cksum_vec[2].ptr = (const guint8 *)phdr;
4452             switch (pinfo->src.type) {
4453
4454             case AT_IPv4:
4455                 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
4456                 cksum_vec[2].len = 4;
4457                 break;
4458
4459             case AT_IPv6:
4460                 phdr[0] = g_htonl(reported_len);
4461                 phdr[1] = g_htonl(IP_PROTO_TCP);
4462                 cksum_vec[2].len = 8;
4463                 break;
4464
4465             default:
4466                 /* TCP runs only atop IPv4 and IPv6.... */
4467                 DISSECTOR_ASSERT_NOT_REACHED();
4468                 break;
4469             }
4470             cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, reported_len);
4471             cksum_vec[3].len = reported_len;
4472             computed_cksum = in_cksum(cksum_vec, 4);
4473             if (computed_cksum == 0 && th_sum == 0xffff) {
4474                 item = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_checksum, tvb,
4475                                                   offset + 16, 2, th_sum,
4476                                                   "0x%04x [should be 0x0000 (see RFC 1624)]", th_sum);
4477
4478                 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
4479                 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
4480                                               offset + 16, 2, FALSE);
4481                 PROTO_ITEM_SET_GENERATED(item);
4482                 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
4483                                               offset + 16, 2, FALSE);
4484                 PROTO_ITEM_SET_GENERATED(item);
4485                 expert_add_info(pinfo, item, &ei_tcp_checksum_ffff);
4486
4487                 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM 0xFFFF]");
4488
4489                 /* Checksum is treated as valid on most systems, so we're willing to desegment it. */
4490                 desegment_ok = TRUE;
4491             } else if (computed_cksum == 0) {
4492                 item = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_checksum, tvb,
4493                                                   offset + 16, 2, th_sum, "0x%04x [correct]", th_sum);
4494
4495                 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
4496                 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
4497                                               offset + 16, 2, TRUE);
4498                 PROTO_ITEM_SET_GENERATED(item);
4499                 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
4500                                               offset + 16, 2, FALSE);
4501                 PROTO_ITEM_SET_GENERATED(item);
4502
4503                 /* Checksum is valid, so we're willing to desegment it. */
4504                 desegment_ok = TRUE;
4505             } else {
4506                 item = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_checksum, tvb,
4507                                                   offset + 16, 2, th_sum,
4508                                                   "0x%04x [incorrect, should be 0x%04x (maybe caused by \"TCP checksum offload\"?)]", th_sum,
4509                                                   in_cksum_shouldbe(th_sum, computed_cksum));
4510
4511                 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
4512                 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
4513                                               offset + 16, 2, FALSE);
4514                 PROTO_ITEM_SET_GENERATED(item);
4515                 item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
4516                                               offset + 16, 2, TRUE);
4517                 PROTO_ITEM_SET_GENERATED(item);
4518                 expert_add_info(pinfo, item, &ei_tcp_checksum_bad);
4519
4520                 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
4521
4522                 /* Checksum is invalid, so we're not willing to desegment it. */
4523                 desegment_ok = FALSE;
4524                 pinfo->noreassembly_reason = " [incorrect TCP checksum]";
4525             }
4526         } else {
4527             item = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_checksum, tvb,
4528                                               offset + 16, 2, th_sum, "0x%04x [validation disabled]", th_sum);
4529
4530             checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
4531             item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
4532                                           offset + 16, 2, FALSE);
4533             PROTO_ITEM_SET_GENERATED(item);
4534             item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
4535                                           offset + 16, 2, FALSE);
4536             PROTO_ITEM_SET_GENERATED(item);
4537
4538             /* We didn't check the checksum, and don't care if it's valid,
4539                so we're willing to desegment it. */
4540             desegment_ok = TRUE;
4541         }
4542     } else {
4543         /* We don't have all the packet data, so we can't checksum it... */
4544         item = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_checksum, tvb,
4545                                           offset + 16, 2, th_sum, "0x%04x [unchecked, not all data available]", th_sum);
4546
4547         checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
4548         item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_good, tvb,
4549                                       offset + 16, 2, FALSE);
4550         PROTO_ITEM_SET_GENERATED(item);
4551         item = proto_tree_add_boolean(checksum_tree, hf_tcp_checksum_bad, tvb,
4552                                       offset + 16, 2, FALSE);
4553         PROTO_ITEM_SET_GENERATED(item);
4554
4555         /* ...and aren't willing to desegment it. */
4556         desegment_ok = FALSE;
4557     }
4558
4559     if (desegment_ok) {
4560         /* We're willing to desegment this.  Is desegmentation enabled? */
4561         if (tcp_desegment) {
4562             /* Yes - is this segment being returned in an error packet? */
4563             if (!pinfo->flags.in_error_pkt) {
4564                 /* No - indicate that we will desegment.
4565                    We do NOT want to desegment segments returned in error
4566                    packets, as they're not part of a TCP connection. */
4567                 pinfo->can_desegment = 2;
4568             }
4569         }
4570     }
4571
4572     th_urp = tvb_get_ntohs(tvb, offset + 18);
4573     item = proto_tree_add_item(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, ENC_BIG_ENDIAN);
4574     if (tcph->th_flags & TH_URG) {
4575         /* Export the urgent pointer, for the benefit of protocols such as
4576            rlogin. */
4577         tcpinfo.urgent = TRUE;
4578         tcpinfo.urgent_pointer = th_urp;
4579         col_append_fstr(pinfo->cinfo, COL_INFO, " Urg=%u", th_urp);
4580     } else {
4581         tcpinfo.urgent = FALSE;
4582          if (th_urp) {
4583             /* Note if the urgent pointer field is non-zero */
4584             expert_add_info(pinfo, item, &ei_tcp_urgent_pointer_non_zero);
4585          }
4586     }
4587
4588     if (tcph->th_have_seglen) {
4589         col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", tcph->th_seglen);
4590     }
4591
4592     /* If there's more than just the fixed-length header (20 bytes), decode the options. */
4593     tcph->num_sack_ranges = 0;
4594     if (tcph->th_hlen > TCPH_MIN_LEN) {
4595         guint bc = (guint)MAX(0, tvb_length_remaining(tvb, offset + 20));
4596
4597         optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
4598
4599         if (tcp_tree != NULL) {
4600             /* If the frame has been sliced but the options field is at least 4 bytes, decode as much
4601              * of it as possible; otherwise, set optlen to zero. */
4602             if (bc < optlen) {
4603                 if (bc >= 4) {
4604                     guint8 *p_options = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset + 20, bc);
4605
4606                     tf = proto_tree_add_bytes_format(tcp_tree, hf_tcp_options, tvb, offset + 20,
4607                             bc, p_options, "Options: (%u bytes but truncated to %u bytes)", optlen, bc);
4608                     optlen = bc;
4609                 } else {
4610                     optlen = 0;
4611                 }
4612             } else {
4613                 guint8 *p_options = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset + 20, optlen);
4614
4615                 tf = proto_tree_add_bytes_format(tcp_tree, hf_tcp_options, tvb, offset +  20,
4616                                                  optlen, p_options, "Options: (%u bytes)", optlen);
4617             }
4618             field_tree = proto_item_add_subtree(tf, ett_tcp_options);
4619         } else {
4620             tf = NULL;
4621             field_tree = NULL;
4622         }
4623         if (optlen)
4624             dissect_ip_tcp_options(tvb, offset + 20, optlen, tcpopts, N_TCP_OPTS, TCPOPT_EOL,
4625                 &TCP_OPT_TYPES, &ei_tcp_opt_len_invalid, pinfo, field_tree, tf, tcph);
4626     }
4627
4628     if(!pinfo->fd->flags.visited) {
4629         if((tcph->th_flags & TH_SYN)==TH_SYN) {
4630             /* Check the validity of the window scale value
4631              */
4632             verify_tcp_window_scaling((tcph->th_flags&TH_ACK)==TH_ACK,tcpd);
4633         }
4634
4635         if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
4636             /* If the SYN or the SYN+ACK offered SCPS capabilities,
4637              * validate the flow's bidirectional scps capabilities.
4638              * The or protects against broken implementations offering
4639              * SCPS capabilities on SYN+ACK even if it wasn't offered with the SYN
4640              */
4641             if(tcpd && ((tcpd->rev->scps_capable) || (tcpd->fwd->scps_capable))) {
4642                 verify_scps(pinfo, tf_syn, tcpd);
4643             }
4644         }
4645     }
4646
4647     /* Skip over header + options */
4648     offset += tcph->th_hlen;
4649
4650     /* Check the packet length to see if there's more data
4651        (it could be an ACK-only packet) */
4652     length_remaining = MAX(0, tvb_length_remaining(tvb, offset));
4653
4654     if (tcph->th_have_seglen) {
4655         if( data_out_file ) {
4656             reassemble_tcp( tcpd->stream,                         /* tcp stream index */
4657                             tcph->th_seq,                         /* sequence number */
4658                             tcph->th_ack,                         /* acknowledgment number */
4659                             tcph->th_seglen,                      /* data length */
4660                             (gchar*)tvb_get_ptr(tvb, offset, length_remaining), /* data */
4661                             length_remaining,                     /* captured data length */
4662                             ( tcph->th_flags & TH_SYN ),          /* is syn set? */
4663                             &pinfo->net_src,
4664                             &pinfo->net_dst,
4665                             pinfo->srcport,
4666                             pinfo->destport,
4667                             pinfo->fd->num);
4668         }
4669     }
4670
4671     /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
4672     if(tcp_analyze_seq) {
4673         guint32 use_seq = tcph->th_seq;
4674         guint32 use_ack = tcph->th_ack;
4675         /* May need to recover absolute values here... */
4676         if (tcp_relative_seq) {
4677             use_seq += tcpd->fwd->base_seq;
4678             if (tcph->th_flags & TH_ACK) {
4679                 use_ack += tcpd->rev->base_seq;
4680             }
4681         }
4682         tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd, use_seq, use_ack);
4683     }
4684
4685     /* handle conversation timestamps */
4686     if(tcp_calculate_ts) {
4687         tcp_print_timestamps(pinfo, tvb, tcp_tree, tcpd, tcppd);
4688     }
4689
4690     tap_queue_packet(tcp_tap, pinfo, tcph);
4691
4692
4693     /* If we're reassembling something whose length isn't known
4694      * beforehand, and that runs all the way to the end of
4695      * the data stream, a FIN indicates the end of the data
4696      * stream and thus the completion of reassembly, so we
4697      * need to explicitly check for that here.
4698      */
4699     if(tcph->th_have_seglen && tcpd && (tcph->th_flags & TH_FIN)
4700        && (tcpd->fwd->flags&TCP_FLOW_REASSEMBLE_UNTIL_FIN) ) {
4701         struct tcp_multisegment_pdu *msp;
4702
4703         /* Is this the FIN that ended the data stream or is it a
4704          * retransmission of that FIN?
4705          */
4706         if (tcpd->fwd->fin == 0 || tcpd->fwd->fin == pinfo->fd->num) {
4707             /* Either we haven't seen a FIN for this flow or we
4708              * have and it's this frame. Note that this is the FIN
4709              * for this flow, terminate reassembly and dissect the
4710              * results. */
4711             tcpd->fwd->fin = pinfo->fd->num;
4712             msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(tcpd->fwd->multisegment_pdus, tcph->th_seq-1);
4713             if(msp) {
4714                 fragment_head *ipfd_head;
4715
4716                 ipfd_head = fragment_add(&tcp_reassembly_table, tvb, offset,
4717                                          pinfo, msp->first_frame, NULL,
4718                                          tcph->th_seq - msp->seq,
4719                                          tcph->th_seglen,
4720                                          FALSE );
4721                 if(ipfd_head) {
4722                     tvbuff_t *next_tvb;
4723
4724                     /* create a new TVB structure for desegmented data
4725                      * datalen-1 to strip the dummy FIN byte off
4726                      */
4727                     next_tvb = tvb_new_chain(tvb, ipfd_head->tvb_data);
4728
4729                     /* add desegmented data to the data source list */
4730                     add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
4731
4732                     /* Show details of the reassembly */
4733                     print_tcp_fragment_tree(ipfd_head, tree, tcp_tree, pinfo, next_tvb);
4734
4735                     /* call the payload dissector
4736                      * but make sure we don't offer desegmentation any more
4737                      */
4738                     pinfo->can_desegment = 0;
4739
4740                     process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, tcph->th_sport, tcph->th_dport, tcph->th_seq,
4741                                         nxtseq, FALSE, tcpd, &tcpinfo);
4742
4743                     return;
4744                 }
4745             }
4746         } else {
4747             /* Yes.  This is a retransmission of the final FIN (or it's
4748              * the final FIN transmitted via a different path).
4749              * XXX - we need to flag retransmissions a bit better.
4750              */
4751             proto_tree_add_text(tcp_tree, tvb, 0, 0, "Retransmission of FIN from frame %u",
4752                                 tcpd->fwd->fin);
4753         }
4754     }
4755
4756     if (tcpd && ((tcpd->fwd && tcpd->fwd->command) || (tcpd->rev && tcpd->rev->command))) {
4757         ti = proto_tree_add_text(tcp_tree, tvb, offset, 0, "Process Information");
4758         PROTO_ITEM_SET_GENERATED(ti);
4759         field_tree = proto_item_add_subtree(ti, ett_tcp_process_info);
4760         if (tcpd->fwd && tcpd->fwd->command) {
4761             proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_dst_uid, tvb, 0, 0,
4762                                              tcpd->fwd->process_uid, "%u", tcpd->fwd->process_uid);
4763             proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_dst_pid, tvb, 0, 0,
4764                                              tcpd->fwd->process_pid, "%u", tcpd->fwd->process_pid);
4765             proto_tree_add_string_format_value(field_tree, hf_tcp_proc_dst_uname, tvb, 0, 0,
4766                                                tcpd->fwd->username, "%s", tcpd->fwd->username);
4767             proto_tree_add_string_format_value(field_tree, hf_tcp_proc_dst_cmd, tvb, 0, 0,
4768                                                tcpd->fwd->command, "%s", tcpd->fwd->command);
4769         }
4770         if (tcpd->rev && tcpd->rev->command) {
4771             proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_src_uid, tvb, 0, 0,
4772                                              tcpd->rev->process_uid, "%u", tcpd->rev->process_uid);
4773             proto_tree_add_uint_format_value(field_tree, hf_tcp_proc_src_pid, tvb, 0, 0,
4774                                              tcpd->rev->process_pid, "%u", tcpd->rev->process_pid);
4775             proto_tree_add_string_format_value(field_tree, hf_tcp_proc_src_uname, tvb, 0, 0,
4776                                                tcpd->rev->username, "%s", tcpd->rev->username);
4777             proto_tree_add_string_format_value(field_tree, hf_tcp_proc_src_cmd, tvb, 0, 0,
4778                                                tcpd->rev->command, "%s", tcpd->rev->command);
4779         }
4780     }
4781
4782     /*
4783      * XXX - what, if any, of this should we do if this is included in an
4784      * error packet?  It might be nice to see the details of the packet
4785      * that caused the ICMP error, but it might not be nice to have the
4786      * dissector update state based on it.
4787      * Also, we probably don't want to run TCP taps on those packets.
4788      */
4789     if (length_remaining != 0) {
4790         if (tcph->th_flags & TH_RST) {
4791             /*
4792              * RFC1122 says:
4793              *
4794              *  4.2.2.12  RST Segment: RFC-793 Section 3.4
4795              *
4796              *    A TCP SHOULD allow a received RST segment to include data.
4797              *
4798              *    DISCUSSION
4799              *         It has been suggested that a RST segment could contain
4800              *         ASCII text that encoded and explained the cause of the
4801              *         RST.  No standard has yet been established for such
4802              *         data.
4803              *
4804              * so for segments with RST we just display the data as text.
4805              */
4806             proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
4807                                 "Reset cause: %s",
4808                                 tvb_format_text(tvb, offset, length_remaining));
4809         } else {
4810             dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
4811                                 tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd, &tcpinfo);
4812         }
4813     }
4814 }
4815
4816 static void
4817 tcp_init(void)
4818 {
4819     tcp_stream_count = 0;
4820     reassembly_table_init(&tcp_reassembly_table,
4821                           &addresses_ports_reassembly_table_functions);
4822 }
4823
4824 void
4825 proto_register_tcp(void)
4826 {
4827     static hf_register_info hf[] = {
4828
4829         { &hf_tcp_srcport,
4830         { "Source Port",        "tcp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
4831             NULL, HFILL }},
4832
4833         { &hf_tcp_dstport,
4834         { "Destination Port",       "tcp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
4835             NULL, HFILL }},
4836
4837         { &hf_tcp_port,
4838         { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
4839             NULL, HFILL }},
4840
4841         { &hf_tcp_stream,
4842         { "Stream index",       "tcp.stream", FT_UINT32, BASE_DEC, NULL, 0x0,
4843             NULL, HFILL }},
4844
4845         { &hf_tcp_seq,
4846         { "Sequence number",        "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
4847             NULL, HFILL }},
4848
4849         { &hf_tcp_nxtseq,
4850         { "Next sequence number",   "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
4851             NULL, HFILL }},
4852
4853         { &hf_tcp_ack,
4854         { "Acknowledgment number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
4855             NULL, HFILL }},
4856
4857         { &hf_tcp_hdr_len,
4858         { "Header Length",      "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
4859             NULL, HFILL }},
4860
4861         { &hf_tcp_flags,
4862         { "Flags",          "tcp.flags", FT_UINT16, BASE_HEX, NULL, TH_MASK,
4863             NULL, HFILL }},
4864
4865         { &hf_tcp_flags_res,
4866         { "Reserved",            "tcp.flags.res", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_RES,
4867             "Three reserved bits (must be zero)", HFILL }},
4868
4869         { &hf_tcp_flags_ns,
4870         { "Nonce", "tcp.flags.ns", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_NS,
4871             "ECN concealment protection (RFC 3540)", HFILL }},
4872
4873         { &hf_tcp_flags_cwr,
4874         { "Congestion Window Reduced (CWR)",            "tcp.flags.cwr", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_CWR,
4875             NULL, HFILL }},
4876
4877         { &hf_tcp_flags_ecn,
4878         { "ECN-Echo",           "tcp.flags.ecn", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_ECN,
4879             NULL, HFILL }},
4880
4881         { &hf_tcp_flags_urg,
4882         { "Urgent",         "tcp.flags.urg", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_URG,
4883             NULL, HFILL }},
4884
4885         { &hf_tcp_flags_ack,
4886         { "Acknowledgment",        "tcp.flags.ack", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_ACK,
4887             NULL, HFILL }},
4888
4889         { &hf_tcp_flags_push,
4890         { "Push",           "tcp.flags.push", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_PUSH,
4891             NULL, HFILL }},
4892
4893         { &hf_tcp_flags_reset,
4894         { "Reset",          "tcp.flags.reset", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_RST,
4895             NULL, HFILL }},
4896
4897         { &hf_tcp_flags_syn,
4898         { "Syn",            "tcp.flags.syn", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_SYN,
4899             NULL, HFILL }},
4900
4901         { &hf_tcp_flags_fin,
4902         { "Fin",            "tcp.flags.fin", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_FIN,
4903             NULL, HFILL }},
4904
4905         { &hf_tcp_window_size_value,
4906         { "Window size value",        "tcp.window_size_value", FT_UINT16, BASE_DEC, NULL, 0x0,
4907             "The window size value from the TCP header", HFILL }},
4908
4909         /* 32 bits so we can present some values adjusted to window scaling */
4910         { &hf_tcp_window_size,
4911         { "Calculated window size",        "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
4912             "The scaled window size (if scaling has been used)", HFILL }},
4913
4914         { &hf_tcp_window_size_scalefactor,
4915         { "Window size scaling factor", "tcp.window_size_scalefactor", FT_INT32, BASE_DEC, NULL, 0x0,
4916             "The window size scaling factor (-1 when unknown, -2 when no scaling is used)", HFILL }},
4917
4918         { &hf_tcp_checksum,
4919         { "Checksum",           "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
4920             "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
4921
4922         { &hf_tcp_checksum_good,
4923         { "Good Checksum",      "tcp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4924             "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
4925
4926         { &hf_tcp_checksum_bad,
4927         { "Bad Checksum",       "tcp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4928             "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
4929
4930         { &hf_tcp_analysis,
4931         { "SEQ/ACK analysis",   "tcp.analysis", FT_NONE, BASE_NONE, NULL, 0x0,
4932             "This frame has some of the TCP analysis shown", HFILL }},
4933
4934         { &hf_tcp_analysis_flags,
4935         { "TCP Analysis Flags",     "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
4936             "This frame has some of the TCP analysis flags set", HFILL }},
4937
4938         { &hf_tcp_analysis_duplicate_ack,
4939         { "Duplicate ACK",      "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
4940             "This is a duplicate ACK", HFILL }},
4941
4942         { &hf_tcp_analysis_duplicate_ack_num,
4943         { "Duplicate ACK #",        "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
4944             "This is duplicate ACK number #", HFILL }},
4945
4946         { &hf_tcp_analysis_duplicate_ack_frame,
4947         { "Duplicate to the ACK in frame",      "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4948             "This is a duplicate to the ACK in frame #", HFILL }},
4949
4950         { &hf_tcp_continuation_to,
4951         { "This is a continuation to the PDU in frame",     "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4952             "This is a continuation to the PDU in frame #", HFILL }},
4953
4954         { &hf_tcp_len,
4955           { "TCP Segment Len",            "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
4956             NULL, HFILL}},
4957
4958         { &hf_tcp_analysis_acks_frame,
4959           { "This is an ACK to the segment in frame",            "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4960             "Which previous segment is this an ACK for", HFILL}},
4961
4962         { &hf_tcp_analysis_bytes_in_flight,
4963           { "Bytes in flight",            "tcp.analysis.bytes_in_flight", FT_UINT32, BASE_DEC, NULL, 0x0,
4964             "How many bytes are now in flight for this connection", HFILL}},
4965
4966         { &hf_tcp_analysis_ack_rtt,
4967           { "The RTT to ACK the segment was",            "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4968             "How long time it took to ACK the segment (RTT)", HFILL}},
4969
4970         { &hf_tcp_analysis_rto,
4971           { "The RTO for this segment was",            "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4972             "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
4973
4974         { &hf_tcp_analysis_rto_frame,
4975           { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4976             "This is the frame we measure the RTO from", HFILL }},
4977
4978         { &hf_tcp_urgent_pointer,
4979         { "Urgent pointer",     "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
4980             NULL, HFILL }},
4981
4982         { &hf_tcp_segment_overlap,
4983         { "Segment overlap",    "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4984             "Segment overlaps with other segments", HFILL }},
4985
4986         { &hf_tcp_segment_overlap_conflict,
4987         { "Conflicting data in segment overlap",    "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4988             "Overlapping segments contained conflicting data", HFILL }},
4989
4990         { &hf_tcp_segment_multiple_tails,
4991         { "Multiple tail segments found",   "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4992             "Several tails were found when reassembling the pdu", HFILL }},
4993
4994         { &hf_tcp_segment_too_long_fragment,
4995         { "Segment too long",   "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4996             "Segment contained data past end of the pdu", HFILL }},
4997
4998         { &hf_tcp_segment_error,
4999         { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5000             "Reassembling error due to illegal segments", HFILL }},
5001
5002         { &hf_tcp_segment_count,
5003         { "Segment count", "tcp.segment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
5004             NULL, HFILL }},
5005
5006         { &hf_tcp_segment,
5007         { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5008             NULL, HFILL }},
5009
5010         { &hf_tcp_segments,
5011         { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
5012             "TCP Segments", HFILL }},
5013
5014         { &hf_tcp_reassembled_in,
5015         { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5016             "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
5017
5018         { &hf_tcp_reassembled_length,
5019         { "Reassembled TCP length", "tcp.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
5020             "The total length of the reassembled payload", HFILL }},
5021
5022         { &hf_tcp_reassembled_data,
5023         { "Reassembled TCP Data", "tcp.reassembled.data", FT_BYTES, BASE_NONE, NULL, 0x0,
5024             "The reassembled payload", HFILL }},
5025
5026         { &hf_tcp_option_kind,
5027           { "Kind", "tcp.option_kind", FT_UINT8,
5028             BASE_DEC, VALS(tcp_option_kind_vs), 0x0, "This TCP option's kind", HFILL }},
5029
5030         { &hf_tcp_option_len,
5031           { "Length", "tcp.option_len", FT_UINT8,
5032             BASE_DEC, NULL, 0x0, "Length of this TCP option in bytes (including kind and length fields)", HFILL }},
5033
5034         { &hf_tcp_options,
5035           { "TCP Options", "tcp.options", FT_BYTES,
5036             BASE_NONE, NULL, 0x0, NULL, HFILL }},
5037
5038         { &hf_tcp_option_mss,
5039           { "TCP MSS Option", "tcp.options.mss", FT_NONE,
5040             BASE_NONE, NULL, 0x0, NULL, HFILL }},
5041
5042         { &hf_tcp_option_mss_val,
5043           { "MSS Value", "tcp.options.mss_val", FT_UINT16,
5044             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5045
5046         { &hf_tcp_option_wscale_shift,
5047           { "Shift count", "tcp.options.wscale.shift", FT_UINT8,
5048             BASE_DEC, NULL, 0x0, "Logarithmically encoded power of 2 scale factor", HFILL}},
5049
5050         { &hf_tcp_option_wscale_multiplier,
5051           { "Multiplier", "tcp.options.wscale.multiplier",  FT_UINT8,
5052             BASE_DEC, NULL, 0x0, "Multiply segment window size by this for scaled window size", HFILL}},
5053
5054         { &hf_tcp_option_exp,
5055           { "TCP Option - Experimental", "tcp.options.experimental", FT_BYTES,
5056             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5057
5058         { &hf_tcp_option_exp_data,
5059           { "Data", "tcp.options.experimental.data", FT_BYTES,
5060             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5061
5062         { &hf_tcp_option_exp_magic_number,
5063           { "Magic Number", "tcp.options.experimental.magic_number", FT_UINT16,
5064             BASE_HEX, NULL, 0x0, NULL, HFILL}},
5065
5066         { &hf_tcp_option_sack_perm,
5067           { "TCP SACK Permitted Option", "tcp.options.sack_perm",
5068             FT_BOOLEAN,
5069             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5070
5071         { &hf_tcp_option_sack,
5072           { "TCP SACK Option", "tcp.options.sack", FT_BOOLEAN,
5073             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5074
5075         { &hf_tcp_option_sack_sle,
5076           {"TCP SACK Left Edge", "tcp.options.sack_le", FT_UINT32,
5077            BASE_DEC, NULL, 0x0, NULL, HFILL}},
5078
5079         { &hf_tcp_option_sack_sre,
5080           {"TCP SACK Right Edge", "tcp.options.sack_re", FT_UINT32,
5081            BASE_DEC, NULL, 0x0, NULL, HFILL}},
5082
5083         { &hf_tcp_option_sack_range_count,
5084           { "TCP SACK Count", "tcp.options.sack.count", FT_UINT8,
5085             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5086
5087         { &hf_tcp_option_echo,
5088           { "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
5089             BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
5090
5091         { &hf_tcp_option_timestamp_tsval,
5092           { "Timestamp value", "tcp.options.timestamp.tsval", FT_UINT32,
5093             BASE_DEC, NULL, 0x0, "Value of sending machine's timestamp clock", HFILL}},
5094
5095         { &hf_tcp_option_timestamp_tsecr,
5096           { "Timestamp echo reply", "tcp.options.timestamp.tsecr", FT_UINT32,
5097             BASE_DEC, NULL, 0x0, "Echoed timestamp from remote machine", HFILL}},
5098
5099         { &hf_tcp_option_mptcp_subtype,
5100           { "Multipath TCP subtype", "tcp.options.mptcp.subtype", FT_UINT8,
5101             BASE_DEC, VALS(mptcp_subtype_vs), 0xF0, NULL, HFILL}},
5102
5103         { &hf_tcp_option_mptcp_version,
5104           { "Multipath TCP version", "tcp.options.mptcp.version", FT_UINT8,
5105             BASE_DEC, NULL, 0x0F, NULL, HFILL}},
5106
5107         { &hf_tcp_option_mptcp_flags,
5108           { "Multipath TCP flags", "tcp.options.mptcp.flags", FT_UINT8,
5109             BASE_HEX, NULL, 0x0, NULL, HFILL}},
5110
5111         { &hf_tcp_option_mptcp_B_flag,
5112           { "Backup flag", "tcp.options.mptcp.backup.flag", FT_UINT8,
5113             BASE_DEC, NULL, 0x01, NULL, HFILL}},
5114
5115         { &hf_tcp_option_mptcp_C_flag,
5116           { "Checksum required", "tcp.options.mptcp.checksumreq.flags", FT_UINT8,
5117             BASE_DEC, NULL, 0x80, NULL, HFILL}},
5118
5119         { &hf_tcp_option_mptcp_S_flag,
5120           { "Use HMAC-SHA1", "tcp.options.mptcp.sha1.flag", FT_UINT8,
5121             BASE_DEC, NULL, 0x01, NULL, HFILL}},
5122
5123         { &hf_tcp_option_mptcp_F_flag,
5124           { "DATA_FIN", "tcp.options.mptcp.datafin.flag", FT_UINT8,
5125             BASE_DEC, NULL, 0x10, NULL, HFILL}},
5126
5127         { &hf_tcp_option_mptcp_m_flag,
5128           { "Data Sequence Number is 8 octets", "tcp.options.mptcp.dseqn8.flag", FT_UINT8,
5129             BASE_DEC, NULL, 0x08, NULL, HFILL}},
5130
5131         { &hf_tcp_option_mptcp_M_flag,
5132           { "Data Sequence Number, Subflow Sequence Number, Data-level Length, Checksum present", "tcp.options.mptcp.dseqnpresent.flag", FT_UINT8,
5133             BASE_DEC, NULL, 0x04, NULL, HFILL}},
5134
5135         { &hf_tcp_option_mptcp_a_flag,
5136           { "Data ACK is 8 octets", "tcp.options.mptcp.dataack8.flag", FT_UINT8,
5137             BASE_DEC, NULL, 0x02, NULL, HFILL}},
5138
5139         { &hf_tcp_option_mptcp_A_flag,
5140           { "Data ACK is present", "tcp.options.mptcp.dataackpresent.flag", FT_UINT8,
5141             BASE_DEC, NULL, 0x01, NULL, HFILL}},
5142
5143         { &hf_tcp_option_mptcp_address_id,
5144           { "Multipath TCP Address ID", "tcp.options.mptcp.addrid", FT_UINT8,
5145             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5146
5147         { &hf_tcp_option_mptcp_sender_key,
5148           { "Multipath TCP Sender's Key", "tcp.options.mptcp.sendkey", FT_UINT64,
5149             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5150
5151         { &hf_tcp_option_mptcp_recv_key,
5152           { "Multipath TCP Receiver's Key", "tcp.options.mptcp.recvkey", FT_UINT64,
5153             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5154
5155         { &hf_tcp_option_mptcp_recv_token,
5156           { "Multipath TCP Receiver's Token", "tcp.options.mptcp.recvtok", FT_UINT32,
5157             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5158
5159         { &hf_tcp_option_mptcp_sender_rand,
5160           { "Multipath TCP Sender's Random Number", "tcp.options.mptcp.sendrand", FT_UINT32,
5161             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5162
5163         { &hf_tcp_option_mptcp_sender_trunc_mac,
5164           { "Multipath TCP Sender's Truncated MAC", "tcp.options.mptcp.sendtruncmac", FT_UINT64,
5165             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5166
5167         { &hf_tcp_option_mptcp_sender_mac,
5168           { "Multipath TCP Sender's MAC", "tcp.options.mptcp.sendmac", FT_UINT32,
5169             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5170
5171         { &hf_tcp_option_mptcp_data_ack,
5172           { "Multipath TCP Data ACK", "tcp.options.mptcp.dataack", FT_UINT64,
5173             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5174
5175         { &hf_tcp_option_mptcp_data_seq_no,
5176           { "Multipath TCP Data Sequence Number", "tcp.options.mptcp.dataseqno", FT_UINT64,
5177             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5178
5179         { &hf_tcp_option_mptcp_subflow_seq_no,
5180           { "Multipath TCP Subflow Sequence Number", "tcp.options.mptcp.subflowseqno", FT_UINT32,
5181             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5182
5183         { &hf_tcp_option_mptcp_data_lvl_len,
5184           { "Multipath TCP Data-level Length", "tcp.options.mptcp.datalvllen", FT_UINT16,
5185             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5186
5187         { &hf_tcp_option_mptcp_checksum,
5188           { "Multipath TCP Checksum", "tcp.options.mptcp.checksum", FT_UINT16,
5189             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5190
5191         { &hf_tcp_option_mptcp_ipver,
5192           { "Multipath TCP IPVer", "tcp.options.mptcp.ipver", FT_UINT8,
5193             BASE_DEC, NULL, 0x0F, NULL, HFILL}},
5194
5195         { &hf_tcp_option_mptcp_ipv4,
5196           { "Multipath TCP Address", "tcp.options.mptcp.ipv4", FT_IPv4,
5197             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5198
5199         { &hf_tcp_option_mptcp_ipv6,
5200           { "Multipath TCP Address", "tcp.options.mptcp.ipv6", FT_IPv6,
5201             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5202
5203         { &hf_tcp_option_mptcp_port,
5204           { "Multipath TCP Port", "tcp.options.mptcp.port", FT_UINT16,
5205             BASE_DEC, NULL, 0x0, NULL, HFILL}},
5206
5207         { &hf_tcp_option_cc,
5208           { "TCP CC Option", "tcp.options.cc", FT_BOOLEAN, BASE_NONE,
5209             NULL, 0x0, NULL, HFILL}},
5210
5211         { &hf_tcp_option_qs,
5212           { "TCP QS Option", "tcp.options.qs", FT_BOOLEAN, BASE_NONE,
5213             NULL, 0x0, NULL, HFILL}},
5214
5215         { &hf_tcp_option_type,
5216           { "Type", "tcp.options.type", FT_UINT8, BASE_DEC,
5217             NULL, 0x0, NULL, HFILL}},
5218
5219         { &hf_tcp_option_type_copy,
5220           { "Copy on fragmentation", "tcp.options.type.copy", FT_BOOLEAN, 8,
5221             TFS(&tfs_yes_no), IPOPT_COPY_MASK, NULL, HFILL}},
5222
5223         { &hf_tcp_option_type_class,
5224           { "Class", "tcp.options.type.class", FT_UINT8, BASE_DEC,
5225             VALS(ipopt_type_class_vals), IPOPT_CLASS_MASK, NULL, HFILL}},
5226
5227         { &hf_tcp_option_type_number,
5228           { "Number", "tcp.options.type.number", FT_UINT8, BASE_DEC,
5229             VALS(ipopt_type_number_vals), IPOPT_NUMBER_MASK, NULL, HFILL}},
5230
5231         { &hf_tcp_option_scps,
5232           { "TCP SCPS Capabilities Option", "tcp.options.scps",
5233             FT_BOOLEAN, BASE_NONE, NULL,  0x0,
5234             NULL, HFILL}},
5235
5236         { &hf_tcp_option_scps_vector,
5237           { "TCP SCPS Capabilities Vector", "tcp.options.scps.vector",
5238             FT_UINT8, BASE_HEX, NULL, 0x0,
5239             NULL, HFILL}},
5240
5241         { &hf_tcp_option_scps_binding,
5242           { "Binding Space (Community) ID",
5243             "tcp.options.scps.binding.id",
5244             FT_UINT8, BASE_DEC, NULL, 0x0,
5245             "TCP SCPS Extended Binding Space (Community) ID", HFILL}},
5246
5247         { &hf_tcp_option_scps_binding_len,
5248           { "Extended Capability Length",
5249             "tcp.options.scps.binding.len",
5250             FT_UINT8, BASE_DEC, NULL, 0x0,
5251             "TCP SCPS Extended Capability Length in bytes", HFILL}},
5252
5253         { &hf_tcp_option_snack,
5254           { "TCP Selective Negative Acknowledgment Option",
5255             "tcp.options.snack",
5256             FT_BOOLEAN, BASE_NONE, NULL,  0x0,
5257             NULL, HFILL}},
5258
5259         { &hf_tcp_option_snack_offset,
5260           { "TCP SNACK Offset", "tcp.options.snack.offset",
5261             FT_UINT16, BASE_DEC, NULL, 0x0,
5262             NULL, HFILL}},
5263
5264         { &hf_tcp_option_snack_size,
5265           { "TCP SNACK Size", "tcp.options.snack.size",
5266             FT_UINT16, BASE_DEC, NULL, 0x0,
5267             NULL, HFILL}},
5268
5269         { &hf_tcp_option_snack_le,
5270           { "TCP SNACK Left Edge", "tcp.options.snack.le",
5271             FT_UINT16, BASE_DEC, NULL, 0x0,
5272             NULL, HFILL}},
5273
5274         { &hf_tcp_option_snack_re,
5275           { "TCP SNACK Right Edge", "tcp.options.snack.re",
5276             FT_UINT16, BASE_DEC, NULL, 0x0,
5277             NULL, HFILL}},
5278
5279         { &hf_tcp_scpsoption_flags_bets,
5280           { "Partial Reliability Capable (BETS)",
5281             "tcp.options.scpsflags.bets", FT_BOOLEAN, 8,
5282             TFS(&tfs_set_notset), 0x80, NULL, HFILL }},
5283
5284         { &hf_tcp_scpsoption_flags_snack1,
5285           { "Short Form SNACK Capable (SNACK1)",
5286             "tcp.options.scpsflags.snack1", FT_BOOLEAN, 8,
5287             TFS(&tfs_set_notset), 0x40, NULL, HFILL }},
5288
5289         { &hf_tcp_scpsoption_flags_snack2,
5290           { "Long Form SNACK Capable (SNACK2)",
5291             "tcp.options.scpsflags.snack2", FT_BOOLEAN, 8,
5292             TFS(&tfs_set_notset), 0x20, NULL, HFILL }},
5293
5294         { &hf_tcp_scpsoption_flags_compress,
5295           { "Lossless Header Compression (COMP)",
5296             "tcp.options.scpsflags.compress", FT_BOOLEAN, 8,
5297             TFS(&tfs_set_notset), 0x10, NULL, HFILL }},
5298
5299         { &hf_tcp_scpsoption_flags_nlts,
5300           { "Network Layer Timestamp (NLTS)",
5301             "tcp.options.scpsflags.nlts", FT_BOOLEAN, 8,
5302             TFS(&tfs_set_notset), 0x8, NULL, HFILL }},
5303
5304         { &hf_tcp_scpsoption_flags_reserved,
5305           { "Reserved",
5306             "tcp.options.scpsflags.reserved", FT_UINT8, BASE_DEC,
5307             NULL, 0x7, NULL, HFILL }},
5308
5309         { &hf_tcp_scpsoption_connection_id,
5310           { "Connection ID",
5311             "tcp.options.scps.binding",
5312             FT_UINT8, BASE_DEC, NULL, 0x0,
5313             "TCP SCPS Connection ID", HFILL}},
5314
5315         { &hf_tcp_option_user_to,
5316           { "TCP User Timeout", "tcp.options.user_to", FT_BOOLEAN,
5317             BASE_NONE, NULL, 0x0, NULL, HFILL }},
5318
5319         { &hf_tcp_option_user_to_granularity,
5320           { "Granularity", "tcp.options.user_to_granularity", FT_BOOLEAN,
5321             16, TFS(&tcp_option_user_to_granularity), 0x8000, "TCP User Timeout Granularity", HFILL}},
5322
5323         { &hf_tcp_option_user_to_val,
5324           { "User Timeout", "tcp.options.user_to_val", FT_UINT16,
5325             BASE_DEC, NULL, 0x7FFF, "TCP User Timeout Value", HFILL}},
5326
5327         { &hf_tcp_option_rvbd_probe,
5328           { "Riverbed Probe", "tcp.options.rvbd.probe", FT_BOOLEAN,
5329             BASE_NONE, NULL, 0x0, "RVBD TCP Probe Option", HFILL }},
5330
5331         { &hf_tcp_option_rvbd_probe_type1,
5332           { "Type", "tcp.options.rvbd.probe.type1",
5333             FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
5334
5335         { &hf_tcp_option_rvbd_probe_type2,
5336           { "Type", "tcp.options.rvbd.probe.type2",
5337             FT_UINT8, BASE_DEC, NULL, 0xFE, NULL, HFILL }},
5338
5339         { &hf_tcp_option_rvbd_probe_version1,
5340           { "Version", "tcp.options.rvbd.probe.version",
5341             FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }},
5342
5343         { &hf_tcp_option_rvbd_probe_version2,
5344           { "Version", "tcp.options.rvbd.probe.version_raw",
5345             FT_UINT8, BASE_DEC, NULL, 0x01, "Version 2 Raw Value", HFILL }},
5346
5347         { &hf_tcp_option_rvbd_probe_optlen,
5348           { "Length", "tcp.options.rvbd.probe.len",
5349             FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5350
5351         { &hf_tcp_option_rvbd_probe_prober,
5352           { "CSH IP", "tcp.options.rvbd.probe.prober",
5353             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5354
5355         { &hf_tcp_option_rvbd_probe_proxy,
5356           { "SSH IP", "tcp.options.rvbd.probe.proxy.ip",
5357             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5358
5359         { &hf_tcp_option_rvbd_probe_proxy_port,
5360           { "SSH Port", "tcp.options.rvbd.probe.proxy.port",
5361             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5362
5363         { &hf_tcp_option_rvbd_probe_appli_ver,
5364           { "Application Version", "tcp.options.rvbd.probe.appli_ver",
5365             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5366
5367         { &hf_tcp_option_rvbd_probe_client,
5368           { "Client IP", "tcp.options.rvbd.probe.client.ip",
5369             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5370
5371         { &hf_tcp_option_rvbd_probe_storeid,
5372           { "CFE Store ID", "tcp.options.rvbd.probe.storeid",
5373             FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5374
5375         { &hf_tcp_option_rvbd_probe_flags,
5376           { "Probe Flags", "tcp.options.rvbd.probe.flags",
5377             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5378
5379         { &hf_tcp_option_rvbd_probe_flag_not_cfe,
5380           { "Not CFE", "tcp.options.rvbd.probe.flags.notcfe",
5381             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_NCFE,
5382             NULL, HFILL }},
5383
5384         { &hf_tcp_option_rvbd_probe_flag_last_notify,
5385           { "Last Notify", "tcp.options.rvbd.probe.flags.last",
5386             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_LAST,
5387             NULL, HFILL }},
5388
5389         { &hf_tcp_option_rvbd_probe_flag_probe_cache,
5390           { "Disable Probe Cache on CSH", "tcp.options.rvbd.probe.flags.probe",
5391             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE,
5392             NULL, HFILL }},
5393
5394         { &hf_tcp_option_rvbd_probe_flag_sslcert,
5395           { "SSL Enabled", "tcp.options.rvbd.probe.flags.ssl",
5396             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_SSLCERT,
5397             NULL, HFILL }},
5398
5399         { &hf_tcp_option_rvbd_probe_flag_server_connected,
5400           { "SSH outer to server established", "tcp.options.rvbd.probe.flags.server",
5401             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_SERVER,
5402             NULL, HFILL }},
5403
5404         { &hf_tcp_option_rvbd_trpy,
5405           { "Riverbed Transparency", "tcp.options.rvbd.trpy",
5406             FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5407             "RVBD TCP Transparency Option", HFILL }},
5408
5409         { &hf_tcp_option_rvbd_trpy_flags,
5410           { "Transparency Options", "tcp.options.rvbd.trpy.flags",
5411             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5412
5413         { &hf_tcp_option_rvbd_trpy_flag_fw_rst_probe,
5414           { "Enable FW traversal feature", "tcp.options.rvbd.trpy.flags.fw_rst_probe",
5415             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
5416             RVBD_FLAGS_TRPY_FW_RST_PROBE,
5417             "Reset state created by probe on the nexthop firewall",
5418             HFILL }},
5419
5420         { &hf_tcp_option_rvbd_trpy_flag_fw_rst_inner,
5421           { "Enable Inner FW feature on All FWs", "tcp.options.rvbd.trpy.flags.fw_rst_inner",
5422             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
5423             RVBD_FLAGS_TRPY_FW_RST_INNER,
5424             "Reset state created by transparent inner on all firewalls"
5425             " before passing connection through",
5426             HFILL }},
5427
5428         { &hf_tcp_option_rvbd_trpy_flag_fw_rst,
5429           { "Enable Transparency FW feature on All FWs", "tcp.options.rvbd.trpy.flags.fw_rst",
5430             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
5431             RVBD_FLAGS_TRPY_FW_RST,
5432             "Reset state created by probe on all firewalls before "
5433             "establishing transparent inner connection", HFILL }},
5434
5435         { &hf_tcp_option_rvbd_trpy_flag_chksum,
5436           { "Reserved", "tcp.options.rvbd.trpy.flags.chksum",
5437             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
5438             RVBD_FLAGS_TRPY_CHKSUM, NULL, HFILL }},
5439
5440         { &hf_tcp_option_rvbd_trpy_flag_oob,
5441           { "Out of band connection", "tcp.options.rvbd.trpy.flags.oob",
5442             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
5443             RVBD_FLAGS_TRPY_OOB, NULL, HFILL }},
5444
5445         { &hf_tcp_option_rvbd_trpy_flag_mode,
5446           { "Transparency Mode", "tcp.options.rvbd.trpy.flags.mode",
5447             FT_BOOLEAN, 16, TFS(&trpy_mode_str),
5448             RVBD_FLAGS_TRPY_MODE, NULL, HFILL }},
5449
5450         { &hf_tcp_option_rvbd_trpy_src,
5451           { "Src SH IP Addr", "tcp.options.rvbd.trpy.src.ip",
5452             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5453
5454         { &hf_tcp_option_rvbd_trpy_dst,
5455           { "Dst SH IP Addr", "tcp.options.rvbd.trpy.dst.ip",
5456             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5457
5458         { &hf_tcp_option_rvbd_trpy_src_port,
5459           { "Src SH Inner Port", "tcp.options.rvbd.trpy.src.port",
5460             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5461
5462         { &hf_tcp_option_rvbd_trpy_dst_port,
5463           { "Dst SH Inner Port", "tcp.options.rvbd.trpy.dst.port",
5464             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5465
5466         { &hf_tcp_option_rvbd_trpy_client_port,
5467           { "Out of band connection Client Port", "tcp.options.rvbd.trpy.client.port",
5468             FT_UINT16, BASE_DEC, NULL , 0x0, NULL, HFILL }},
5469
5470         { &hf_tcp_option_fast_open,
5471           { "Fast Open", "tcp.options.tfo", FT_NONE,
5472             BASE_NONE, NULL, 0x0, NULL, HFILL }},
5473
5474         { &hf_tcp_option_fast_open_cookie_request,
5475           { "Fast Open Cookie Request", "tcp.options.tfo.request", FT_NONE,
5476             BASE_NONE, NULL, 0x0, NULL, HFILL }},
5477
5478         { &hf_tcp_option_fast_open_cookie,
5479           { "Fast Open Cookie", "tcp.options.tfo.cookie", FT_BYTES,
5480             BASE_NONE, NULL, 0x0, NULL, HFILL}},
5481
5482         { &hf_tcp_pdu_time,
5483           { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
5484             "How long time has passed until the last frame of this PDU", HFILL}},
5485
5486         { &hf_tcp_pdu_size,
5487           { "PDU Size", "tcp.pdu.size", FT_UINT32, BASE_DEC, NULL, 0x0,
5488             "The size of this PDU", HFILL}},
5489
5490         { &hf_tcp_pdu_last_frame,
5491           { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
5492             "This is the last frame of the PDU starting in this segment", HFILL }},
5493
5494         { &hf_tcp_ts_relative,
5495           { "Time since first frame in this TCP stream", "tcp.time_relative", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
5496             "Time relative to first frame in this TCP stream", HFILL}},
5497
5498         { &hf_tcp_ts_delta,
5499           { "Time since previous frame in this TCP stream", "tcp.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
5500             "Time delta from previous frame in this TCP stream", HFILL}},
5501
5502         { &hf_tcp_proc_src_uid,
5503           { "Source process user ID", "tcp.proc.srcuid", FT_UINT32, BASE_DEC, NULL, 0x0,
5504             NULL, HFILL}},
5505
5506         { &hf_tcp_proc_src_pid,
5507           { "Source process ID", "tcp.proc.srcpid", FT_UINT32, BASE_DEC, NULL, 0x0,
5508             NULL, HFILL}},
5509
5510         { &hf_tcp_proc_src_uname,
5511           { "Source process user name", "tcp.proc.srcuname", FT_STRING, BASE_NONE, NULL, 0x0,
5512             NULL, HFILL}},
5513
5514         { &hf_tcp_proc_src_cmd,
5515           { "Source process name", "tcp.proc.srccmd", FT_STRING, BASE_NONE, NULL, 0x0,
5516             "Source process command name", HFILL}},
5517
5518         { &hf_tcp_proc_dst_uid,
5519           { "Destination process user ID", "tcp.proc.dstuid", FT_UINT32, BASE_DEC, NULL, 0x0,
5520             NULL, HFILL}},
5521
5522         { &hf_tcp_proc_dst_pid,
5523           { "Destination process ID", "tcp.proc.dstpid", FT_UINT32, BASE_DEC, NULL, 0x0,
5524             NULL, HFILL}},
5525
5526         { &hf_tcp_proc_dst_uname,
5527           { "Destination process user name", "tcp.proc.dstuname", FT_STRING, BASE_NONE, NULL, 0x0,
5528             NULL, HFILL}},
5529
5530         { &hf_tcp_proc_dst_cmd,
5531           { "Destination process name", "tcp.proc.dstcmd", FT_STRING, BASE_NONE, NULL, 0x0,
5532             "Destination process command name", HFILL}},
5533
5534         { &hf_tcp_segment_data,
5535           { "TCP segment data", "tcp.segment_data", FT_BYTES, BASE_NONE, NULL, 0x0,
5536             "A data segment used in reassembly of a lower-level protocol", HFILL}}
5537     };
5538
5539     static gint *ett[] = {
5540         &ett_tcp,
5541         &ett_tcp_flags,
5542         &ett_tcp_option_type,
5543         &ett_tcp_options,
5544         &ett_tcp_option_timestamp,
5545         &ett_tcp_option_mptcp,
5546         &ett_tcp_option_wscale,
5547         &ett_tcp_option_sack,
5548         &ett_tcp_option_scps,
5549         &ett_tcp_option_scps_extended,
5550         &ett_tcp_option_user_to,
5551         &ett_tcp_option_exp,
5552         &ett_tcp_option_sack_perm,
5553         &ett_tcp_option_mss,
5554         &ett_tcp_opt_rvbd_probe,
5555         &ett_tcp_opt_rvbd_probe_flags,
5556         &ett_tcp_opt_rvbd_trpy,
5557         &ett_tcp_opt_rvbd_trpy_flags,
5558         &ett_tcp_analysis_faults,
5559         &ett_tcp_analysis,
5560         &ett_tcp_timestamps,
5561         &ett_tcp_segments,
5562         &ett_tcp_segment,
5563         &ett_tcp_checksum,
5564         &ett_tcp_process_info
5565     };
5566
5567     static const enum_val_t window_scaling_vals[] = {
5568         {"not-known",  "Not known",                  WindowScaling_NotKnown},
5569         {"0",          "0 (no scaling)",             WindowScaling_0},
5570         {"1",          "1 (multiply by 2)",          WindowScaling_1},
5571         {"2",          "2 (multiply by 4)",          WindowScaling_2},
5572         {"3",          "3 (multiply by 8)",          WindowScaling_3},
5573         {"4",          "4 (multiply by 16)",         WindowScaling_4},
5574         {"5",          "5 (multiply by 32)",         WindowScaling_5},
5575         {"6",          "6 (multiply by 64)",         WindowScaling_6},
5576         {"7",          "7 (multiply by 128)",        WindowScaling_7},
5577         {"8",          "8 (multiply by 256)",        WindowScaling_8},
5578         {"9",          "9 (multiply by 512)",        WindowScaling_9},
5579         {"10",         "10 (multiply by 1024)",      WindowScaling_10},
5580         {"11",         "11 (multiply by 2048)",      WindowScaling_11},
5581         {"12",         "12 (multiply by 4096)",      WindowScaling_12},
5582         {"13",         "13 (multiply by 8192)",      WindowScaling_13},
5583         {"14",         "14 (multiply by 16384)",     WindowScaling_14},
5584         {NULL, NULL, -1}
5585     };
5586
5587     static ei_register_info ei[] = {
5588         { &ei_tcp_opt_len_invalid, { "tcp.option.len.invalid", PI_SEQUENCE, PI_NOTE, "Invalid length for option", EXPFILL }},
5589         { &ei_tcp_analysis_retransmission, { "tcp.analysis.retransmission", PI_SEQUENCE, PI_NOTE, "This frame is a (suspected) retransmission", EXPFILL }},
5590         { &ei_tcp_analysis_fast_retransmission, { "tcp.analysis.fast_retransmission", PI_SEQUENCE, PI_NOTE, "This frame is a (suspected) fast retransmission", EXPFILL }},
5591         { &ei_tcp_analysis_spurious_retransmission, { "tcp.analysis.spurious_retransmission", PI_SEQUENCE, PI_NOTE, "This frame is a (suspected) spurious retransmission", EXPFILL }},
5592         { &ei_tcp_analysis_out_of_order, { "tcp.analysis.out_of_order", PI_SEQUENCE, PI_WARN, "This frame is a (suspected) out-of-order segment", EXPFILL }},
5593         { &ei_tcp_analysis_reused_ports, { "tcp.analysis.reused_ports", PI_SEQUENCE, PI_NOTE, "A new tcp session is started with the same ports as an earlier session in this trace", EXPFILL }},
5594         { &ei_tcp_analysis_lost_packet, { "tcp.analysis.lost_segment", PI_SEQUENCE, PI_WARN, "Previous segment not captured (common at capture start)", EXPFILL }},
5595         { &ei_tcp_analysis_ack_lost_packet, { "tcp.analysis.ack_lost_segment", PI_SEQUENCE, PI_WARN, "ACKed segment that wasn't captured (common at capture start)", EXPFILL }},
5596         { &ei_tcp_analysis_window_update, { "tcp.analysis.window_update", PI_SEQUENCE, PI_CHAT, "TCP window update", EXPFILL }},
5597         { &ei_tcp_analysis_window_full, { "tcp.analysis.window_full", PI_SEQUENCE, PI_WARN, "TCP transmission window is now completely full", EXPFILL }},
5598         { &ei_tcp_analysis_keep_alive, { "tcp.analysis.keep_alive", PI_SEQUENCE, PI_NOTE, "TCP keep-alive segment", EXPFILL }},
5599         { &ei_tcp_analysis_keep_alive_ack, { "tcp.analysis.keep_alive_ack", PI_SEQUENCE, PI_NOTE, "ACK to a TCP keep-alive segment", EXPFILL }},
5600         { &ei_tcp_analysis_duplicate_ack, { "tcp.analysis.duplicate_ack", PI_SEQUENCE, PI_NOTE, "Duplicate ACK", EXPFILL }},
5601         { &ei_tcp_analysis_zero_window_probe, { "tcp.analysis.zero_window_probe", PI_SEQUENCE, PI_NOTE, "TCP Zero Window Probe", EXPFILL }},
5602         { &ei_tcp_analysis_zero_window, { "tcp.analysis.zero_window", PI_SEQUENCE, PI_WARN, "TCP Zero Window segment", EXPFILL }},
5603         { &ei_tcp_analysis_zero_window_probe_ack, { "tcp.analysis.zero_window_probe_ack", PI_SEQUENCE, PI_NOTE, "ACK to a TCP Zero Window Probe", EXPFILL }},
5604         { &ei_tcp_scps_capable, { "tcp.analysis.zero_window_probe_ack", PI_SEQUENCE, PI_NOTE, "Connection establish request (SYN-ACK): SCPS Capabilities Negotiated", EXPFILL }},
5605         { &ei_tcp_option_snack_sequence, { "tcp.options.snack.sequence", PI_SEQUENCE, PI_NOTE, "SNACK Sequence", EXPFILL }},
5606         { &ei_tcp_short_segment, { "tcp.short_segment", PI_MALFORMED, PI_WARN, "Short segment", EXPFILL }},
5607         { &ei_tcp_ack_nonzero, { "tcp.ack.nonzero", PI_PROTOCOL, PI_NOTE, "The acknowledgment number field is nonzero while the ACK flag is not set", EXPFILL }},
5608         { &ei_tcp_connection_sack, { "tcp.connection.sack", PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK)", EXPFILL }},
5609         { &ei_tcp_connection_syn, { "tcp.connection.syn", PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN)", EXPFILL }},
5610         { &ei_tcp_connection_fin, { "tcp.connection.fin", PI_SEQUENCE, PI_CHAT, "Connection finish (FIN)", EXPFILL }},
5611         { &ei_tcp_connection_rst, { "tcp.connection.rst", PI_SEQUENCE, PI_CHAT, "Connection reset (RST)", EXPFILL }},
5612         { &ei_tcp_checksum_ffff, { "tcp.checksum.ffff", PI_CHECKSUM, PI_WARN, "TCP Checksum 0xffff instead of 0x0000 (see RFC 1624)", EXPFILL }},
5613         { &ei_tcp_checksum_bad, { "tcp.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
5614         { &ei_tcp_urgent_pointer_non_zero, { "tcp.urgent_pointer.non_zero", PI_PROTOCOL, PI_NOTE, "The urgent pointer field is nonzero while the URG flag is not set", EXPFILL }}
5615     };
5616
5617     static build_valid_func tcp_da_src_values[1] = {tcp_src_value};
5618     static build_valid_func tcp_da_dst_values[1] = {tcp_dst_value};
5619     static build_valid_func tcp_da_both_values[2] = {tcp_src_value, tcp_dst_value};
5620     static decode_as_value_t tcp_da_values[3] = {{tcp_src_prompt, 1, tcp_da_src_values}, {tcp_dst_prompt, 1, tcp_da_dst_values}, {tcp_both_prompt, 2, tcp_da_both_values}};
5621     static decode_as_t tcp_da = {"tcp", "Transport", "tcp.port", 3, 2, tcp_da_values, "TCP", "port(s) as",
5622                                  decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
5623
5624     module_t *tcp_module;
5625     expert_module_t* expert_tcp;
5626
5627     proto_tcp = proto_register_protocol("Transmission Control Protocol", "TCP", "tcp");
5628     register_dissector("tcp", dissect_tcp, proto_tcp);
5629     proto_register_field_array(proto_tcp, hf, array_length(hf));
5630     proto_register_subtree_array(ett, array_length(ett));
5631     expert_tcp = expert_register_protocol(proto_tcp);
5632     expert_register_field_array(expert_tcp, ei, array_length(ei));
5633
5634     /* subdissector code */
5635     subdissector_table = register_dissector_table("tcp.port",
5636         "TCP port", FT_UINT16, BASE_DEC);
5637     register_heur_dissector_list("tcp", &heur_subdissector_list);
5638
5639     /* Register configuration preferences */
5640     tcp_module = prefs_register_protocol(proto_tcp, NULL);
5641     prefs_register_bool_preference(tcp_module, "summary_in_tree",
5642         "Show TCP summary in protocol tree",
5643         "Whether the TCP summary line should be shown in the protocol tree",
5644         &tcp_summary_in_tree);
5645     prefs_register_bool_preference(tcp_module, "check_checksum",
5646         "Validate the TCP checksum if possible",
5647         "Whether to validate the TCP checksum or not.  "
5648         "(Invalid checksums will cause reassembly, if enabled, to fail.)",
5649         &tcp_check_checksum);
5650     prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
5651         "Allow subdissector to reassemble TCP streams",
5652         "Whether subdissector can request TCP streams to be reassembled",
5653         &tcp_desegment);
5654     prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
5655         "Analyze TCP sequence numbers",
5656         "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
5657         &tcp_analyze_seq);
5658     prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
5659         "Relative sequence numbers",
5660         "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
5661         "To use this option you must also enable \"Analyze TCP sequence numbers\". ",
5662         &tcp_relative_seq);
5663     prefs_register_enum_preference(tcp_module, "default_window_scaling",
5664         "Scaling factor to use when not available from capture",
5665         "Make the TCP dissector use this scaling factor for streams where the signalled scaling factor "
5666         "is not visible in the capture",
5667         &tcp_default_window_scaling, window_scaling_vals, FALSE);
5668
5669     /* Presumably a retired, unconditional version of what has been added back with the preference above... */
5670     prefs_register_obsolete_preference(tcp_module, "window_scaling");
5671
5672     prefs_register_bool_preference(tcp_module, "track_bytes_in_flight",
5673         "Track number of bytes in flight",
5674         "Make the TCP dissector track the number on un-ACKed bytes of data are in flight per packet. "
5675         "To use this option you must also enable \"Analyze TCP sequence numbers\". "
5676         "This takes a lot of memory but allows you to track how much data are in flight at a time and graphing it in io-graphs",
5677         &tcp_track_bytes_in_flight);
5678     prefs_register_bool_preference(tcp_module, "calculate_timestamps",
5679         "Calculate conversation timestamps",
5680         "Calculate timestamps relative to the first frame and the previous frame in the tcp conversation",
5681         &tcp_calculate_ts);
5682     prefs_register_bool_preference(tcp_module, "try_heuristic_first",
5683         "Try heuristic sub-dissectors first",
5684         "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
5685         &try_heuristic_first);
5686     prefs_register_bool_preference(tcp_module, "ignore_tcp_timestamps",
5687         "Ignore TCP Timestamps in summary",
5688         "Do not place the TCP Timestamps in the summary line",
5689         &tcp_ignore_timestamps);
5690
5691     prefs_register_bool_preference(tcp_module, "no_subdissector_on_error",
5692         "Do not call subdissectors for error packets",
5693         "Do not call any subdissectors for Retransmitted or OutOfOrder segments",
5694         &tcp_no_subdissector_on_error);
5695
5696     prefs_register_bool_preference(tcp_module, "dissect_experimental_options_with_magic",
5697         "TCP Experimental Options with a Magic Number",
5698         "Assume TCP Experimental Options (253, 254) have a Magic Number and use it for dissection",
5699         &tcp_exp_options_with_magic);
5700
5701     register_init_routine(tcp_init);
5702
5703     register_decode_as(&tcp_da);
5704 }
5705
5706 void
5707 proto_reg_handoff_tcp(void)
5708 {
5709     dissector_handle_t tcp_handle;
5710
5711     tcp_handle = find_dissector("tcp");
5712     dissector_add_uint("ip.proto", IP_PROTO_TCP, tcp_handle);
5713     data_handle = find_dissector("data");
5714     sport_handle = find_dissector("sport");
5715     tcp_tap = register_tap("tcp");
5716 }
5717
5718 /*
5719  * Editor modelines
5720  *
5721  * Local Variables:
5722  * c-basic-offset: 4
5723  * tab-width: 8
5724  * indent-tabs-mode: nil
5725  * End:
5726  *
5727  * ex: set shiftwidth=4 tabstop=8 expandtab:
5728  * :indentSize=4:tabSize=8:noTabs=true:
5729  */