1 /* packet-tcp.c
2  * Routines for TCP packet disassembly
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #include "config.h"
12 
13 #include <stdio.h>
14 #include <epan/packet.h>
15 #include <epan/capture_dissectors.h>
16 #include <epan/exceptions.h>
17 #include <epan/addr_resolv.h>
18 #include <epan/ipproto.h>
19 #include <epan/expert.h>
20 #include <epan/ip_opts.h>
21 #include <epan/follow.h>
22 #include <epan/prefs.h>
23 #include <epan/show_exception.h>
24 #include <epan/conversation_table.h>
25 #include <epan/conversation_filter.h>
26 #include <epan/sequence_analysis.h>
27 #include <epan/reassemble.h>
28 #include <epan/decode_as.h>
29 #include <epan/exported_pdu.h>
30 #include <epan/in_cksum.h>
31 #include <epan/proto_data.h>
32 
33 #include <wsutil/utf8_entities.h>
34 #include <wsutil/str_util.h>
35 #include <wsutil/wsgcrypt.h>
36 #include <wsutil/pint.h>
37 #include <wsutil/ws_assert.h>
38 
39 #include "packet-tcp.h"
40 #include "packet-ip.h"
41 #include "packet-icmp.h"
42 
43 void proto_register_tcp(void);
44 void proto_reg_handoff_tcp(void);
45 static void conversation_completeness_fill(gchar*, guint32);
46 
47 static int tcp_tap = -1;
48 static int tcp_follow_tap = -1;
49 static int mptcp_tap = -1;
50 static int exported_pdu_tap = -1;
51 
52 /* Place TCP summary in proto tree */
53 static gboolean tcp_summary_in_tree = TRUE;
54 
KEEP_32MSB_OF_GUINT64(guint64 nb)55 static inline guint64 KEEP_32MSB_OF_GUINT64(guint64 nb) {
56     return (nb >> 32) << 32;
57 }
58 
59 #define MPTCP_DSS_FLAG_DATA_ACK_PRESENT     0x01
60 #define MPTCP_DSS_FLAG_DATA_ACK_8BYTES      0x02
61 #define MPTCP_DSS_FLAG_MAPPING_PRESENT      0x04
62 #define MPTCP_DSS_FLAG_DSN_8BYTES           0x08
63 #define MPTCP_DSS_FLAG_DATA_FIN_PRESENT     0x10
64 
65 /*
66  * Flag to control whether to check the TCP checksum.
67  *
68  * In at least some Solaris network traces, there are packets with bad
69  * TCP checksums, but the traffic appears to indicate that the packets
70  * *were* received; the packets were probably sent by the host on which
71  * the capture was being done, on a network interface to which
72  * checksumming was offloaded, so that DLPI supplied an un-checksummed
73  * packet to the capture program but a checksummed packet got put onto
74  * the wire.
75  */
76 static gboolean tcp_check_checksum = FALSE;
77 
78 /*
79  * Window scaling values to be used when not known (set as a preference) */
80  enum scaling_window_value {
81   WindowScaling_NotKnown=-1,
82   WindowScaling_0=0,
83   WindowScaling_1,
84   WindowScaling_2,
85   WindowScaling_3,
86   WindowScaling_4,
87   WindowScaling_5,
88   WindowScaling_6,
89   WindowScaling_7,
90   WindowScaling_8,
91   WindowScaling_9,
92   WindowScaling_10,
93   WindowScaling_11,
94   WindowScaling_12,
95   WindowScaling_13,
96   WindowScaling_14
97 };
98 
99 /*
100  * Using enum instead of boolean make API easier
101  */
102 enum mptcp_dsn_conversion {
103     DSN_CONV_64_TO_32,
104     DSN_CONV_32_TO_64,
105     DSN_CONV_NONE
106 } ;
107 
108 #define MPTCP_TCPRST_FLAG_T_PRESENT     0x1
109 #define MPTCP_TCPRST_FLAG_W_PRESENT     0x2
110 #define MPTCP_TCPRST_FLAG_V_PRESENT     0x4
111 #define MPTCP_TCPRST_FLAG_U_PRESENT     0x8
112 
113 static const value_string mp_tcprst_reasons[] = {
114         { 0x0, "Unspecified error" },
115         { 0x1, "MPTCP-specific error" },
116         { 0x2, "Lack of resources" },
117         { 0x3, "Administratively prohibited" },
118         { 0x4, "Too much outstanding data" },
119         { 0x5, "Unacceptable performance" },
120         { 0x6, "Middlebox interference" },
121         { 0, NULL },
122 };
123 
124 static gint tcp_default_window_scaling = (gint)WindowScaling_NotKnown;
125 
126 static int proto_tcp = -1;
127 static int proto_ip = -1;
128 static int proto_icmp = -1;
129 
130 static int proto_tcp_option_nop = -1;
131 static int proto_tcp_option_eol = -1;
132 static int proto_tcp_option_timestamp = -1;
133 static int proto_tcp_option_mss = -1;
134 static int proto_tcp_option_wscale = -1;
135 static int proto_tcp_option_sack_perm = -1;
136 static int proto_tcp_option_sack = -1;
137 static int proto_tcp_option_echo = -1;
138 static int proto_tcp_option_echoreply = -1;
139 static int proto_tcp_option_cc = -1;
140 static int proto_tcp_option_cc_new = -1;
141 static int proto_tcp_option_cc_echo = -1;
142 static int proto_tcp_option_md5 = -1;
143 static int proto_tcp_option_ao = -1;
144 static int proto_tcp_option_scps = -1;
145 static int proto_tcp_option_snack = -1;
146 static int proto_tcp_option_scpsrec = -1;
147 static int proto_tcp_option_scpscor = -1;
148 static int proto_tcp_option_qs = -1;
149 static int proto_tcp_option_user_to = -1;
150 static int proto_tcp_option_tfo = -1;
151 static int proto_tcp_option_rvbd_probe = -1;
152 static int proto_tcp_option_rvbd_trpy = -1;
153 static int proto_tcp_option_exp = -1;
154 static int proto_tcp_option_unknown = -1;
155 static int proto_mptcp = -1;
156 
157 static int hf_tcp_srcport = -1;
158 static int hf_tcp_dstport = -1;
159 static int hf_tcp_port = -1;
160 static int hf_tcp_stream = -1;
161 static int hf_tcp_completeness = -1;
162 static int hf_tcp_seq = -1;
163 static int hf_tcp_seq_abs = -1;
164 static int hf_tcp_nxtseq = -1;
165 static int hf_tcp_ack = -1;
166 static int hf_tcp_ack_abs = -1;
167 static int hf_tcp_hdr_len = -1;
168 static int hf_tcp_flags = -1;
169 static int hf_tcp_flags_res = -1;
170 static int hf_tcp_flags_ns = -1;
171 static int hf_tcp_flags_cwr = -1;
172 static int hf_tcp_flags_ecn = -1;
173 static int hf_tcp_flags_urg = -1;
174 static int hf_tcp_flags_ack = -1;
175 static int hf_tcp_flags_push = -1;
176 static int hf_tcp_flags_reset = -1;
177 static int hf_tcp_flags_syn = -1;
178 static int hf_tcp_flags_fin = -1;
179 static int hf_tcp_flags_str = -1;
180 static int hf_tcp_window_size_value = -1;
181 static int hf_tcp_window_size = -1;
182 static int hf_tcp_window_size_scalefactor = -1;
183 static int hf_tcp_checksum = -1;
184 static int hf_tcp_checksum_status = -1;
185 static int hf_tcp_checksum_calculated = -1;
186 static int hf_tcp_len = -1;
187 static int hf_tcp_urgent_pointer = -1;
188 static int hf_tcp_analysis = -1;
189 static int hf_tcp_analysis_flags = -1;
190 static int hf_tcp_analysis_bytes_in_flight = -1;
191 static int hf_tcp_analysis_push_bytes_sent = -1;
192 static int hf_tcp_analysis_acks_frame = -1;
193 static int hf_tcp_analysis_ack_rtt = -1;
194 static int hf_tcp_analysis_first_rtt = -1;
195 static int hf_tcp_analysis_rto = -1;
196 static int hf_tcp_analysis_rto_frame = -1;
197 static int hf_tcp_analysis_duplicate_ack = -1;
198 static int hf_tcp_analysis_duplicate_ack_num = -1;
199 static int hf_tcp_analysis_duplicate_ack_frame = -1;
200 static int hf_tcp_continuation_to = -1;
201 static int hf_tcp_pdu_time = -1;
202 static int hf_tcp_pdu_size = -1;
203 static int hf_tcp_pdu_last_frame = -1;
204 static int hf_tcp_reassembled_in = -1;
205 static int hf_tcp_reassembled_length = -1;
206 static int hf_tcp_reassembled_data = -1;
207 static int hf_tcp_segments = -1;
208 static int hf_tcp_segment = -1;
209 static int hf_tcp_segment_overlap = -1;
210 static int hf_tcp_segment_overlap_conflict = -1;
211 static int hf_tcp_segment_multiple_tails = -1;
212 static int hf_tcp_segment_too_long_fragment = -1;
213 static int hf_tcp_segment_error = -1;
214 static int hf_tcp_segment_count = -1;
215 static int hf_tcp_options = -1;
216 static int hf_tcp_option_kind = -1;
217 static int hf_tcp_option_len = -1;
218 static int hf_tcp_option_mss_val = -1;
219 static int hf_tcp_option_wscale_shift = -1;
220 static int hf_tcp_option_wscale_multiplier = -1;
221 static int hf_tcp_option_sack_sle = -1;
222 static int hf_tcp_option_sack_sre = -1;
223 static int hf_tcp_option_sack_range_count = -1;
224 static int hf_tcp_option_sack_dsack_le = -1;
225 static int hf_tcp_option_sack_dsack_re = -1;
226 static int hf_tcp_option_echo = -1;
227 static int hf_tcp_option_timestamp_tsval = -1;
228 static int hf_tcp_option_timestamp_tsecr = -1;
229 static int hf_tcp_option_cc = -1;
230 static int hf_tcp_option_md5_digest = -1;
231 static int hf_tcp_option_ao_keyid = -1;
232 static int hf_tcp_option_ao_rnextkeyid = -1;
233 static int hf_tcp_option_ao_mac = -1;
234 static int hf_tcp_option_qs_rate = -1;
235 static int hf_tcp_option_qs_ttl_diff = -1;
236 static int hf_tcp_option_exp_data = -1;
237 static int hf_tcp_option_exp_magic_number = -1;
238 static int hf_tcp_option_unknown_payload = -1;
239 
240 static int hf_tcp_option_rvbd_probe_version1 = -1;
241 static int hf_tcp_option_rvbd_probe_version2 = -1;
242 static int hf_tcp_option_rvbd_probe_type1 = -1;
243 static int hf_tcp_option_rvbd_probe_type2 = -1;
244 static int hf_tcp_option_rvbd_probe_prober = -1;
245 static int hf_tcp_option_rvbd_probe_proxy = -1;
246 static int hf_tcp_option_rvbd_probe_client = -1;
247 static int hf_tcp_option_rvbd_probe_proxy_port = -1;
248 static int hf_tcp_option_rvbd_probe_appli_ver = -1;
249 static int hf_tcp_option_rvbd_probe_storeid = -1;
250 static int hf_tcp_option_rvbd_probe_flags = -1;
251 static int hf_tcp_option_rvbd_probe_flag_last_notify = -1;
252 static int hf_tcp_option_rvbd_probe_flag_server_connected = -1;
253 static int hf_tcp_option_rvbd_probe_flag_not_cfe = -1;
254 static int hf_tcp_option_rvbd_probe_flag_sslcert = -1;
255 static int hf_tcp_option_rvbd_probe_flag_probe_cache = -1;
256 
257 static int hf_tcp_option_rvbd_trpy_flags = -1;
258 static int hf_tcp_option_rvbd_trpy_flag_mode = -1;
259 static int hf_tcp_option_rvbd_trpy_flag_oob = -1;
260 static int hf_tcp_option_rvbd_trpy_flag_chksum = -1;
261 static int hf_tcp_option_rvbd_trpy_flag_fw_rst = -1;
262 static int hf_tcp_option_rvbd_trpy_flag_fw_rst_inner = -1;
263 static int hf_tcp_option_rvbd_trpy_flag_fw_rst_probe = -1;
264 static int hf_tcp_option_rvbd_trpy_src = -1;
265 static int hf_tcp_option_rvbd_trpy_dst = -1;
266 static int hf_tcp_option_rvbd_trpy_src_port = -1;
267 static int hf_tcp_option_rvbd_trpy_dst_port = -1;
268 static int hf_tcp_option_rvbd_trpy_client_port = -1;
269 
270 static int hf_tcp_option_mptcp_flags = -1;
271 static int hf_tcp_option_mptcp_backup_flag = -1;
272 static int hf_tcp_option_mptcp_checksum_flag = -1;
273 static int hf_tcp_option_mptcp_B_flag = -1;
274 static int hf_tcp_option_mptcp_C_flag = -1;
275 static int hf_tcp_option_mptcp_H_v0_flag = -1;
276 static int hf_tcp_option_mptcp_H_v1_flag = -1;
277 static int hf_tcp_option_mptcp_F_flag = -1;
278 static int hf_tcp_option_mptcp_m_flag = -1;
279 static int hf_tcp_option_mptcp_M_flag = -1;
280 static int hf_tcp_option_mptcp_a_flag = -1;
281 static int hf_tcp_option_mptcp_A_flag = -1;
282 static int hf_tcp_option_mptcp_U_flag = -1;
283 static int hf_tcp_option_mptcp_V_flag = -1;
284 static int hf_tcp_option_mptcp_W_flag = -1;
285 static int hf_tcp_option_mptcp_T_flag = -1;
286 static int hf_tcp_option_mptcp_tcprst_reason = -1;
287 static int hf_tcp_option_mptcp_reserved_v0_flag = -1;
288 static int hf_tcp_option_mptcp_reserved_v1_flag = -1;
289 static int hf_tcp_option_mptcp_subtype = -1;
290 static int hf_tcp_option_mptcp_version = -1;
291 static int hf_tcp_option_mptcp_reserved = -1;
292 static int hf_tcp_option_mptcp_address_id = -1;
293 static int hf_tcp_option_mptcp_recv_token = -1;
294 static int hf_tcp_option_mptcp_sender_key = -1;
295 static int hf_tcp_option_mptcp_recv_key = -1;
296 static int hf_tcp_option_mptcp_sender_rand = -1;
297 static int hf_tcp_option_mptcp_sender_trunc_hmac = -1;
298 static int hf_tcp_option_mptcp_sender_hmac = -1;
299 static int hf_tcp_option_mptcp_addaddr_trunc_hmac = -1;
300 static int hf_tcp_option_mptcp_data_ack_raw = -1;
301 static int hf_tcp_option_mptcp_data_seq_no_raw = -1;
302 static int hf_tcp_option_mptcp_subflow_seq_no = -1;
303 static int hf_tcp_option_mptcp_data_lvl_len = -1;
304 static int hf_tcp_option_mptcp_checksum = -1;
305 static int hf_tcp_option_mptcp_ipver = -1;
306 static int hf_tcp_option_mptcp_echo = -1;
307 static int hf_tcp_option_mptcp_ipv4 = -1;
308 static int hf_tcp_option_mptcp_ipv6 = -1;
309 static int hf_tcp_option_mptcp_port = -1;
310 static int hf_mptcp_expected_idsn = -1;
311 
312 static int hf_mptcp_dsn = -1;
313 static int hf_mptcp_rawdsn64 = -1;
314 static int hf_mptcp_dss_dsn = -1;
315 static int hf_mptcp_ack = -1;
316 static int hf_mptcp_stream = -1;
317 static int hf_mptcp_expected_token = -1;
318 static int hf_mptcp_analysis = -1;
319 static int hf_mptcp_analysis_master = -1;
320 static int hf_mptcp_analysis_subflows = -1;
321 static int hf_mptcp_number_of_removed_addresses = -1;
322 static int hf_mptcp_related_mapping = -1;
323 static int hf_mptcp_reinjection_of = -1;
324 static int hf_mptcp_reinjected_in = -1;
325 
326 
327 static int hf_tcp_option_fast_open_cookie_request = -1;
328 static int hf_tcp_option_fast_open_cookie = -1;
329 
330 static int hf_tcp_ts_relative = -1;
331 static int hf_tcp_ts_delta = -1;
332 static int hf_tcp_option_scps_vector = -1;
333 static int hf_tcp_option_scps_binding = -1;
334 static int hf_tcp_option_scps_binding_len = -1;
335 static int hf_tcp_scpsoption_flags_bets = -1;
336 static int hf_tcp_scpsoption_flags_snack1 = -1;
337 static int hf_tcp_scpsoption_flags_snack2 = -1;
338 static int hf_tcp_scpsoption_flags_compress = -1;
339 static int hf_tcp_scpsoption_flags_nlts = -1;
340 static int hf_tcp_scpsoption_flags_reserved = -1;
341 static int hf_tcp_scpsoption_connection_id = -1;
342 static int hf_tcp_option_snack_offset = -1;
343 static int hf_tcp_option_snack_size = -1;
344 static int hf_tcp_option_snack_le = -1;
345 static int hf_tcp_option_snack_re = -1;
346 static int hf_tcp_option_user_to_granularity = -1;
347 static int hf_tcp_option_user_to_val = -1;
348 static int hf_tcp_proc_src_uid = -1;
349 static int hf_tcp_proc_src_pid = -1;
350 static int hf_tcp_proc_src_uname = -1;
351 static int hf_tcp_proc_src_cmd = -1;
352 static int hf_tcp_proc_dst_uid = -1;
353 static int hf_tcp_proc_dst_pid = -1;
354 static int hf_tcp_proc_dst_uname = -1;
355 static int hf_tcp_proc_dst_cmd = -1;
356 static int hf_tcp_segment_data = -1;
357 static int hf_tcp_payload = -1;
358 static int hf_tcp_reset_cause = -1;
359 static int hf_tcp_fin_retransmission = -1;
360 static int hf_tcp_option_rvbd_probe_reserved = -1;
361 static int hf_tcp_option_scps_binding_data = -1;
362 
363 static gint ett_tcp = -1;
364 static gint ett_tcp_flags = -1;
365 static gint ett_tcp_options = -1;
366 static gint ett_tcp_option_timestamp = -1;
367 static gint ett_tcp_option_mss = -1;
368 static gint ett_tcp_option_wscale = -1;
369 static gint ett_tcp_option_sack = -1;
370 static gint ett_tcp_option_snack = -1;
371 static gint ett_tcp_option_scps = -1;
372 static gint ett_tcp_scpsoption_flags = -1;
373 static gint ett_tcp_option_scps_extended = -1;
374 static gint ett_tcp_option_user_to = -1;
375 static gint ett_tcp_option_exp = -1;
376 static gint ett_tcp_option_sack_perm = -1;
377 static gint ett_tcp_analysis = -1;
378 static gint ett_tcp_analysis_faults = -1;
379 static gint ett_tcp_timestamps = -1;
380 static gint ett_tcp_segments = -1;
381 static gint ett_tcp_segment  = -1;
382 static gint ett_tcp_checksum = -1;
383 static gint ett_tcp_process_info = -1;
384 static gint ett_tcp_option_mptcp = -1;
385 static gint ett_tcp_opt_rvbd_probe = -1;
386 static gint ett_tcp_opt_rvbd_probe_flags = -1;
387 static gint ett_tcp_opt_rvbd_trpy = -1;
388 static gint ett_tcp_opt_rvbd_trpy_flags = -1;
389 static gint ett_tcp_opt_echo = -1;
390 static gint ett_tcp_opt_cc = -1;
391 static gint ett_tcp_opt_md5 = -1;
392 static gint ett_tcp_opt_ao = -1;
393 static gint ett_tcp_opt_qs = -1;
394 static gint ett_tcp_opt_recbound = -1;
395 static gint ett_tcp_opt_scpscor = -1;
396 static gint ett_tcp_unknown_opt = -1;
397 static gint ett_tcp_option_other = -1;
398 static gint ett_mptcp_analysis = -1;
399 static gint ett_mptcp_analysis_subflows = -1;
400 
401 static expert_field ei_tcp_opt_len_invalid = EI_INIT;
402 static expert_field ei_tcp_analysis_retransmission = EI_INIT;
403 static expert_field ei_tcp_analysis_fast_retransmission = EI_INIT;
404 static expert_field ei_tcp_analysis_spurious_retransmission = EI_INIT;
405 static expert_field ei_tcp_analysis_out_of_order = EI_INIT;
406 static expert_field ei_tcp_analysis_reused_ports = EI_INIT;
407 static expert_field ei_tcp_analysis_lost_packet = EI_INIT;
408 static expert_field ei_tcp_analysis_ack_lost_packet = EI_INIT;
409 static expert_field ei_tcp_analysis_window_update = EI_INIT;
410 static expert_field ei_tcp_analysis_window_full = EI_INIT;
411 static expert_field ei_tcp_analysis_keep_alive = EI_INIT;
412 static expert_field ei_tcp_analysis_keep_alive_ack = EI_INIT;
413 static expert_field ei_tcp_analysis_duplicate_ack = EI_INIT;
414 static expert_field ei_tcp_analysis_zero_window_probe = EI_INIT;
415 static expert_field ei_tcp_analysis_zero_window = EI_INIT;
416 static expert_field ei_tcp_analysis_zero_window_probe_ack = EI_INIT;
417 static expert_field ei_tcp_analysis_tfo_syn = EI_INIT;
418 static expert_field ei_tcp_analysis_tfo_ack = EI_INIT;
419 static expert_field ei_tcp_analysis_tfo_ignored = EI_INIT;
420 static expert_field ei_tcp_scps_capable = EI_INIT;
421 static expert_field ei_tcp_option_sack_dsack = EI_INIT;
422 static expert_field ei_tcp_option_snack_sequence = EI_INIT;
423 static expert_field ei_tcp_option_wscale_shift_invalid = EI_INIT;
424 static expert_field ei_tcp_option_mss_absent = EI_INIT;
425 static expert_field ei_tcp_option_mss_present = EI_INIT;
426 static expert_field ei_tcp_short_segment = EI_INIT;
427 static expert_field ei_tcp_ack_nonzero = EI_INIT;
428 static expert_field ei_tcp_connection_synack = EI_INIT;
429 static expert_field ei_tcp_connection_syn = EI_INIT;
430 static expert_field ei_tcp_connection_fin = EI_INIT;
431 static expert_field ei_tcp_connection_rst = EI_INIT;
432 static expert_field ei_tcp_connection_fin_active = EI_INIT;
433 static expert_field ei_tcp_connection_fin_passive = EI_INIT;
434 static expert_field ei_tcp_checksum_ffff = EI_INIT;
435 static expert_field ei_tcp_checksum_bad = EI_INIT;
436 static expert_field ei_tcp_urgent_pointer_non_zero = EI_INIT;
437 static expert_field ei_tcp_suboption_malformed = EI_INIT;
438 static expert_field ei_tcp_nop = EI_INIT;
439 static expert_field ei_tcp_bogus_header_length = EI_INIT;
440 
441 /* static expert_field ei_mptcp_analysis_unexpected_idsn = EI_INIT; */
442 static expert_field ei_mptcp_analysis_echoed_key_mismatch = EI_INIT;
443 static expert_field ei_mptcp_analysis_missing_algorithm = EI_INIT;
444 static expert_field ei_mptcp_analysis_unsupported_algorithm = EI_INIT;
445 static expert_field ei_mptcp_infinite_mapping= EI_INIT;
446 static expert_field ei_mptcp_mapping_missing = EI_INIT;
447 /* static expert_field ei_mptcp_stream_incomplete = EI_INIT; */
448 /* static expert_field ei_mptcp_analysis_dsn_out_of_order = EI_INIT; */
449 
450 /* Some protocols such as encrypted DCE/RPCoverHTTP have dependencies
451  * from one PDU to the next PDU and require that they are called in sequence.
452  * These protocols would not be able to handle PDUs coming out of order
453  * or for example when a PDU is seen twice, like for retransmissions.
454  * This preference can be set for such protocols to make sure that we don't
455  * invoke the subdissectors for retransmitted or out-of-order segments.
456  */
457 static gboolean tcp_no_subdissector_on_error = TRUE;
458 
459 /*
460  * FF: (draft-ietf-tcpm-experimental-options-03)
461  * With this flag set we assume the option structure for experimental
462  * codepoints (253, 254) has a magic number field (first field after the
463  * Kind and Length).  The magic number is used to differentiate different
464  * experiments and thus will be used in data dissection.
465  */
466 static gboolean tcp_exp_options_with_magic = TRUE;
467 
468 /*
469  * This flag indicates which of Fast Retransmission or Out-of-Order
470  * interpretation should supersede when analyzing an ambiguous packet as
471  * things are not always clear. The user is authorized to change this
472  * behavior.
473  * When set, we keep the historical interpretation (Fast RT > OOO)
474  */
475 static gboolean tcp_fastrt_precedence = TRUE;
476 
477 /* Process info, currently discovered via IPFIX */
478 static gboolean tcp_display_process_info = FALSE;
479 
480 /*
481  *  TCP option
482  */
483 #define TCPOPT_NOP              1       /* Padding */
484 #define TCPOPT_EOL              0       /* End of options */
485 #define TCPOPT_MSS              2       /* Segment size negotiating */
486 #define TCPOPT_WINDOW           3       /* Window scaling */
487 #define TCPOPT_SACK_PERM        4       /* SACK Permitted */
488 #define TCPOPT_SACK             5       /* SACK Block */
489 #define TCPOPT_ECHO             6
490 #define TCPOPT_ECHOREPLY        7
491 #define TCPOPT_TIMESTAMP        8       /* Better RTT estimations/PAWS */
492 #define TCPOPT_CC               11
493 #define TCPOPT_CCNEW            12
494 #define TCPOPT_CCECHO           13
495 #define TCPOPT_MD5              19      /* RFC2385 */
496 #define TCPOPT_SCPS             20      /* SCPS Capabilities */
497 #define TCPOPT_SNACK            21      /* SCPS SNACK */
498 #define TCPOPT_RECBOUND         22      /* SCPS Record Boundary */
499 #define TCPOPT_CORREXP          23      /* SCPS Corruption Experienced */
500 #define TCPOPT_QS               27      /* RFC4782 Quick-Start Response */
501 #define TCPOPT_USER_TO          28      /* RFC5482 User Timeout Option */
502 #define TCPOPT_AO               29      /* RFC5925 The TCP Authentication Option */
503 #define TCPOPT_MPTCP            30      /* RFC6824 Multipath TCP */
504 #define TCPOPT_TFO              34      /* RFC7413 TCP Fast Open Cookie */
505 #define TCPOPT_EXP_FD           0xfd    /* Experimental, reserved */
506 #define TCPOPT_EXP_FE           0xfe    /* Experimental, reserved */
507 /* Non IANA registered option numbers */
508 #define TCPOPT_RVBD_PROBE       76      /* Riverbed probe option */
509 #define TCPOPT_RVBD_TRPY        78      /* Riverbed transparency option */
510 
511 /*
512  *     TCP option lengths
513  */
514 #define TCPOLEN_MSS            4
515 #define TCPOLEN_WINDOW         3
516 #define TCPOLEN_SACK_PERM      2
517 #define TCPOLEN_SACK_MIN       2
518 #define TCPOLEN_ECHO           6
519 #define TCPOLEN_ECHOREPLY      6
520 #define TCPOLEN_TIMESTAMP     10
521 #define TCPOLEN_CC             6
522 #define TCPOLEN_CCNEW          6
523 #define TCPOLEN_CCECHO         6
524 #define TCPOLEN_MD5           18
525 #define TCPOLEN_SCPS           4
526 #define TCPOLEN_SNACK          6
527 #define TCPOLEN_RECBOUND       2
528 #define TCPOLEN_CORREXP        2
529 #define TCPOLEN_QS             8
530 #define TCPOLEN_USER_TO        4
531 #define TCPOLEN_MPTCP_MIN      3
532 #define TCPOLEN_TFO_MIN        2
533 #define TCPOLEN_RVBD_PROBE_MIN 3
534 #define TCPOLEN_RVBD_TRPY_MIN 16
535 #define TCPOLEN_EXP_MIN        2
536 
537 /*
538  *     Multipath TCP subtypes
539  */
540 #define TCPOPT_MPTCP_MP_CAPABLE    0x0    /* Multipath TCP Multipath Capable */
541 #define TCPOPT_MPTCP_MP_JOIN       0x1    /* Multipath TCP Join Connection */
542 #define TCPOPT_MPTCP_DSS           0x2    /* Multipath TCP Data Sequence Signal */
543 #define TCPOPT_MPTCP_ADD_ADDR      0x3    /* Multipath TCP Add Address */
544 #define TCPOPT_MPTCP_REMOVE_ADDR   0x4    /* Multipath TCP Remove Address */
545 #define TCPOPT_MPTCP_MP_PRIO       0x5    /* Multipath TCP Change Subflow Priority */
546 #define TCPOPT_MPTCP_MP_FAIL       0x6    /* Multipath TCP Fallback */
547 #define TCPOPT_MPTCP_MP_FASTCLOSE  0x7    /* Multipath TCP Fast Close */
548 #define TCPOPT_MPTCP_MP_TCPRST     0x8    /* Multipath TCP Reset */
549 
550 /*
551  *     Conversation Completeness values
552  */
553 #define TCP_COMPLETENESS_SYNSENT    0x01  /* TCP SYN SENT */
554 #define TCP_COMPLETENESS_SYNACK     0x02  /* TCP SYN ACK  */
555 #define TCP_COMPLETENESS_ACK        0x04  /* TCP ACK      */
556 #define TCP_COMPLETENESS_DATA       0x08  /* TCP data     */
557 #define TCP_COMPLETENESS_FIN        0x10  /* TCP FIN      */
558 #define TCP_COMPLETENESS_RST        0x20  /* TCP RST      */
559 
560 static const true_false_string tcp_option_user_to_granularity = {
561   "Minutes", "Seconds"
562 };
563 
564 static const value_string tcp_option_kind_vs[] = {
565     { TCPOPT_EOL, "End of Option List" },
566     { TCPOPT_NOP, "No-Operation" },
567     { TCPOPT_MSS, "Maximum Segment Size" },
568     { TCPOPT_WINDOW, "Window Scale" },
569     { TCPOPT_SACK_PERM, "SACK Permitted" },
570     { TCPOPT_SACK, "SACK" },
571     { TCPOPT_ECHO, "Echo" },
572     { TCPOPT_ECHOREPLY, "Echo Reply" },
573     { TCPOPT_TIMESTAMP, "Time Stamp Option" },
574     { 9, "Partial Order Connection Permitted" },
575     { 10, "Partial Order Service Profile" },
576     { TCPOPT_CC, "CC" },
577     { TCPOPT_CCNEW, "CC.NEW" },
578     { TCPOPT_CCECHO, "CC.ECHO" },
579     { 14, "TCP Alternate Checksum Request" },
580     { 15, "TCP Alternate Checksum Data" },
581     { 16, "Skeeter" },
582     { 17, "Bubba" },
583     { 18, "Trailer Checksum Option" },
584     { TCPOPT_MD5, "MD5 Signature Option" },
585     { TCPOPT_SCPS, "SCPS Capabilities" },
586     { TCPOPT_SNACK, "Selective Negative Acknowledgements" },
587     { TCPOPT_RECBOUND, "Record Boundaries" },
588     { TCPOPT_CORREXP, "Corruption experienced" },
589     { 24, "SNAP" },
590     { 25, "Unassigned" },
591     { 26, "TCP Compression Filter" },
592     { TCPOPT_QS, "Quick-Start Response" },
593     { TCPOPT_USER_TO, "User Timeout Option" },
594     { TCPOPT_AO, "The TCP Authentication Option" },
595     { TCPOPT_MPTCP, "Multipath TCP" },
596     { TCPOPT_TFO, "TCP Fast Open Cookie" },
597     { TCPOPT_RVBD_PROBE, "Riverbed Probe" },
598     { TCPOPT_RVBD_TRPY, "Riverbed Transparency" },
599     { TCPOPT_EXP_FD, "RFC3692-style Experiment 1" },
600     { TCPOPT_EXP_FE, "RFC3692-style Experiment 2" },
601     { 0, NULL }
602 };
603 static value_string_ext tcp_option_kind_vs_ext = VALUE_STRING_EXT_INIT(tcp_option_kind_vs);
604 
605 /* not all of the hf_fields below make sense for TCP but we have to provide
606    them anyways to comply with the API (which was aimed for IP fragment
607    reassembly) */
608 static const fragment_items tcp_segment_items = {
609     &ett_tcp_segment,
610     &ett_tcp_segments,
611     &hf_tcp_segments,
612     &hf_tcp_segment,
613     &hf_tcp_segment_overlap,
614     &hf_tcp_segment_overlap_conflict,
615     &hf_tcp_segment_multiple_tails,
616     &hf_tcp_segment_too_long_fragment,
617     &hf_tcp_segment_error,
618     &hf_tcp_segment_count,
619     &hf_tcp_reassembled_in,
620     &hf_tcp_reassembled_length,
621     &hf_tcp_reassembled_data,
622     "Segments"
623 };
624 
625 
626 static const value_string mptcp_subtype_vs[] = {
627     { TCPOPT_MPTCP_MP_CAPABLE, "Multipath Capable" },
628     { TCPOPT_MPTCP_MP_JOIN, "Join Connection" },
629     { TCPOPT_MPTCP_DSS, "Data Sequence Signal" },
630     { TCPOPT_MPTCP_ADD_ADDR, "Add Address"},
631     { TCPOPT_MPTCP_REMOVE_ADDR, "Remove Address" },
632     { TCPOPT_MPTCP_MP_PRIO, "Change Subflow Priority" },
633     { TCPOPT_MPTCP_MP_FAIL, "TCP Fallback" },
634     { TCPOPT_MPTCP_MP_FASTCLOSE, "Fast Close" },
635     { TCPOPT_MPTCP_MP_TCPRST, "TCP Reset" },
636     { 0, NULL }
637 };
638 
639 static dissector_table_t subdissector_table;
640 static dissector_table_t tcp_option_table;
641 static heur_dissector_list_t heur_subdissector_list;
642 static dissector_handle_t data_handle;
643 static dissector_handle_t tcp_handle;
644 static dissector_handle_t sport_handle;
645 static dissector_handle_t tcp_opt_unknown_handle;
646 static guint32 tcp_stream_count;
647 static guint32 mptcp_stream_count;
648 
649 
650 
651 /*
652  * Maps an MPTCP token to a mptcp_analysis structure
653  * Collisions are not handled
654  */
655 static wmem_tree_t *mptcp_tokens = NULL;
656 
657 static int * const tcp_option_mptcp_capable_v0_flags[] = {
658   &hf_tcp_option_mptcp_checksum_flag,
659   &hf_tcp_option_mptcp_B_flag,
660   &hf_tcp_option_mptcp_H_v0_flag,
661   &hf_tcp_option_mptcp_reserved_v0_flag,
662   NULL
663 };
664 
665 static int * const tcp_option_mptcp_capable_v1_flags[] = {
666   &hf_tcp_option_mptcp_checksum_flag,
667   &hf_tcp_option_mptcp_B_flag,
668   &hf_tcp_option_mptcp_C_flag,
669   &hf_tcp_option_mptcp_H_v1_flag,
670   &hf_tcp_option_mptcp_reserved_v1_flag,
671   NULL
672 };
673 
674 static int * const tcp_option_mptcp_join_flags[] = {
675   &hf_tcp_option_mptcp_backup_flag,
676   NULL
677 };
678 
679 static int * const tcp_option_mptcp_dss_flags[] = {
680   &hf_tcp_option_mptcp_F_flag,
681   &hf_tcp_option_mptcp_m_flag,
682   &hf_tcp_option_mptcp_M_flag,
683   &hf_tcp_option_mptcp_a_flag,
684   &hf_tcp_option_mptcp_A_flag,
685   NULL
686 };
687 
688 static int * const tcp_option_mptcp_tcprst_flags[] = {
689   &hf_tcp_option_mptcp_U_flag,
690   &hf_tcp_option_mptcp_V_flag,
691   &hf_tcp_option_mptcp_W_flag,
692   &hf_tcp_option_mptcp_T_flag,
693   NULL
694 };
695 
696 static const unit_name_string units_64bit_version = { " (64bits version)", NULL };
697 
698 
699 static char *
tcp_flags_to_str(wmem_allocator_t * scope,const struct tcpheader * tcph)700 tcp_flags_to_str(wmem_allocator_t *scope, const struct tcpheader *tcph)
701 {
702     static const char flags[][4] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR", "NS" };
703     const int maxlength = 64; /* upper bounds, max 53B: 8 * 3 + 2 + strlen("Reserved") + 9 * 2 + 1 */
704 
705     char *pbuf;
706     char *buf;
707 
708     int i;
709 
710     buf = pbuf = (char *) wmem_alloc(scope, maxlength);
711     *pbuf = '\0';
712 
713     for (i = 0; i < 9; i++) {
714         if (tcph->th_flags & (1 << i)) {
715             if (buf[0])
716                 pbuf = g_stpcpy(pbuf, ", ");
717             pbuf = g_stpcpy(pbuf, flags[i]);
718         }
719     }
720 
721     if (tcph->th_flags & TH_RES) {
722         if (buf[0])
723             pbuf = g_stpcpy(pbuf, ", ");
724         g_stpcpy(pbuf, "Reserved");
725     }
726 
727     if (buf[0] == '\0')
728         g_stpcpy(pbuf, "<None>");
729 
730     return buf;
731 }
732 static char *
tcp_flags_to_str_first_letter(wmem_allocator_t * scope,const struct tcpheader * tcph)733 tcp_flags_to_str_first_letter(wmem_allocator_t *scope, const struct tcpheader *tcph)
734 {
735     wmem_strbuf_t *buf = wmem_strbuf_new(scope, "");
736     unsigned i;
737     const unsigned flags_count = 12;
738     const char first_letters[] = "RRRNCEUAPRSF";
739 
740     /* upper three bytes are marked as reserved ('R'). */
741     for (i = 0; i < flags_count; i++) {
742         if (((tcph->th_flags >> (flags_count - 1 - i)) & 1)) {
743             wmem_strbuf_append_c(buf, first_letters[i]);
744         } else {
745             wmem_strbuf_append(buf, UTF8_MIDDLE_DOT);
746         }
747     }
748 
749     return wmem_strbuf_finalize(buf);
750 }
751 
752 static void
tcp_src_prompt(packet_info * pinfo,gchar * result)753 tcp_src_prompt(packet_info *pinfo, gchar *result)
754 {
755     guint32 port = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_tcp_srcport, pinfo->curr_layer_num));
756 
757     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "source (%u%s)", port, UTF8_RIGHTWARDS_ARROW);
758 }
759 
760 static gpointer
tcp_src_value(packet_info * pinfo)761 tcp_src_value(packet_info *pinfo)
762 {
763     return p_get_proto_data(pinfo->pool, pinfo, hf_tcp_srcport, pinfo->curr_layer_num);
764 }
765 
766 static void
tcp_dst_prompt(packet_info * pinfo,gchar * result)767 tcp_dst_prompt(packet_info *pinfo, gchar *result)
768 {
769     guint32 port = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_tcp_dstport, pinfo->curr_layer_num));
770 
771     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "destination (%s%u)", UTF8_RIGHTWARDS_ARROW, port);
772 }
773 
774 static gpointer
tcp_dst_value(packet_info * pinfo)775 tcp_dst_value(packet_info *pinfo)
776 {
777     return p_get_proto_data(pinfo->pool, pinfo, hf_tcp_dstport, pinfo->curr_layer_num);
778 }
779 
780 static void
tcp_both_prompt(packet_info * pinfo,gchar * result)781 tcp_both_prompt(packet_info *pinfo, gchar *result)
782 {
783     guint32 srcport = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_tcp_srcport, pinfo->curr_layer_num)),
784             destport = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_tcp_dstport, pinfo->curr_layer_num));
785     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "both (%u%s%u)", srcport, UTF8_LEFT_RIGHT_ARROW, destport);
786 }
787 
tcp_conv_get_filter_type(conv_item_t * conv,conv_filter_type_e filter)788 static const char* tcp_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
789 {
790 
791     if (filter == CONV_FT_SRC_PORT)
792         return "tcp.srcport";
793 
794     if (filter == CONV_FT_DST_PORT)
795         return "tcp.dstport";
796 
797     if (filter == CONV_FT_ANY_PORT)
798         return "tcp.port";
799 
800     if(!conv) {
801         return CONV_FILTER_INVALID;
802     }
803 
804     if (filter == CONV_FT_SRC_ADDRESS) {
805         if (conv->src_address.type == AT_IPv4)
806             return "ip.src";
807         if (conv->src_address.type == AT_IPv6)
808             return "ipv6.src";
809     }
810 
811     if (filter == CONV_FT_DST_ADDRESS) {
812         if (conv->dst_address.type == AT_IPv4)
813             return "ip.dst";
814         if (conv->dst_address.type == AT_IPv6)
815             return "ipv6.dst";
816     }
817 
818     if (filter == CONV_FT_ANY_ADDRESS) {
819         if (conv->src_address.type == AT_IPv4)
820             return "ip.addr";
821         if (conv->src_address.type == AT_IPv6)
822             return "ipv6.addr";
823     }
824 
825     return CONV_FILTER_INVALID;
826 }
827 
828 static ct_dissector_info_t tcp_ct_dissector_info = {&tcp_conv_get_filter_type};
829 
830 static tap_packet_status
tcpip_conversation_packet(void * pct,packet_info * pinfo,epan_dissect_t * edt _U_,const void * vip)831 tcpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
832 {
833     conv_hash_t *hash = (conv_hash_t*) pct;
834     const struct tcpheader *tcphdr=(const struct tcpheader *)vip;
835 
836     add_conversation_table_data_with_conv_id(hash, &tcphdr->ip_src, &tcphdr->ip_dst, tcphdr->th_sport, tcphdr->th_dport, (conv_id_t) tcphdr->th_stream, 1, pinfo->fd->pkt_len,
837                                               &pinfo->rel_ts, &pinfo->abs_ts, &tcp_ct_dissector_info, ENDPOINT_TCP);
838 
839     return TAP_PACKET_REDRAW;
840 }
841 
842 static tap_packet_status
mptcpip_conversation_packet(void * pct,packet_info * pinfo,epan_dissect_t * edt _U_,const void * vip)843 mptcpip_conversation_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
844 {
845     conv_hash_t *hash = (conv_hash_t*) pct;
846     const struct tcp_analysis *tcpd=(const struct tcp_analysis *)vip;
847     const mptcp_meta_flow_t *meta=(const mptcp_meta_flow_t *)tcpd->fwd->mptcp_subflow->meta;
848 
849     add_conversation_table_data_with_conv_id(hash, &meta->ip_src, &meta->ip_dst,
850         meta->sport, meta->dport, (conv_id_t) tcpd->mptcp_analysis->stream, 1, pinfo->fd->pkt_len,
851                                               &pinfo->rel_ts, &pinfo->abs_ts, &tcp_ct_dissector_info, ENDPOINT_TCP);
852 
853     return TAP_PACKET_REDRAW;
854 }
855 
tcp_host_get_filter_type(hostlist_talker_t * host,conv_filter_type_e filter)856 static const char* tcp_host_get_filter_type(hostlist_talker_t* host, conv_filter_type_e filter)
857 {
858     if (filter == CONV_FT_SRC_PORT)
859         return "tcp.srcport";
860 
861     if (filter == CONV_FT_DST_PORT)
862         return "tcp.dstport";
863 
864     if (filter == CONV_FT_ANY_PORT)
865         return "tcp.port";
866 
867     if(!host) {
868         return CONV_FILTER_INVALID;
869     }
870 
871     if (filter == CONV_FT_SRC_ADDRESS) {
872         if (host->myaddress.type == AT_IPv4)
873             return "ip.src";
874         if (host->myaddress.type == AT_IPv6)
875             return "ipv6.src";
876     }
877 
878     if (filter == CONV_FT_DST_ADDRESS) {
879         if (host->myaddress.type == AT_IPv4)
880             return "ip.dst";
881         if (host->myaddress.type == AT_IPv6)
882             return "ipv6.dst";
883     }
884 
885     if (filter == CONV_FT_ANY_ADDRESS) {
886         if (host->myaddress.type == AT_IPv4)
887             return "ip.addr";
888         if (host->myaddress.type == AT_IPv6)
889             return "ipv6.addr";
890     }
891 
892     return CONV_FILTER_INVALID;
893 }
894 
895 static hostlist_dissector_info_t tcp_host_dissector_info = {&tcp_host_get_filter_type};
896 
897 static tap_packet_status
tcpip_hostlist_packet(void * pit,packet_info * pinfo,epan_dissect_t * edt _U_,const void * vip)898 tcpip_hostlist_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
899 {
900     conv_hash_t *hash = (conv_hash_t*) pit;
901     const struct tcpheader *tcphdr=(const struct tcpheader *)vip;
902 
903     /* Take two "add" passes per packet, adding for each direction, ensures that all
904     packets are counted properly (even if address is sending to itself)
905     XXX - this could probably be done more efficiently inside hostlist_table */
906     add_hostlist_table_data(hash, &tcphdr->ip_src, tcphdr->th_sport, TRUE, 1, pinfo->fd->pkt_len, &tcp_host_dissector_info, ENDPOINT_TCP);
907     add_hostlist_table_data(hash, &tcphdr->ip_dst, tcphdr->th_dport, FALSE, 1, pinfo->fd->pkt_len, &tcp_host_dissector_info, ENDPOINT_TCP);
908 
909     return TAP_PACKET_REDRAW;
910 }
911 
912 static gboolean
tcp_filter_valid(packet_info * pinfo)913 tcp_filter_valid(packet_info *pinfo)
914 {
915     return proto_is_frame_protocol(pinfo->layers, "tcp");
916 }
917 
918 static gchar*
tcp_build_filter(packet_info * pinfo)919 tcp_build_filter(packet_info *pinfo)
920 {
921     if( pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4 ) {
922         /* TCP over IPv4 */
923         return g_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
924             address_to_str(pinfo->pool, &pinfo->net_src),
925             address_to_str(pinfo->pool, &pinfo->net_dst),
926             pinfo->srcport, pinfo->destport );
927     }
928 
929     if( pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6 ) {
930         /* TCP over IPv6 */
931         return g_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
932             address_to_str(pinfo->pool, &pinfo->net_src),
933             address_to_str(pinfo->pool, &pinfo->net_dst),
934             pinfo->srcport, pinfo->destport );
935     }
936 
937     return NULL;
938 }
939 
940 /****************************************************************************/
941 /* whenever a TCP packet is seen by the tap listener */
942 /* Add a new tcp frame into the graph */
943 static tap_packet_status
tcp_seq_analysis_packet(void * ptr,packet_info * pinfo,epan_dissect_t * edt _U_,const void * tcp_info)944 tcp_seq_analysis_packet( void *ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *tcp_info)
945 {
946     seq_analysis_info_t *sainfo = (seq_analysis_info_t *) ptr;
947     const struct tcpheader *tcph = (const struct tcpheader *)tcp_info;
948     char* flags;
949     seq_analysis_item_t *sai = sequence_analysis_create_sai_with_addresses(pinfo, sainfo);
950 
951     if (!sai)
952         return TAP_PACKET_DONT_REDRAW;
953 
954     sai->frame_number = pinfo->num;
955 
956     sai->port_src=pinfo->srcport;
957     sai->port_dst=pinfo->destport;
958 
959     flags = tcp_flags_to_str(NULL, tcph);
960 
961     if ((tcph->th_have_seglen)&&(tcph->th_seglen!=0)){
962         sai->frame_label = g_strdup_printf("%s - Len: %u",flags, tcph->th_seglen);
963     }
964     else{
965         sai->frame_label = g_strdup(flags);
966     }
967 
968     wmem_free(NULL, flags);
969 
970     if (tcph->th_flags & TH_ACK)
971         sai->comment = g_strdup_printf("Seq = %u Ack = %u",tcph->th_seq, tcph->th_ack);
972     else
973         sai->comment = g_strdup_printf("Seq = %u",tcph->th_seq);
974 
975     sai->line_style = 1;
976     sai->conv_num = (guint16) tcph->th_stream;
977     sai->display = TRUE;
978 
979     g_queue_push_tail(sainfo->items, sai);
980 
981     return TAP_PACKET_REDRAW;
982 }
983 
984 
tcp_follow_conv_filter(epan_dissect_t * edt _U_,packet_info * pinfo,guint * stream,guint * sub_stream _U_)985 gchar *tcp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream _U_)
986 {
987     conversation_t *conv;
988     struct tcp_analysis *tcpd;
989 
990     if (((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) ||
991         (pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6))
992         && (conv=find_conversation_pinfo(pinfo, 0)) != NULL )
993     {
994         /* TCP over IPv4/6 */
995         tcpd=get_tcp_conversation_data(conv, pinfo);
996         if (tcpd == NULL)
997             return NULL;
998 
999         *stream = tcpd->stream;
1000         return g_strdup_printf("tcp.stream eq %u", tcpd->stream);
1001     }
1002 
1003     return NULL;
1004 }
1005 
tcp_follow_index_filter(guint stream,guint sub_stream _U_)1006 gchar *tcp_follow_index_filter(guint stream, guint sub_stream _U_)
1007 {
1008     return g_strdup_printf("tcp.stream eq %u", stream);
1009 }
1010 
tcp_follow_address_filter(address * src_addr,address * dst_addr,int src_port,int dst_port)1011 gchar *tcp_follow_address_filter(address *src_addr, address *dst_addr, int src_port, int dst_port)
1012 {
1013     const gchar  *ip_version = src_addr->type == AT_IPv6 ? "v6" : "";
1014     gchar         src_addr_str[WS_INET6_ADDRSTRLEN];
1015     gchar         dst_addr_str[WS_INET6_ADDRSTRLEN];
1016 
1017     address_to_str_buf(src_addr, src_addr_str, sizeof(src_addr_str));
1018     address_to_str_buf(dst_addr, dst_addr_str, sizeof(dst_addr_str));
1019 
1020     return g_strdup_printf("((ip%s.src eq %s and tcp.srcport eq %d) and "
1021                      "(ip%s.dst eq %s and tcp.dstport eq %d))"
1022                      " or "
1023                      "((ip%s.src eq %s and tcp.srcport eq %d) and "
1024                      "(ip%s.dst eq %s and tcp.dstport eq %d))",
1025                      ip_version, src_addr_str, src_port,
1026                      ip_version, dst_addr_str, dst_port,
1027                      ip_version, dst_addr_str, dst_port,
1028                      ip_version, src_addr_str, src_port);
1029 
1030 }
1031 
1032 typedef struct tcp_follow_tap_data
1033 {
1034     tvbuff_t *tvb;
1035     struct tcpheader* tcph;
1036     struct tcp_analysis *tcpd;
1037 
1038 } tcp_follow_tap_data_t;
1039 
1040 /*
1041  * Tries to apply segments from fragments list to the reconstructed payload.
1042  * Fragments that can be appended to the end of the payload will be applied (and
1043  * removed from the list). Fragments that should have been received (according
1044  * to the ack number) will also be appended to the payload (preceded by some
1045  * dummy data to mark packet loss if any).
1046  *
1047  * Returns TRUE if one fragment has been applied or FALSE if no more fragments
1048  * can be added the the payload (there might still be unacked fragments with
1049  * missing segments before them).
1050  */
1051 static gboolean
check_follow_fragments(follow_info_t * follow_info,gboolean is_server,guint32 acknowledged,guint32 packet_num,gboolean use_ack)1052 check_follow_fragments(follow_info_t *follow_info, gboolean is_server, guint32 acknowledged, guint32 packet_num, gboolean use_ack)
1053 {
1054     GList *fragment_entry;
1055     follow_record_t *fragment, *follow_record;
1056     guint32 lowest_seq = 0;
1057     gchar *dummy_str;
1058 
1059     fragment_entry = g_list_first(follow_info->fragments[is_server]);
1060     if (fragment_entry == NULL)
1061         return FALSE;
1062 
1063     fragment = (follow_record_t*)fragment_entry->data;
1064     lowest_seq = fragment->seq;
1065 
1066     for (; fragment_entry != NULL; fragment_entry = g_list_next(fragment_entry))
1067     {
1068         fragment = (follow_record_t*)fragment_entry->data;
1069 
1070         if( GT_SEQ(lowest_seq, fragment->seq) ) {
1071             lowest_seq = fragment->seq;
1072         }
1073 
1074         if( LT_SEQ(fragment->seq, follow_info->seq[is_server]) ) {
1075             guint32 newseq;
1076             /* this sequence number seems dated, but
1077                check the end to make sure it has no more
1078                info than we have already seen */
1079             newseq = fragment->seq + fragment->data->len;
1080             if( GT_SEQ(newseq, follow_info->seq[is_server]) ) {
1081                 guint32 new_pos;
1082 
1083                 /* this one has more than we have seen. let's get the
1084                    payload that we have not seen. This happens when
1085                    part of this frame has been retransmitted */
1086 
1087                 new_pos = follow_info->seq[is_server] - fragment->seq;
1088 
1089                 if ( fragment->data->len > new_pos ) {
1090                     guint32 new_frag_size = fragment->data->len - new_pos;
1091 
1092                     follow_record = g_new0(follow_record_t,1);
1093 
1094                     follow_record->is_server = is_server;
1095                     follow_record->packet_num = fragment->packet_num;
1096                     follow_record->abs_ts = fragment->abs_ts;
1097                     follow_record->seq = follow_info->seq[is_server] + new_frag_size;
1098 
1099                     follow_record->data = g_byte_array_append(g_byte_array_new(),
1100                                                               fragment->data->data + new_pos,
1101                                                               new_frag_size);
1102 
1103                     follow_info->payload = g_list_prepend(follow_info->payload, follow_record);
1104                 }
1105 
1106                 follow_info->seq[is_server] += (fragment->data->len - new_pos);
1107             }
1108 
1109             /* Remove the fragment from the list as the "new" part of it
1110              * has been processed or its data has been seen already in
1111              * another packet. */
1112             g_byte_array_free(fragment->data, TRUE);
1113             g_free(fragment);
1114             follow_info->fragments[is_server] = g_list_delete_link(follow_info->fragments[is_server], fragment_entry);
1115             return TRUE;
1116         }
1117 
1118         if( EQ_SEQ(fragment->seq, follow_info->seq[is_server]) ) {
1119             /* this fragment fits the stream */
1120             if( fragment->data->len > 0 ) {
1121                 follow_info->payload = g_list_prepend(follow_info->payload, fragment);
1122             }
1123 
1124             follow_info->seq[is_server] += fragment->data->len;
1125             follow_info->fragments[is_server] = g_list_delete_link(follow_info->fragments[is_server], fragment_entry);
1126             return TRUE;
1127         }
1128     }
1129 
1130     if( use_ack && GT_SEQ(acknowledged, lowest_seq) ) {
1131         /* There are frames missing in the capture file that were seen
1132          * by the receiving host. Add dummy stream chunk with the data
1133          * "[xxx bytes missing in capture file]".
1134          */
1135         dummy_str = g_strdup_printf("[%d bytes missing in capture file]",
1136                         (int)(lowest_seq - follow_info->seq[is_server]) );
1137         // XXX the dummy replacement could be larger than the actual missing bytes.
1138 
1139         follow_record = g_new0(follow_record_t,1);
1140 
1141         follow_record->data = g_byte_array_append(g_byte_array_new(),
1142                                                   (guchar*)dummy_str,
1143                                                   (guint)strlen(dummy_str)+1);
1144         g_free(dummy_str);
1145         follow_record->is_server = is_server;
1146         follow_record->packet_num = packet_num;
1147         follow_record->seq = lowest_seq;
1148 
1149         follow_info->seq[is_server] = lowest_seq;
1150         follow_info->payload = g_list_prepend(follow_info->payload, follow_record);
1151         return TRUE;
1152     }
1153 
1154     return FALSE;
1155 }
1156 
1157 static tap_packet_status
follow_tcp_tap_listener(void * tapdata,packet_info * pinfo,epan_dissect_t * edt _U_,const void * data)1158 follow_tcp_tap_listener(void *tapdata, packet_info *pinfo,
1159                       epan_dissect_t *edt _U_, const void *data)
1160 {
1161     follow_record_t *follow_record;
1162     follow_info_t *follow_info = (follow_info_t *)tapdata;
1163     const tcp_follow_tap_data_t *follow_data = (const tcp_follow_tap_data_t *)data;
1164     gboolean is_server;
1165     guint32 sequence = follow_data->tcph->th_seq;
1166     guint32 length = follow_data->tcph->th_seglen;
1167     guint32 data_offset = 0;
1168     guint32 data_length = tvb_captured_length(follow_data->tvb);
1169 
1170     if (follow_data->tcph->th_flags & TH_SYN) {
1171         sequence++;
1172     }
1173 
1174     if (follow_info->client_port == 0) {
1175         follow_info->client_port = pinfo->srcport;
1176         copy_address(&follow_info->client_ip, &pinfo->src);
1177         follow_info->server_port = pinfo->destport;
1178         copy_address(&follow_info->server_ip, &pinfo->dst);
1179     }
1180 
1181     is_server = !(addresses_equal(&follow_info->client_ip, &pinfo->src) && follow_info->client_port == pinfo->srcport);
1182 
1183    /* Check whether this frame ACKs fragments in flow from the other direction.
1184     * This happens when frames are not in the capture file, but were actually
1185     * seen by the receiving host (Fixes bug 592).
1186     */
1187     if (follow_info->fragments[!is_server] != NULL) {
1188         while (check_follow_fragments(follow_info, !is_server, follow_data->tcph->th_ack, pinfo->fd->num, TRUE));
1189     }
1190 
1191     /*
1192      * If this is the first segment of this stream, initialize the next expected
1193      * sequence number. If there is any data, it will be added below.
1194      */
1195     if (follow_info->bytes_written[is_server] == 0 && follow_info->seq[is_server] == 0) {
1196         follow_info->seq[is_server] = sequence;
1197     }
1198 
1199     /* We have already seen this src (and received some segments), let's figure
1200      * out whether this segment extends the stream or overlaps a previous gap. */
1201     if (LT_SEQ(sequence, follow_info->seq[is_server])) {
1202         /* This sequence number seems dated, but check the end in case it was a
1203          * retransmission with more data. */
1204         guint32 nextseq = sequence + length;
1205         if (GT_SEQ(nextseq, follow_info->seq[is_server])) {
1206             /* The begin of the segment was already seen, try to add the
1207              * remaining data that we have not seen to the payload. */
1208             data_offset = follow_info->seq[is_server] - sequence;
1209             if (data_length <= data_offset) {
1210                 data_length = 0;
1211             } else {
1212                 data_length -= data_offset;
1213             }
1214 
1215             sequence = follow_info->seq[is_server];
1216             length = nextseq - follow_info->seq[is_server];
1217         }
1218     }
1219     /*
1220      * Ignore segments that have no new data (either because it was empty, or
1221      * because it was fully overlapping with previously received data).
1222      */
1223     if (data_length == 0 || LT_SEQ(sequence, follow_info->seq[is_server])) {
1224         return TAP_PACKET_DONT_REDRAW;
1225     }
1226 
1227     follow_record = g_new0(follow_record_t, 1);
1228     follow_record->is_server = is_server;
1229     follow_record->packet_num = pinfo->fd->num;
1230     follow_record->abs_ts = pinfo->fd->abs_ts;
1231     follow_record->seq = sequence;  /* start of fragment, used by check_follow_fragments. */
1232     follow_record->data = g_byte_array_append(g_byte_array_new(),
1233                                               tvb_get_ptr(follow_data->tvb, data_offset, data_length),
1234                                               data_length);
1235 
1236     if (EQ_SEQ(sequence, follow_info->seq[is_server])) {
1237         /* The segment overlaps or extends the previous end of stream. */
1238         follow_info->seq[is_server] += length;
1239         follow_info->bytes_written[is_server] += follow_record->data->len;
1240         follow_info->payload = g_list_prepend(follow_info->payload, follow_record);
1241 
1242         /* done with the packet, see if it caused a fragment to fit */
1243         while(check_follow_fragments(follow_info, is_server, 0, pinfo->fd->num, FALSE));
1244     } else {
1245         /* Out of order packet (more preceding segments are expected). */
1246         follow_info->fragments[is_server] = g_list_append(follow_info->fragments[is_server], follow_record);
1247     }
1248     return TAP_PACKET_DONT_REDRAW;
1249 }
1250 
1251 #define EXP_PDU_TCP_INFO_DATA_LEN   19
1252 #define EXP_PDU_TCP_INFO_VERSION    1
1253 
exp_pdu_tcp_dissector_data_size(packet_info * pinfo _U_,void * data _U_)1254 static int exp_pdu_tcp_dissector_data_size(packet_info *pinfo _U_, void* data _U_)
1255 {
1256     return EXP_PDU_TCP_INFO_DATA_LEN+4;
1257 }
1258 
exp_pdu_tcp_dissector_data_populate_data(packet_info * pinfo _U_,void * data,guint8 * tlv_buffer,guint32 buffer_size _U_)1259 static int exp_pdu_tcp_dissector_data_populate_data(packet_info *pinfo _U_, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
1260 {
1261     struct tcpinfo* dissector_data = (struct tcpinfo*)data;
1262 
1263     phton16(&tlv_buffer[0], EXP_PDU_TAG_TCP_INFO_DATA);
1264     phton16(&tlv_buffer[2], EXP_PDU_TCP_INFO_DATA_LEN); /* tag length */
1265     phton16(&tlv_buffer[4], EXP_PDU_TCP_INFO_VERSION);
1266     phton32(&tlv_buffer[6], dissector_data->seq);
1267     phton32(&tlv_buffer[10], dissector_data->nxtseq);
1268     phton32(&tlv_buffer[14], dissector_data->lastackseq);
1269     tlv_buffer[18] = dissector_data->is_reassembled;
1270     phton16(&tlv_buffer[19], dissector_data->flags);
1271     phton16(&tlv_buffer[21], dissector_data->urgent_pointer);
1272 
1273     return exp_pdu_tcp_dissector_data_size(pinfo, data);
1274 }
1275 
1276 static void
handle_export_pdu_dissection_table(packet_info * pinfo,tvbuff_t * tvb,guint32 port,struct tcpinfo * tcpinfo)1277 handle_export_pdu_dissection_table(packet_info *pinfo, tvbuff_t *tvb, guint32 port, struct tcpinfo *tcpinfo)
1278 {
1279     if (have_tap_listener(exported_pdu_tap)) {
1280         exp_pdu_data_item_t exp_pdu_data_table_value = {exp_pdu_data_dissector_table_num_value_size, exp_pdu_data_dissector_table_num_value_populate_data, NULL};
1281         exp_pdu_data_item_t exp_pdu_data_dissector_data = {exp_pdu_tcp_dissector_data_size, exp_pdu_tcp_dissector_data_populate_data, NULL};
1282         const exp_pdu_data_item_t *tcp_exp_pdu_items[] = {
1283             &exp_pdu_data_src_ip,
1284             &exp_pdu_data_dst_ip,
1285             &exp_pdu_data_port_type,
1286             &exp_pdu_data_src_port,
1287             &exp_pdu_data_dst_port,
1288             &exp_pdu_data_orig_frame_num,
1289             &exp_pdu_data_table_value,
1290             &exp_pdu_data_dissector_data,
1291             NULL
1292         };
1293 
1294         exp_pdu_data_t *exp_pdu_data;
1295 
1296         exp_pdu_data_table_value.data = GUINT_TO_POINTER(port);
1297         exp_pdu_data_dissector_data.data = tcpinfo;
1298 
1299         exp_pdu_data = export_pdu_create_tags(pinfo, "tcp.port", EXP_PDU_TAG_DISSECTOR_TABLE_NAME, tcp_exp_pdu_items);
1300         exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
1301         exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
1302         exp_pdu_data->pdu_tvb = tvb;
1303 
1304         tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
1305     }
1306 }
1307 
1308 static void
handle_export_pdu_heuristic(packet_info * pinfo,tvbuff_t * tvb,heur_dtbl_entry_t * hdtbl_entry,struct tcpinfo * tcpinfo)1309 handle_export_pdu_heuristic(packet_info *pinfo, tvbuff_t *tvb, heur_dtbl_entry_t *hdtbl_entry, struct tcpinfo *tcpinfo)
1310 {
1311     exp_pdu_data_t *exp_pdu_data = NULL;
1312 
1313     if (have_tap_listener(exported_pdu_tap)) {
1314         if ((!hdtbl_entry->enabled) ||
1315             (hdtbl_entry->protocol != NULL && !proto_is_protocol_enabled(hdtbl_entry->protocol))) {
1316             exp_pdu_data = export_pdu_create_common_tags(pinfo, "data", EXP_PDU_TAG_PROTO_NAME);
1317         } else if (hdtbl_entry->protocol != NULL) {
1318             exp_pdu_data_item_t exp_pdu_data_dissector_data = {exp_pdu_tcp_dissector_data_size, exp_pdu_tcp_dissector_data_populate_data, NULL};
1319             const exp_pdu_data_item_t *tcp_exp_pdu_items[] = {
1320                 &exp_pdu_data_src_ip,
1321                 &exp_pdu_data_dst_ip,
1322                 &exp_pdu_data_port_type,
1323                 &exp_pdu_data_src_port,
1324                 &exp_pdu_data_dst_port,
1325                 &exp_pdu_data_orig_frame_num,
1326                 &exp_pdu_data_dissector_data,
1327                 NULL
1328             };
1329 
1330             exp_pdu_data_dissector_data.data = tcpinfo;
1331 
1332             exp_pdu_data = export_pdu_create_tags(pinfo, hdtbl_entry->short_name, EXP_PDU_TAG_HEUR_PROTO_NAME, tcp_exp_pdu_items);
1333         }
1334 
1335         if (exp_pdu_data != NULL) {
1336             exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
1337             exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
1338             exp_pdu_data->pdu_tvb = tvb;
1339 
1340             tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
1341         }
1342     }
1343 }
1344 
1345 static void
handle_export_pdu_conversation(packet_info * pinfo,tvbuff_t * tvb,int src_port,int dst_port,struct tcpinfo * tcpinfo)1346 handle_export_pdu_conversation(packet_info *pinfo, tvbuff_t *tvb, int src_port, int dst_port, struct tcpinfo *tcpinfo)
1347 {
1348     if (have_tap_listener(exported_pdu_tap)) {
1349         conversation_t *conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, ENDPOINT_TCP, src_port, dst_port, 0);
1350         if (conversation != NULL)
1351         {
1352             dissector_handle_t handle = (dissector_handle_t)wmem_tree_lookup32_le(conversation->dissector_tree, pinfo->num);
1353             if (handle != NULL)
1354             {
1355                 exp_pdu_data_item_t exp_pdu_data_dissector_data = {exp_pdu_tcp_dissector_data_size, exp_pdu_tcp_dissector_data_populate_data, NULL};
1356                 const exp_pdu_data_item_t *tcp_exp_pdu_items[] = {
1357                     &exp_pdu_data_src_ip,
1358                     &exp_pdu_data_dst_ip,
1359                     &exp_pdu_data_port_type,
1360                     &exp_pdu_data_src_port,
1361                     &exp_pdu_data_dst_port,
1362                     &exp_pdu_data_orig_frame_num,
1363                     &exp_pdu_data_dissector_data,
1364                     NULL
1365                 };
1366 
1367                 exp_pdu_data_t *exp_pdu_data;
1368 
1369                 exp_pdu_data_dissector_data.data = tcpinfo;
1370 
1371                 exp_pdu_data = export_pdu_create_tags(pinfo, dissector_handle_get_dissector_name(handle), EXP_PDU_TAG_PROTO_NAME, tcp_exp_pdu_items);
1372                 exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
1373                 exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
1374                 exp_pdu_data->pdu_tvb = tvb;
1375 
1376                 tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
1377             }
1378         }
1379     }
1380 }
1381 
1382 /*
1383  * display the TCP Conversation Completeness
1384  * we of course pay much attention on complete conversations but also incomplete ones which
1385  * have a regular start, as in practice we are often looking for such thing
1386  */
conversation_completeness_fill(gchar * buf,guint32 value)1387 static void conversation_completeness_fill(gchar *buf, guint32 value)
1388 {
1389     switch(value) {
1390         case TCP_COMPLETENESS_SYNSENT:
1391             g_snprintf(buf, ITEM_LABEL_LENGTH, "Incomplete, SYN_SENT (%u)", value);
1392             break;
1393         case (TCP_COMPLETENESS_SYNSENT|
1394               TCP_COMPLETENESS_SYNACK):
1395             g_snprintf(buf, ITEM_LABEL_LENGTH, "Incomplete, CLIENT_ESTABLISHED (%u)", value);
1396             break;
1397         case (TCP_COMPLETENESS_SYNSENT|
1398               TCP_COMPLETENESS_SYNACK|
1399               TCP_COMPLETENESS_ACK):
1400             g_snprintf(buf, ITEM_LABEL_LENGTH, "Incomplete, ESTABLISHED (%u)", value);
1401             break;
1402         case (TCP_COMPLETENESS_SYNSENT|
1403               TCP_COMPLETENESS_SYNACK|
1404               TCP_COMPLETENESS_ACK|
1405               TCP_COMPLETENESS_DATA):
1406             g_snprintf(buf, ITEM_LABEL_LENGTH, "Incomplete, DATA (%u)", value);
1407             break;
1408         case (TCP_COMPLETENESS_SYNSENT|
1409               TCP_COMPLETENESS_SYNACK|
1410               TCP_COMPLETENESS_ACK|
1411               TCP_COMPLETENESS_DATA|
1412               TCP_COMPLETENESS_FIN):
1413         case (TCP_COMPLETENESS_SYNSENT|
1414               TCP_COMPLETENESS_SYNACK|
1415               TCP_COMPLETENESS_ACK|
1416               TCP_COMPLETENESS_DATA|
1417               TCP_COMPLETENESS_RST):
1418         case (TCP_COMPLETENESS_SYNSENT|
1419               TCP_COMPLETENESS_SYNACK|
1420               TCP_COMPLETENESS_ACK|
1421               TCP_COMPLETENESS_DATA|
1422               TCP_COMPLETENESS_FIN|
1423               TCP_COMPLETENESS_RST):
1424             g_snprintf(buf, ITEM_LABEL_LENGTH, "Complete, WITH_DATA (%u)", value);
1425             break;
1426         case (TCP_COMPLETENESS_SYNSENT|
1427               TCP_COMPLETENESS_SYNACK|
1428               TCP_COMPLETENESS_ACK|
1429               TCP_COMPLETENESS_FIN):
1430         case (TCP_COMPLETENESS_SYNSENT|
1431               TCP_COMPLETENESS_SYNACK|
1432               TCP_COMPLETENESS_ACK|
1433               TCP_COMPLETENESS_RST):
1434         case (TCP_COMPLETENESS_SYNSENT|
1435               TCP_COMPLETENESS_SYNACK|
1436               TCP_COMPLETENESS_ACK|
1437               TCP_COMPLETENESS_FIN|
1438               TCP_COMPLETENESS_RST):
1439             g_snprintf(buf, ITEM_LABEL_LENGTH, "Complete, NO_DATA (%u)", value);
1440             break;
1441         default:
1442             g_snprintf(buf, ITEM_LABEL_LENGTH, "Incomplete (%u)", value);
1443             break;
1444     }
1445 }
1446 
1447 /* TCP structs and definitions */
1448 
1449 /* **************************************************************************
1450  * RTT, relative sequence numbers, window scaling & etc.
1451  * **************************************************************************/
1452 static gboolean tcp_analyze_seq           = TRUE;
1453 static gboolean tcp_relative_seq          = TRUE;
1454 static gboolean tcp_track_bytes_in_flight = TRUE;
1455 static gboolean tcp_bif_seq_based         = FALSE;
1456 static gboolean tcp_calculate_ts          = TRUE;
1457 
1458 static gboolean tcp_analyze_mptcp                   = TRUE;
1459 static gboolean mptcp_relative_seq                  = TRUE;
1460 static gboolean mptcp_analyze_mappings              = FALSE;
1461 static gboolean mptcp_intersubflows_retransmission  = FALSE;
1462 
1463 
1464 #define TCP_A_RETRANSMISSION          0x0001
1465 #define TCP_A_LOST_PACKET             0x0002
1466 #define TCP_A_ACK_LOST_PACKET         0x0004
1467 #define TCP_A_KEEP_ALIVE              0x0008
1468 #define TCP_A_DUPLICATE_ACK           0x0010
1469 #define TCP_A_ZERO_WINDOW             0x0020
1470 #define TCP_A_ZERO_WINDOW_PROBE       0x0040
1471 #define TCP_A_ZERO_WINDOW_PROBE_ACK   0x0080
1472 #define TCP_A_KEEP_ALIVE_ACK          0x0100
1473 #define TCP_A_OUT_OF_ORDER            0x0200
1474 #define TCP_A_FAST_RETRANSMISSION     0x0400
1475 #define TCP_A_WINDOW_UPDATE           0x0800
1476 #define TCP_A_WINDOW_FULL             0x1000
1477 #define TCP_A_REUSED_PORTS            0x2000
1478 #define TCP_A_SPURIOUS_RETRANSMISSION 0x4000
1479 
1480 /* Static TCP flags. Set in tcp_flow_t:static_flags */
1481 #define TCP_S_BASE_SEQ_SET 0x01
1482 #define TCP_S_SAW_SYN      0x03
1483 #define TCP_S_SAW_SYNACK   0x05
1484 
1485 
1486 /* Describe the fields sniffed and set in mptcp_meta_flow_t:static_flags */
1487 #define MPTCP_META_HAS_BASE_DSN_MSB  0x01
1488 #define MPTCP_META_HAS_KEY  0x03
1489 #define MPTCP_META_HAS_TOKEN  0x04
1490 #define MPTCP_META_HAS_ADDRESSES  0x08
1491 
1492 /* Describe the fields sniffed and set in mptcp_meta_flow_t:static_flags */
1493 #define MPTCP_SUBFLOW_HAS_NONCE 0x01
1494 #define MPTCP_SUBFLOW_HAS_ADDRESS_ID 0x02
1495 
1496 /* MPTCP meta analysis related */
1497 #define MPTCP_META_CHECKSUM_REQUIRED   0x0002
1498 
1499 /* if we have no key for this connection, some conversion become impossible,
1500  * thus return false
1501  */
1502 static
1503 gboolean
mptcp_convert_dsn(guint64 dsn,mptcp_meta_flow_t * meta,enum mptcp_dsn_conversion conv,gboolean relative,guint64 * result)1504 mptcp_convert_dsn(guint64 dsn, mptcp_meta_flow_t *meta, enum mptcp_dsn_conversion conv, gboolean relative, guint64 *result ) {
1505 
1506     *result = dsn;
1507 
1508     /* if relative is set then we need the 64 bits version anyway
1509      * we assume no wrapping was done on the 32 lsb so this may be wrong for elphant flows
1510      */
1511     if(conv == DSN_CONV_32_TO_64 || relative) {
1512 
1513         if(!(meta->static_flags & MPTCP_META_HAS_BASE_DSN_MSB)) {
1514             /* can't do those without the expected_idsn based on the key */
1515             return FALSE;
1516         }
1517     }
1518 
1519     if(conv == DSN_CONV_32_TO_64) {
1520         *result = KEEP_32MSB_OF_GUINT64(meta->base_dsn) | dsn;
1521     }
1522 
1523     if(relative) {
1524         *result -= meta->base_dsn;
1525     }
1526 
1527     if(conv == DSN_CONV_64_TO_32) {
1528         *result = (guint32) *result;
1529     }
1530 
1531     return TRUE;
1532 }
1533 
1534 
1535 static void
1536 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
1537     proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
1538     guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
1539     struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo);
1540 
1541 
1542 static struct tcp_analysis *
init_tcp_conversation_data(packet_info * pinfo,int direction)1543 init_tcp_conversation_data(packet_info *pinfo, int direction)
1544 {
1545     struct tcp_analysis *tcpd;
1546 
1547     /* Initialize the tcp protocol data structure to add to the tcp conversation */
1548     tcpd=wmem_new0(wmem_file_scope(), struct tcp_analysis);
1549     tcpd->flow1.win_scale = (direction >= 0) ? pinfo->src_win_scale : pinfo->dst_win_scale;
1550     tcpd->flow1.window = G_MAXUINT32;
1551     tcpd->flow1.multisegment_pdus=wmem_tree_new(wmem_file_scope());
1552 
1553     tcpd->flow2.window = G_MAXUINT32;
1554     tcpd->flow2.win_scale = (direction >= 0) ? pinfo->dst_win_scale : pinfo->src_win_scale;
1555     tcpd->flow2.multisegment_pdus=wmem_tree_new(wmem_file_scope());
1556 
1557     /* Only allocate the data if its actually going to be analyzed */
1558     if (tcp_analyze_seq)
1559     {
1560         tcpd->flow1.tcp_analyze_seq_info = wmem_new0(wmem_file_scope(), struct tcp_analyze_seq_flow_info_t);
1561         tcpd->flow2.tcp_analyze_seq_info = wmem_new0(wmem_file_scope(), struct tcp_analyze_seq_flow_info_t);
1562     }
1563     /* Only allocate the data if its actually going to be displayed */
1564     if (tcp_display_process_info)
1565     {
1566         tcpd->flow1.process_info = wmem_new0(wmem_file_scope(), struct tcp_process_info_t);
1567         tcpd->flow2.process_info = wmem_new0(wmem_file_scope(), struct tcp_process_info_t);
1568     }
1569 
1570     tcpd->acked_table=wmem_tree_new(wmem_file_scope());
1571     tcpd->ts_first.secs=pinfo->abs_ts.secs;
1572     tcpd->ts_first.nsecs=pinfo->abs_ts.nsecs;
1573     nstime_set_zero(&tcpd->ts_mru_syn);
1574     nstime_set_zero(&tcpd->ts_first_rtt);
1575     tcpd->ts_prev.secs=pinfo->abs_ts.secs;
1576     tcpd->ts_prev.nsecs=pinfo->abs_ts.nsecs;
1577     tcpd->flow1.valid_bif = 1;
1578     tcpd->flow2.valid_bif = 1;
1579     tcpd->flow1.push_bytes_sent = 0;
1580     tcpd->flow2.push_bytes_sent = 0;
1581     tcpd->flow1.push_set_last = FALSE;
1582     tcpd->flow2.push_set_last = FALSE;
1583     tcpd->flow1.closing_initiator = FALSE;
1584     tcpd->flow2.closing_initiator = FALSE;
1585     tcpd->stream = tcp_stream_count++;
1586     tcpd->server_port = 0;
1587 
1588     return tcpd;
1589 }
1590 
1591 /* setup meta as well */
1592 static void
mptcp_init_subflow(tcp_flow_t * flow)1593 mptcp_init_subflow(tcp_flow_t *flow)
1594 {
1595     struct mptcp_subflow *sf = wmem_new0(wmem_file_scope(), struct mptcp_subflow);
1596 
1597     DISSECTOR_ASSERT(flow->mptcp_subflow == 0);
1598     flow->mptcp_subflow = sf;
1599     sf->ssn2dsn_mappings        = wmem_itree_new(wmem_file_scope());
1600     sf->dsn2packet_map         = wmem_itree_new(wmem_file_scope());
1601 }
1602 
1603 
1604 /* add a new subflow to an mptcp connection */
1605 static void
mptcp_attach_subflow(struct mptcp_analysis * mptcpd,struct tcp_analysis * tcpd)1606 mptcp_attach_subflow(struct mptcp_analysis* mptcpd, struct tcp_analysis* tcpd) {
1607 
1608     if(!wmem_list_find(mptcpd->subflows, tcpd)) {
1609         wmem_list_prepend(mptcpd->subflows, tcpd);
1610     }
1611 
1612     /* in case we merge 2 mptcp connections */
1613     tcpd->mptcp_analysis = mptcpd;
1614 }
1615 
1616 
1617 struct tcp_analysis *
get_tcp_conversation_data(conversation_t * conv,packet_info * pinfo)1618 get_tcp_conversation_data(conversation_t *conv, packet_info *pinfo)
1619 {
1620     int direction;
1621     struct tcp_analysis *tcpd;
1622     gboolean clear_ta = TRUE;
1623 
1624     /* Did the caller supply the conversation pointer? */
1625     if( conv==NULL ) {
1626         /* If the caller didn't supply a conversation, don't
1627          * clear the analysis, it may be needed */
1628         clear_ta = FALSE;
1629         conv = find_or_create_conversation(pinfo);
1630     }
1631 
1632     /* Get the data for this conversation */
1633     tcpd=(struct tcp_analysis *)conversation_get_proto_data(conv, proto_tcp);
1634 
1635     direction = cmp_address(&pinfo->src, &pinfo->dst);
1636     /* if the addresses are equal, match the ports instead */
1637     if (direction == 0) {
1638         direction = (pinfo->srcport > pinfo->destport) ? 1 : -1;
1639     }
1640     /* If the conversation was just created or it matched a
1641      * conversation with template options, tcpd will not
1642      * have been initialized. So, initialize
1643      * a new tcpd structure for the conversation.
1644      */
1645     if (!tcpd) {
1646         tcpd = init_tcp_conversation_data(pinfo, direction);
1647         conversation_add_proto_data(conv, proto_tcp, tcpd);
1648     }
1649 
1650     if (!tcpd) {
1651       return NULL;
1652     }
1653 
1654     /* check direction and get ua lists */
1655     if(direction>=0) {
1656         tcpd->fwd=&(tcpd->flow1);
1657         tcpd->rev=&(tcpd->flow2);
1658     } else {
1659         tcpd->fwd=&(tcpd->flow2);
1660         tcpd->rev=&(tcpd->flow1);
1661     }
1662 
1663     if (clear_ta) {
1664         tcpd->ta=NULL;
1665     }
1666     return tcpd;
1667 }
1668 
1669 /* Attach process info to a flow */
1670 /* XXX - We depend on the TCP dissector finding the conversation first */
1671 void
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)1672 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) {
1673     conversation_t *conv;
1674     struct tcp_analysis *tcpd;
1675     tcp_flow_t *flow = NULL;
1676 
1677     if (!tcp_display_process_info)
1678         return;
1679 
1680     conv = find_conversation(frame_num, local_addr, remote_addr, ENDPOINT_TCP, local_port, remote_port, 0);
1681     if (!conv) {
1682         return;
1683     }
1684 
1685     tcpd = (struct tcp_analysis *)conversation_get_proto_data(conv, proto_tcp);
1686     if (!tcpd) {
1687         return;
1688     }
1689 
1690     if (cmp_address(local_addr, conversation_key_addr1(conv->key_ptr)) == 0 && local_port == conversation_key_port1(conv->key_ptr)) {
1691         flow = &tcpd->flow1;
1692     } else if (cmp_address(remote_addr, conversation_key_addr1(conv->key_ptr)) == 0 && remote_port == conversation_key_port1(conv->key_ptr)) {
1693         flow = &tcpd->flow2;
1694     }
1695     if (!flow || (flow->process_info && flow->process_info->command)) {
1696         return;
1697     }
1698 
1699     if (flow->process_info == NULL)
1700         flow->process_info = wmem_new0(wmem_file_scope(), struct tcp_process_info_t);
1701 
1702     flow->process_info->process_uid = uid;
1703     flow->process_info->process_pid = pid;
1704     flow->process_info->username = wmem_strdup(wmem_file_scope(), username);
1705     flow->process_info->command = wmem_strdup(wmem_file_scope(), command);
1706 }
1707 
1708 /* Return the current stream count */
get_tcp_stream_count(void)1709 guint32 get_tcp_stream_count(void)
1710 {
1711     return tcp_stream_count;
1712 }
1713 
1714 /* Return the mptcp current stream count */
get_mptcp_stream_count(void)1715 guint32 get_mptcp_stream_count(void)
1716 {
1717     return mptcp_stream_count;
1718 }
1719 
1720 /* Calculate the timestamps relative to this conversation */
1721 static void
tcp_calculate_timestamps(packet_info * pinfo,struct tcp_analysis * tcpd,struct tcp_per_packet_data_t * tcppd)1722 tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd,
1723             struct tcp_per_packet_data_t *tcppd)
1724 {
1725     if( !tcppd ) {
1726         tcppd = wmem_new(wmem_file_scope(), struct tcp_per_packet_data_t);
1727         p_add_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num, tcppd);
1728     }
1729 
1730     if (!tcpd)
1731         return;
1732 
1733     nstime_delta(&tcppd->ts_del, &pinfo->abs_ts, &tcpd->ts_prev);
1734 
1735     tcpd->ts_prev.secs=pinfo->abs_ts.secs;
1736     tcpd->ts_prev.nsecs=pinfo->abs_ts.nsecs;
1737 }
1738 
1739 /* Add a subtree with the timestamps relative to this conversation */
1740 static void
tcp_print_timestamps(packet_info * pinfo,tvbuff_t * tvb,proto_tree * parent_tree,struct tcp_analysis * tcpd,struct tcp_per_packet_data_t * tcppd)1741 tcp_print_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, struct tcp_analysis *tcpd, struct tcp_per_packet_data_t *tcppd)
1742 {
1743     proto_item  *item;
1744     proto_tree  *tree;
1745     nstime_t    ts;
1746 
1747     if (!tcpd)
1748         return;
1749 
1750     tree=proto_tree_add_subtree(parent_tree, tvb, 0, 0, ett_tcp_timestamps, &item, "Timestamps");
1751     proto_item_set_generated(item);
1752 
1753     nstime_delta(&ts, &pinfo->abs_ts, &tcpd->ts_first);
1754     item = proto_tree_add_time(tree, hf_tcp_ts_relative, tvb, 0, 0, &ts);
1755     proto_item_set_generated(item);
1756 
1757     if( !tcppd )
1758         tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num);
1759 
1760     if( tcppd ) {
1761         item = proto_tree_add_time(tree, hf_tcp_ts_delta, tvb, 0, 0,
1762             &tcppd->ts_del);
1763         proto_item_set_generated(item);
1764     }
1765 }
1766 
1767 static void
print_pdu_tracking_data(packet_info * pinfo,tvbuff_t * tvb,proto_tree * tcp_tree,struct tcp_multisegment_pdu * msp)1768 print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, struct tcp_multisegment_pdu *msp)
1769 {
1770     proto_item *item;
1771 
1772     col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", msp->first_frame);
1773     item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to,
1774         tvb, 0, 0, msp->first_frame);
1775     proto_item_set_generated(item);
1776 }
1777 
1778 /* if we know that a PDU starts inside this segment, return the adjusted
1779    offset to where that PDU starts or just return offset back
1780    and let TCP try to find out what it can about this segment
1781 */
1782 static int
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)1783 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)
1784 {
1785     struct tcp_multisegment_pdu *msp=NULL;
1786 
1787     if(!pinfo->fd->visited) {
1788         msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(multisegment_pdus, seq-1);
1789         if(msp) {
1790             /* If this is a continuation of a PDU started in a
1791              * previous segment we need to update the last_frame
1792              * variables.
1793             */
1794             if(seq>msp->seq && seq<msp->nxtpdu) {
1795                 msp->last_frame=pinfo->num;
1796                 msp->last_frame_time=pinfo->abs_ts;
1797                 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
1798             }
1799 
1800             /* If this segment is completely within a previous PDU
1801              * then we just skip this packet
1802              */
1803             if(seq>msp->seq && nxtseq<=msp->nxtpdu) {
1804                 return -1;
1805             }
1806             if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu) {
1807                 offset+=msp->nxtpdu-seq;
1808                 return offset;
1809             }
1810 
1811         }
1812     } else {
1813         /* First we try to find the start and transfer time for a PDU.
1814          * We only print this for the very first segment of a PDU
1815          * and only for PDUs spanning multiple segments.
1816          * Se we look for if there was any multisegment PDU started
1817          * just BEFORE the end of this segment. I.e. either inside this
1818          * segment or in a previous segment.
1819          * Since this might also match PDUs that are completely within
1820          * this segment we also verify that the found PDU does span
1821          * beyond the end of this segment.
1822          */
1823         msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(multisegment_pdus, nxtseq-1);
1824         if(msp) {
1825             if(pinfo->num==msp->first_frame) {
1826                 proto_item *item;
1827                 nstime_t ns;
1828 
1829                 item=proto_tree_add_uint(tcp_tree, hf_tcp_pdu_last_frame, tvb, 0, 0, msp->last_frame);
1830                 proto_item_set_generated(item);
1831 
1832                 nstime_delta(&ns, &msp->last_frame_time, &pinfo->abs_ts);
1833                 item = proto_tree_add_time(tcp_tree, hf_tcp_pdu_time,
1834                         tvb, 0, 0, &ns);
1835                 proto_item_set_generated(item);
1836             }
1837         }
1838 
1839         /* Second we check if this segment is part of a PDU started
1840          * prior to the segment (seq-1)
1841          */
1842         msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(multisegment_pdus, seq-1);
1843         if(msp) {
1844             /* If this segment is completely within a previous PDU
1845              * then we just skip this packet
1846              */
1847             if(seq>msp->seq && nxtseq<=msp->nxtpdu) {
1848                 print_pdu_tracking_data(pinfo, tvb, tcp_tree, msp);
1849                 return -1;
1850             }
1851 
1852             if(seq<msp->nxtpdu && nxtseq>msp->nxtpdu) {
1853                 offset+=msp->nxtpdu-seq;
1854                 return offset;
1855             }
1856         }
1857 
1858     }
1859     return offset;
1860 }
1861 
1862 /* if we saw a PDU that extended beyond the end of the segment,
1863    use this function to remember where the next pdu starts
1864 */
1865 struct tcp_multisegment_pdu *
pdu_store_sequencenumber_of_next_pdu(packet_info * pinfo,guint32 seq,guint32 nxtpdu,wmem_tree_t * multisegment_pdus)1866 pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nxtpdu, wmem_tree_t *multisegment_pdus)
1867 {
1868     struct tcp_multisegment_pdu *msp;
1869 
1870     msp=wmem_new(wmem_file_scope(), struct tcp_multisegment_pdu);
1871     msp->nxtpdu=nxtpdu;
1872     msp->seq=seq;
1873     msp->first_frame=pinfo->num;
1874     msp->first_frame_with_seq=pinfo->num;
1875     msp->last_frame=pinfo->num;
1876     msp->last_frame_time=pinfo->abs_ts;
1877     msp->flags=0;
1878     wmem_tree_insert32(multisegment_pdus, seq, (void *)msp);
1879     /*ws_warning("pdu_store_sequencenumber_of_next_pdu: seq %u", seq);*/
1880     return msp;
1881 }
1882 
1883 /* This is called for SYN and SYN+ACK packets and the purpose is to verify
1884  * that we have seen window scaling in both directions.
1885  * If we can't find window scaling being set in both directions
1886  * that means it was present in the SYN but not in the SYN+ACK
1887  * (or the SYN was missing) and then we disable the window scaling
1888  * for this tcp session.
1889  */
1890 static void
verify_tcp_window_scaling(gboolean is_synack,struct tcp_analysis * tcpd)1891 verify_tcp_window_scaling(gboolean is_synack, struct tcp_analysis *tcpd)
1892 {
1893     if( tcpd->fwd->win_scale==-1 ) {
1894         /* We know window scaling will not be used as:
1895          * a) this is the SYN and it does not have the WS option
1896          *    (we set the reverse win_scale also in case we miss
1897          *    the SYN/ACK)
1898          * b) this is the SYN/ACK and either the SYN packet has not
1899          *    been seen or it did have the WS option. As the SYN/ACK
1900          *    does not have the WS option, window scaling will not be used.
1901          *
1902          * Setting win_scale to -2 to indicate that we can
1903          * trust the window_size value in the TCP header.
1904          */
1905         tcpd->fwd->win_scale = -2;
1906         tcpd->rev->win_scale = -2;
1907 
1908     } else if( is_synack && tcpd->rev->win_scale==-2 ) {
1909         /* The SYN/ACK has the WS option, while the SYN did not,
1910          * this should not happen, but the endpoints will not
1911          * have used window scaling, so we will neither
1912          */
1913         tcpd->fwd->win_scale = -2;
1914     }
1915 }
1916 
1917 /* given a tcpd, returns the mptcp_subflow that sides with meta */
1918 static struct mptcp_subflow *
mptcp_select_subflow_from_meta(const struct tcp_analysis * tcpd,const mptcp_meta_flow_t * meta)1919 mptcp_select_subflow_from_meta(const struct tcp_analysis *tcpd, const mptcp_meta_flow_t *meta)
1920 {
1921     /* select the tcp_flow with appropriate direction */
1922     if( tcpd->flow1.mptcp_subflow->meta == meta) {
1923         return tcpd->flow1.mptcp_subflow;
1924     }
1925     else {
1926         return tcpd->flow2.mptcp_subflow;
1927     }
1928 }
1929 
1930 /* if we saw a window scaling option, store it for future reference
1931 */
1932 static void
pdu_store_window_scale_option(guint8 ws,struct tcp_analysis * tcpd)1933 pdu_store_window_scale_option(guint8 ws, struct tcp_analysis *tcpd)
1934 {
1935     if (tcpd)
1936         tcpd->fwd->win_scale=ws;
1937 }
1938 
1939 /* when this function returns, it will (if createflag) populate the ta pointer.
1940  */
1941 static void
tcp_analyze_get_acked_struct(guint32 frame,guint32 seq,guint32 ack,gboolean createflag,struct tcp_analysis * tcpd)1942 tcp_analyze_get_acked_struct(guint32 frame, guint32 seq, guint32 ack, gboolean createflag, struct tcp_analysis *tcpd)
1943 {
1944 
1945     wmem_tree_key_t key[4];
1946 
1947     key[0].length = 1;
1948     key[0].key = &frame;
1949 
1950     key[1].length = 1;
1951     key[1].key = &seq;
1952 
1953     key[2].length = 1;
1954     key[2].key = &ack;
1955 
1956     key[3].length = 0;
1957     key[3].key = NULL;
1958 
1959     if (!tcpd) {
1960         return;
1961     }
1962 
1963     tcpd->ta = (struct tcp_acked *)wmem_tree_lookup32_array(tcpd->acked_table, key);
1964     if((!tcpd->ta) && createflag) {
1965         tcpd->ta = wmem_new0(wmem_file_scope(), struct tcp_acked);
1966         wmem_tree_insert32_array(tcpd->acked_table, key, (void *)tcpd->ta);
1967     }
1968 }
1969 
1970 
1971 /* fwd contains a list of all segments processed but not yet ACKed in the
1972  *     same direction as the current segment.
1973  * rev contains a list of all segments received but not yet ACKed in the
1974  *     opposite direction to the current segment.
1975  *
1976  * New segments are always added to the head of the fwd/rev lists.
1977  *
1978  * Changes below should be synced with ChAdvTCPAnalysis in the User's
1979  * Guide: docbook/wsug_src/WSUG_chapter_advanced.adoc
1980  */
1981 static void
tcp_analyze_sequence_number(packet_info * pinfo,guint32 seq,guint32 ack,guint32 seglen,guint16 flags,guint32 window,struct tcp_analysis * tcpd)1982 tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint32 seglen, guint16 flags, guint32 window, struct tcp_analysis *tcpd)
1983 {
1984     tcp_unacked_t *ual=NULL;
1985     tcp_unacked_t *prevual=NULL;
1986     guint32 nextseq;
1987     int ackcount;
1988 
1989 #if 0
1990     printf("\nanalyze_sequence numbers   frame:%u\n",pinfo->num);
1991     printf("FWD list lastflags:0x%04x base_seq:%u: nextseq:%u lastack:%u\n",tcpd->fwd->lastsegmentflags,tcpd->fwd->base_seq,tcpd->fwd->tcp_analyze_seq_info->nextseq,tcpd->rev->tcp_analyze_seq_info->lastack);
1992     for(ual=tcpd->fwd->tcp_analyze_seq_info->segments; ual; ual=ual->next)
1993             printf("Frame:%d Seq:%u Nextseq:%u\n",ual->frame,ual->seq,ual->nextseq);
1994     printf("REV list lastflags:0x%04x base_seq:%u nextseq:%u lastack:%u\n",tcpd->rev->lastsegmentflags,tcpd->rev->base_seq,tcpd->rev->tcp_analyze_seq_info->nextseq,tcpd->fwd->tcp_analyze_seq_info->lastack);
1995     for(ual=tcpd->rev->tcp_analyze_seq_info->segments; ual; ual=ual->next)
1996             printf("Frame:%d Seq:%u Nextseq:%u\n",ual->frame,ual->seq,ual->nextseq);
1997 #endif
1998 
1999     if (!tcpd) {
2000         return;
2001     }
2002 
2003     /* if this is the first segment for this list we need to store the
2004      * base_seq
2005      * We use TCP_S_SAW_SYN/SYNACK to distinguish between client and server
2006      *
2007      * Start relative seq and ack numbers at 1 if this
2008      * is not a SYN packet. This makes the relative
2009      * seq/ack numbers to be displayed correctly in the
2010      * event that the SYN or SYN/ACK packet is not seen
2011      * (this solves bug 1542)
2012      */
2013     if( !(tcpd->fwd->static_flags & TCP_S_BASE_SEQ_SET)) {
2014         if(flags & TH_SYN) {
2015             tcpd->fwd->base_seq = seq;
2016             tcpd->fwd->static_flags |= (flags & TH_ACK) ? TCP_S_SAW_SYNACK : TCP_S_SAW_SYN;
2017         }
2018         else {
2019             tcpd->fwd->base_seq = seq-1;
2020         }
2021         tcpd->fwd->static_flags |= TCP_S_BASE_SEQ_SET;
2022     }
2023 
2024     /* Only store reverse sequence if this isn't the SYN
2025      * There's no guarantee that the ACK field of a SYN
2026      * contains zeros; get the ISN from the first segment
2027      * with the ACK bit set instead (usually the SYN/ACK).
2028      *
2029      * If the SYN and SYN/ACK were received out-of-order,
2030      * the ISN is ack-1. If we missed the SYN/ACK, but got
2031      * the last ACK of the 3WHS, the ISN is ack-1. For all
2032      * other packets the ISN is unknown, so ack-1 is
2033      * as good a guess as ack.
2034      */
2035     if( !(tcpd->rev->static_flags & TCP_S_BASE_SEQ_SET) && (flags & TH_ACK) ) {
2036         tcpd->rev->base_seq = ack-1;
2037         tcpd->rev->static_flags |= TCP_S_BASE_SEQ_SET;
2038     }
2039 
2040     if( flags & TH_ACK ) {
2041         tcpd->rev->valid_bif = 1;
2042     }
2043 
2044     /* ZERO WINDOW PROBE
2045      * it is a zero window probe if
2046      *  the sequence number is the next expected one
2047      *  the window in the other direction is 0
2048      *  the segment is exactly 1 byte
2049      */
2050     if( seglen==1
2051     &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
2052     &&  tcpd->rev->window==0 ) {
2053         if(!tcpd->ta) {
2054             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2055         }
2056         tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE;
2057         goto finished_fwd;
2058     }
2059 
2060 
2061     /* ZERO WINDOW
2062      * a zero window packet has window == 0   but none of the SYN/FIN/RST set
2063      */
2064     if( window==0
2065     && (flags&(TH_RST|TH_FIN|TH_SYN))==0 ) {
2066         if(!tcpd->ta) {
2067             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2068         }
2069         tcpd->ta->flags|=TCP_A_ZERO_WINDOW;
2070     }
2071 
2072 
2073     /* LOST PACKET
2074      * If this segment is beyond the last seen nextseq we must
2075      * have missed some previous segment
2076      *
2077      * We only check for this if we have actually seen segments prior to this
2078      * one.
2079      * RST packets are not checked for this.
2080      */
2081     if( tcpd->fwd->tcp_analyze_seq_info->nextseq
2082     &&  GT_SEQ(seq, tcpd->fwd->tcp_analyze_seq_info->nextseq)
2083     &&  (flags&(TH_RST))==0 ) {
2084         if(!tcpd->ta) {
2085             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2086         }
2087         tcpd->ta->flags|=TCP_A_LOST_PACKET;
2088 
2089         /* Disable BiF until an ACK is seen in the other direction */
2090         tcpd->fwd->valid_bif = 0;
2091     }
2092 
2093 
2094     /* KEEP ALIVE
2095      * a keepalive contains 0 or 1 bytes of data and starts one byte prior
2096      * to what should be the next sequence number.
2097      * SYN/FIN/RST segments are never keepalives
2098      */
2099     if( (seglen==0||seglen==1)
2100     &&  seq==(tcpd->fwd->tcp_analyze_seq_info->nextseq-1)
2101     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
2102         if(!tcpd->ta) {
2103             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2104         }
2105         tcpd->ta->flags|=TCP_A_KEEP_ALIVE;
2106     }
2107 
2108     /* WINDOW UPDATE
2109      * A window update is a 0 byte segment with the same SEQ/ACK numbers as
2110      * the previous seen segment and with a new window value
2111      */
2112     if( seglen==0
2113     &&  window
2114     &&  window!=tcpd->fwd->window
2115     &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
2116     &&  ack==tcpd->fwd->tcp_analyze_seq_info->lastack
2117     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
2118         if(!tcpd->ta) {
2119             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2120         }
2121         tcpd->ta->flags|=TCP_A_WINDOW_UPDATE;
2122     }
2123 
2124 
2125     /* WINDOW FULL
2126      * If we know the window scaling
2127      * and if this segment contains data and goes all the way to the
2128      * edge of the advertised window
2129      * then we mark it as WINDOW FULL
2130      * SYN/RST/FIN packets are never WINDOW FULL
2131      */
2132     if( seglen>0
2133     &&  tcpd->rev->win_scale!=-1
2134     &&  (seq+seglen)==(tcpd->rev->tcp_analyze_seq_info->lastack+(tcpd->rev->window<<(tcpd->rev->is_first_ack?0:(tcpd->rev->win_scale==-2?0:tcpd->rev->win_scale))))
2135     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
2136         if(!tcpd->ta) {
2137             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2138         }
2139         tcpd->ta->flags|=TCP_A_WINDOW_FULL;
2140     }
2141 
2142 
2143     /* KEEP ALIVE ACK
2144      * It is a keepalive ack if it repeats the previous ACK and if
2145      * the last segment in the reverse direction was a keepalive
2146      */
2147     if( seglen==0
2148     &&  window
2149     &&  window==tcpd->fwd->window
2150     &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
2151     &&  ack==tcpd->fwd->tcp_analyze_seq_info->lastack
2152     && (tcpd->rev->lastsegmentflags&TCP_A_KEEP_ALIVE)
2153     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
2154         if(!tcpd->ta) {
2155             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2156         }
2157         tcpd->ta->flags|=TCP_A_KEEP_ALIVE_ACK;
2158         goto finished_fwd;
2159     }
2160 
2161 
2162     /* ZERO WINDOW PROBE ACK
2163      * It is a zerowindowprobe ack if it repeats the previous ACK and if
2164      * the last segment in the reverse direction was a zerowindowprobe
2165      * It also repeats the previous zero window indication
2166      */
2167     if( seglen==0
2168     &&  window==0
2169     &&  window==tcpd->fwd->window
2170     &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
2171     &&  ack==tcpd->fwd->tcp_analyze_seq_info->lastack
2172     && (tcpd->rev->lastsegmentflags&TCP_A_ZERO_WINDOW_PROBE)
2173     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
2174         if(!tcpd->ta) {
2175             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2176         }
2177         tcpd->ta->flags|=TCP_A_ZERO_WINDOW_PROBE_ACK;
2178         goto finished_fwd;
2179     }
2180 
2181 
2182     /* DUPLICATE ACK
2183      * It is a duplicate ack if window/seq/ack is the same as the previous
2184      * segment and if the segment length is 0
2185      */
2186     if( seglen==0
2187     &&  window
2188     &&  window==tcpd->fwd->window
2189     &&  seq==tcpd->fwd->tcp_analyze_seq_info->nextseq
2190     &&  ack==tcpd->fwd->tcp_analyze_seq_info->lastack
2191     &&  (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) {
2192 
2193         /* MPTCP tolerates duplicate acks in some circumstances, see RFC 8684 4. */
2194         if(tcpd->mptcp_analysis && (tcpd->mptcp_analysis->mp_operations!=tcpd->fwd->mp_operations)) {
2195             /* just ignore this DUPLICATE ACK */
2196         } else {
2197             tcpd->fwd->tcp_analyze_seq_info->dupacknum++;
2198             if(!tcpd->ta) {
2199                 tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2200             }
2201             tcpd->ta->flags|=TCP_A_DUPLICATE_ACK;
2202             tcpd->ta->dupack_num=tcpd->fwd->tcp_analyze_seq_info->dupacknum;
2203             tcpd->ta->dupack_frame=tcpd->fwd->tcp_analyze_seq_info->lastnondupack;
2204        }
2205     }
2206 
2207 
2208 
2209 finished_fwd:
2210     /* If the ack number changed we must reset the dupack counters */
2211     if( ack != tcpd->fwd->tcp_analyze_seq_info->lastack ) {
2212         tcpd->fwd->tcp_analyze_seq_info->lastnondupack=pinfo->num;
2213         tcpd->fwd->tcp_analyze_seq_info->dupacknum=0;
2214     }
2215 
2216 
2217     /* ACKED LOST PACKET
2218      * If this segment acks beyond the 'max seq to be acked' in the other direction
2219      * then that means we have missed packets going in the
2220      * other direction
2221      *
2222      * We only check this if we have actually seen some seq numbers
2223      * in the other direction.
2224      */
2225     if( tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked
2226     &&  GT_SEQ(ack, tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked )
2227     &&  (flags&(TH_ACK))!=0 ) {
2228         if(!tcpd->ta) {
2229             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2230         }
2231         tcpd->ta->flags|=TCP_A_ACK_LOST_PACKET;
2232         /* update 'max seq to be acked' in the other direction so we don't get
2233          * this indication again.
2234          */
2235         tcpd->rev->tcp_analyze_seq_info->maxseqtobeacked=tcpd->rev->tcp_analyze_seq_info->nextseq;
2236     }
2237 
2238 
2239     /* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
2240      * If the segment contains data (or is a SYN or a FIN) and
2241      * if it does not advance the sequence number, it must be one
2242      * of these three.
2243      * Only test for this if we know what the seq number should be
2244      * (tcpd->fwd->nextseq)
2245      *
2246      * Note that a simple KeepAlive is not a retransmission
2247      */
2248     if (seglen>0 || flags&(TH_SYN|TH_FIN)) {
2249         gboolean seq_not_advanced = tcpd->fwd->tcp_analyze_seq_info->nextseq
2250                 && (LT_SEQ(seq, tcpd->fwd->tcp_analyze_seq_info->nextseq));
2251 
2252         guint64 t;
2253         guint64 ooo_thres;
2254 
2255         if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ) {
2256             goto finished_checking_retransmission_type;
2257         }
2258 
2259         /* This segment is *not* considered a retransmission/out-of-order if
2260          *  the segment length is larger than one (it really adds new data)
2261          *  the sequence number is one less than the previous nextseq and
2262          *      (the previous segment is possibly a zero window probe)
2263          *
2264          * We should still try to flag Spurious Retransmissions though.
2265          */
2266         if (seglen > 1 && tcpd->fwd->tcp_analyze_seq_info->nextseq - 1 == seq) {
2267             seq_not_advanced = FALSE;
2268         }
2269 
2270         /* Check for spurious retransmission. If the current seq + segment length
2271          * is less than or equal to the current lastack, the packet contains
2272          * duplicate data and may be considered spurious.
2273          */
2274         if ( seglen > 0
2275         && tcpd->rev->tcp_analyze_seq_info->lastack
2276         && LE_SEQ(seq + seglen, tcpd->rev->tcp_analyze_seq_info->lastack) ) {
2277             if(!tcpd->ta){
2278                 tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2279             }
2280             tcpd->ta->flags|=TCP_A_SPURIOUS_RETRANSMISSION;
2281             goto finished_checking_retransmission_type;
2282         }
2283 
2284         gboolean precedence_count = tcp_fastrt_precedence;
2285         do {
2286             switch(precedence_count) {
2287                 case TRUE:
2288                     /* If there were >=2 duplicate ACKs in the reverse direction
2289                      * (there might be duplicate acks missing from the trace)
2290                      * and if this sequence number matches those ACKs
2291                      * and if the packet occurs within 20ms of the last
2292                      * duplicate ack
2293                      * then this is a fast retransmission
2294                      */
2295                     t=(pinfo->abs_ts.secs-tcpd->rev->tcp_analyze_seq_info->lastacktime.secs)*1000000000;
2296                     t=t+(pinfo->abs_ts.nsecs)-tcpd->rev->tcp_analyze_seq_info->lastacktime.nsecs;
2297                     if( seq_not_advanced
2298                     &&  tcpd->rev->tcp_analyze_seq_info->dupacknum>=2
2299                     &&  tcpd->rev->tcp_analyze_seq_info->lastack==seq
2300                     &&  t<20000000 ) {
2301                         if(!tcpd->ta) {
2302                             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2303                         }
2304                         tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
2305                         goto finished_checking_retransmission_type;
2306                     }
2307                     precedence_count=!precedence_count;
2308                     break;
2309 
2310                 case FALSE:
2311                     /* If the segment came relatively close since the segment with the highest
2312                      * seen sequence number and it doesn't look like a retransmission
2313                      * then it is an OUT-OF-ORDER segment.
2314                      */
2315                     t=(pinfo->abs_ts.secs-tcpd->fwd->tcp_analyze_seq_info->nextseqtime.secs)*1000000000;
2316                     t=t+(pinfo->abs_ts.nsecs)-tcpd->fwd->tcp_analyze_seq_info->nextseqtime.nsecs;
2317                     if (tcpd->ts_first_rtt.nsecs == 0 && tcpd->ts_first_rtt.secs == 0) {
2318                         ooo_thres = 3000000;
2319                     } else {
2320                         ooo_thres = tcpd->ts_first_rtt.nsecs + tcpd->ts_first_rtt.secs*1000000000;
2321                     }
2322 
2323                     if( seq_not_advanced // XXX is this neccessary?
2324                     && t < ooo_thres
2325                     && tcpd->fwd->tcp_analyze_seq_info->nextseq != seq + seglen ) {
2326                         if(!tcpd->ta) {
2327                             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2328                         }
2329                         tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
2330                         goto finished_checking_retransmission_type;
2331                     }
2332                     precedence_count=!precedence_count;
2333                     break;
2334             }
2335         } while (precedence_count!=tcp_fastrt_precedence) ;
2336 
2337         if (seq_not_advanced) {
2338             /* Then it has to be a generic retransmission */
2339             if(!tcpd->ta) {
2340                 tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2341             }
2342             tcpd->ta->flags|=TCP_A_RETRANSMISSION;
2343 
2344             /*
2345              * worst case scenario: if we don't have better than a recent packet,
2346              * use it as the reference for RTO
2347              */
2348             nstime_delta(&tcpd->ta->rto_ts, &pinfo->abs_ts, &tcpd->fwd->tcp_analyze_seq_info->nextseqtime);
2349             tcpd->ta->rto_frame=tcpd->fwd->tcp_analyze_seq_info->nextseqframe;
2350 
2351             /*
2352              * better case scenario: if we have a list of the previous unacked packets,
2353              * go back to the eldest one, which in theory is likely to be the one retransmitted here.
2354              * It's not always the perfect match, particularly when original captured packet used LSO
2355              */
2356             ual = tcpd->fwd->tcp_analyze_seq_info->segments;
2357             while(ual) {
2358                 nstime_delta(&tcpd->ta->rto_ts, &pinfo->abs_ts, &ual->ts );
2359                 tcpd->ta->rto_frame=ual->frame;
2360                 ual=ual->next;
2361             }
2362         }
2363     }
2364 
2365 finished_checking_retransmission_type:
2366 
2367     nextseq = seq+seglen;
2368     if ((seglen || flags&(TH_SYN|TH_FIN)) && tcpd->fwd->tcp_analyze_seq_info->segment_count < TCP_MAX_UNACKED_SEGMENTS) {
2369         /* Add this new sequence number to the fwd list.  But only if there
2370          * aren't "too many" unacked segments (e.g., we're not seeing the ACKs).
2371          */
2372         ual = wmem_new(wmem_file_scope(), tcp_unacked_t);
2373         ual->next=tcpd->fwd->tcp_analyze_seq_info->segments;
2374         tcpd->fwd->tcp_analyze_seq_info->segments=ual;
2375         tcpd->fwd->tcp_analyze_seq_info->segment_count++;
2376         ual->frame=pinfo->num;
2377         ual->seq=seq;
2378         ual->ts=pinfo->abs_ts;
2379 
2380         /* next sequence number is seglen bytes away, plus SYN/FIN which counts as one byte */
2381         if( (flags&(TH_SYN|TH_FIN)) ) {
2382             nextseq+=1;
2383         }
2384         ual->nextseq=nextseq;
2385     }
2386 
2387     /* Store the highest number seen so far for nextseq so we can detect
2388      * when we receive segments that arrive with a "hole"
2389      * If we don't have anything since before, just store what we got.
2390      * ZeroWindowProbes are special and don't really advance the nextseq
2391      */
2392     if(GT_SEQ(nextseq, tcpd->fwd->tcp_analyze_seq_info->nextseq) || !tcpd->fwd->tcp_analyze_seq_info->nextseq) {
2393         if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ) {
2394             tcpd->fwd->tcp_analyze_seq_info->nextseq=nextseq;
2395             tcpd->fwd->tcp_analyze_seq_info->nextseqframe=pinfo->num;
2396             tcpd->fwd->tcp_analyze_seq_info->nextseqtime.secs=pinfo->abs_ts.secs;
2397             tcpd->fwd->tcp_analyze_seq_info->nextseqtime.nsecs=pinfo->abs_ts.nsecs;
2398         }
2399     }
2400 
2401     /* Store the highest continuous seq number seen so far for 'max seq to be acked',
2402      so we can detect TCP_A_ACK_LOST_PACKET condition
2403      */
2404     if(EQ_SEQ(seq, tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked) || !tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked) {
2405         if( !tcpd->ta || !(tcpd->ta->flags&TCP_A_ZERO_WINDOW_PROBE) ) {
2406             tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked=tcpd->fwd->tcp_analyze_seq_info->nextseq;
2407         }
2408     }
2409 
2410 
2411     /* remember what the ack/window is so we can track window updates and retransmissions */
2412     tcpd->fwd->window=window;
2413     tcpd->fwd->tcp_analyze_seq_info->lastack=ack;
2414     tcpd->fwd->tcp_analyze_seq_info->lastacktime.secs=pinfo->abs_ts.secs;
2415     tcpd->fwd->tcp_analyze_seq_info->lastacktime.nsecs=pinfo->abs_ts.nsecs;
2416 
2417     /* remember the MPTCP operations if any */
2418     if( tcpd->mptcp_analysis ) {
2419         tcpd->fwd->mp_operations=tcpd->mptcp_analysis->mp_operations;
2420     }
2421 
2422     /* if there were any flags set for this segment we need to remember them
2423      * we only remember the flags for the very last segment though.
2424      */
2425     if(tcpd->ta) {
2426         tcpd->fwd->lastsegmentflags=tcpd->ta->flags;
2427     } else {
2428         tcpd->fwd->lastsegmentflags=0;
2429     }
2430 
2431 
2432     /* remove all segments this ACKs and we don't need to keep around any more
2433      */
2434     ackcount=0;
2435     prevual = NULL;
2436     ual = tcpd->rev->tcp_analyze_seq_info->segments;
2437     while(ual) {
2438         tcp_unacked_t *tmpual;
2439 
2440         /* If this ack matches the segment, process accordingly */
2441         if(ack==ual->nextseq) {
2442             tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2443             tcpd->ta->frame_acked=ual->frame;
2444             nstime_delta(&tcpd->ta->ts, &pinfo->abs_ts, &ual->ts);
2445         }
2446         /* If this acknowledges part of the segment, adjust the segment info for the acked part */
2447         else if (GT_SEQ(ack, ual->seq) && LE_SEQ(ack, ual->nextseq)) {
2448             ual->seq = ack;
2449             continue;
2450         }
2451         /* If this acknowledges a segment prior to this one, leave this segment alone and move on */
2452         else if (GT_SEQ(ual->nextseq,ack)) {
2453             prevual = ual;
2454             ual = ual->next;
2455             continue;
2456         }
2457 
2458         /* This segment is old, or an exact match.  Delete the segment from the list */
2459         ackcount++;
2460         tmpual=ual->next;
2461 
2462         if (tcpd->rev->scps_capable) {
2463           /* Track largest segment successfully sent for SNACK analysis*/
2464           if ((ual->nextseq - ual->seq) > tcpd->fwd->maxsizeacked) {
2465             tcpd->fwd->maxsizeacked = (ual->nextseq - ual->seq);
2466           }
2467         }
2468 
2469         if (!prevual) {
2470             tcpd->rev->tcp_analyze_seq_info->segments = tmpual;
2471         }
2472         else{
2473             prevual->next = tmpual;
2474         }
2475         wmem_free(wmem_file_scope(), ual);
2476         ual = tmpual;
2477         tcpd->rev->tcp_analyze_seq_info->segment_count--;
2478     }
2479 
2480     /* how many bytes of data are there in flight after this frame
2481      * was sent
2482      * The historical evaluation is done from the payload seen in the
2483      * segments captured. Another method deduced from the SEQ numbers
2484      * is introduced with issue 7703, but not used by default now. The
2485      * method is chosen by the user preference tcp_bif_seq_based.
2486      */
2487     if(tcp_track_bytes_in_flight) {
2488         guint32 in_flight, delivered = 0;
2489         /*
2490          * "don't repeat yourself" boolean, for the shared part
2491          * between both methods
2492          */
2493         gboolean dry_bif_handling = FALSE;
2494 
2495         /*
2496          * historical calculation method based on payloads, which is
2497          * by now still the default.
2498          */
2499         if(!tcp_bif_seq_based) {
2500             ual=tcpd->fwd->tcp_analyze_seq_info->segments;
2501 
2502             if (seglen!=0 && ual && tcpd->fwd->valid_bif) {
2503                 guint32 first_seq, last_seq;
2504 
2505                 dry_bif_handling = TRUE;
2506 
2507                 first_seq = ual->seq - tcpd->fwd->base_seq;
2508                 last_seq = ual->nextseq - tcpd->fwd->base_seq;
2509                 while (ual) {
2510                     if ((ual->nextseq-tcpd->fwd->base_seq)>last_seq) {
2511                         last_seq = ual->nextseq-tcpd->fwd->base_seq;
2512                     }
2513                     if ((ual->seq-tcpd->fwd->base_seq)<first_seq) {
2514                         first_seq = ual->seq-tcpd->fwd->base_seq;
2515                     }
2516                     ual = ual->next;
2517                 }
2518                 in_flight = last_seq-first_seq;
2519             }
2520         } else { /* calculation based on SEQ numbers (see issue 7703) */
2521             if (seglen!=0 && tcpd->fwd->tcp_analyze_seq_info && tcpd->fwd->valid_bif) {
2522 
2523                 dry_bif_handling = TRUE;
2524 
2525                 in_flight = tcpd->fwd->tcp_analyze_seq_info->nextseq
2526                           - tcpd->rev->tcp_analyze_seq_info->lastack;
2527             }
2528         }
2529         if(dry_bif_handling) {
2530             /* subtract any SACK block */
2531             if(tcpd->rev->tcp_analyze_seq_info->num_sack_ranges > 0) {
2532                 int i;
2533                 for(i = 0; i<tcpd->rev->tcp_analyze_seq_info->num_sack_ranges; i++) {
2534                     delivered += (tcpd->rev->tcp_analyze_seq_info->sack_right_edge[i+1] -
2535                                   tcpd->rev->tcp_analyze_seq_info->sack_left_edge[i+1]);
2536                 }
2537                 in_flight -= delivered;
2538             }
2539 
2540             if (in_flight>0 && in_flight<2000000000) {
2541                 if(!tcpd->ta) {
2542                     tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
2543                 }
2544                 tcpd->ta->bytes_in_flight = in_flight;
2545                 /* Decrement in_flight bytes by one when we have a SYN or FIN bit
2546                  * flag set as it is only virtual.
2547                  */
2548                 if (flags&(TH_SYN|TH_FIN))  {
2549                     tcpd->ta->bytes_in_flight -= 1;
2550 		    }
2551             }
2552 
2553             if((flags & TH_PUSH) && !tcpd->fwd->push_set_last) {
2554               tcpd->fwd->push_bytes_sent += seglen;
2555               tcpd->fwd->push_set_last = TRUE;
2556             } else if ((flags & TH_PUSH) && tcpd->fwd->push_set_last) {
2557               tcpd->fwd->push_bytes_sent = seglen;
2558               tcpd->fwd->push_set_last = TRUE;
2559             } else if (tcpd->fwd->push_set_last) {
2560               tcpd->fwd->push_bytes_sent = seglen;
2561               tcpd->fwd->push_set_last = FALSE;
2562             } else {
2563               tcpd->fwd->push_bytes_sent += seglen;
2564             }
2565             if(!tcpd->ta) {
2566               tcp_analyze_get_acked_struct(pinfo->fd->num, seq, ack, TRUE, tcpd);
2567             }
2568             tcpd->ta->push_bytes_sent = tcpd->fwd->push_bytes_sent;
2569         }
2570     }
2571 
2572 }
2573 
2574 /*
2575  * Prints results of the sequence number analysis concerning tcp segments
2576  * retransmitted or out-of-order
2577  */
2578 static void
tcp_sequence_number_analysis_print_retransmission(packet_info * pinfo,tvbuff_t * tvb,proto_tree * flags_tree,proto_item * flags_item,struct tcp_acked * ta)2579 tcp_sequence_number_analysis_print_retransmission(packet_info * pinfo,
2580                           tvbuff_t * tvb,
2581                           proto_tree * flags_tree, proto_item * flags_item,
2582                           struct tcp_acked *ta
2583                           )
2584 {
2585     /* TCP Retransmission */
2586     if (ta->flags & TCP_A_RETRANSMISSION) {
2587         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_retransmission);
2588 
2589         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
2590 
2591         if (ta->rto_ts.secs || ta->rto_ts.nsecs) {
2592             flags_item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
2593                                              tvb, 0, 0, &ta->rto_ts);
2594             proto_item_set_generated(flags_item);
2595             flags_item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame,
2596                                            tvb, 0, 0, ta->rto_frame);
2597             proto_item_set_generated(flags_item);
2598         }
2599     }
2600     /* TCP Fast Retransmission */
2601     if (ta->flags & TCP_A_FAST_RETRANSMISSION) {
2602         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_fast_retransmission);
2603         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_retransmission);
2604         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2605                                "[TCP Fast Retransmission] ");
2606     }
2607     /* TCP Spurious Retransmission */
2608     if (ta->flags & TCP_A_SPURIOUS_RETRANSMISSION) {
2609         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_spurious_retransmission);
2610         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_retransmission);
2611         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2612                                "[TCP Spurious Retransmission] ");
2613     }
2614 
2615     /* TCP Out-Of-Order */
2616     if (ta->flags & TCP_A_OUT_OF_ORDER) {
2617         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_out_of_order);
2618         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
2619     }
2620 }
2621 
2622 /* Prints results of the sequence number analysis concerning reused ports */
2623 static void
tcp_sequence_number_analysis_print_reused(packet_info * pinfo,proto_item * flags_item,struct tcp_acked * ta)2624 tcp_sequence_number_analysis_print_reused(packet_info * pinfo,
2625                       proto_item * flags_item,
2626                       struct tcp_acked *ta
2627                       )
2628 {
2629     /* TCP Ports Reused */
2630     if (ta->flags & TCP_A_REUSED_PORTS) {
2631         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_reused_ports);
2632         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2633                                "[TCP Port numbers reused] ");
2634     }
2635 }
2636 
2637 /* Prints results of the sequence number analysis concerning lost tcp segments */
2638 static void
tcp_sequence_number_analysis_print_lost(packet_info * pinfo,proto_item * flags_item,struct tcp_acked * ta)2639 tcp_sequence_number_analysis_print_lost(packet_info * pinfo,
2640                     proto_item * flags_item,
2641                     struct tcp_acked *ta
2642                     )
2643 {
2644     /* TCP Lost Segment */
2645     if (ta->flags & TCP_A_LOST_PACKET) {
2646         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_lost_packet);
2647         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2648                                "[TCP Previous segment not captured] ");
2649     }
2650     /* TCP Ack lost segment */
2651     if (ta->flags & TCP_A_ACK_LOST_PACKET) {
2652         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_ack_lost_packet);
2653         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2654                                "[TCP ACKed unseen segment] ");
2655     }
2656 }
2657 
2658 /* Prints results of the sequence number analysis concerning tcp window */
2659 static void
tcp_sequence_number_analysis_print_window(packet_info * pinfo,proto_item * flags_item,struct tcp_acked * ta)2660 tcp_sequence_number_analysis_print_window(packet_info * pinfo,
2661                       proto_item * flags_item,
2662                       struct tcp_acked *ta
2663                       )
2664 {
2665     /* TCP Window Update */
2666     if (ta->flags & TCP_A_WINDOW_UPDATE) {
2667         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_window_update);
2668         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
2669     }
2670     /* TCP Full Window */
2671     if (ta->flags & TCP_A_WINDOW_FULL) {
2672         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_window_full);
2673         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
2674     }
2675 }
2676 
2677 /* Prints results of the sequence number analysis concerning tcp keepalive */
2678 static void
tcp_sequence_number_analysis_print_keepalive(packet_info * pinfo,proto_item * flags_item,struct tcp_acked * ta)2679 tcp_sequence_number_analysis_print_keepalive(packet_info * pinfo,
2680                       proto_item * flags_item,
2681                       struct tcp_acked *ta
2682                       )
2683 {
2684     /*TCP Keep Alive */
2685     if (ta->flags & TCP_A_KEEP_ALIVE) {
2686         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_keep_alive);
2687         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
2688     }
2689     /* TCP Ack Keep Alive */
2690     if (ta->flags & TCP_A_KEEP_ALIVE_ACK) {
2691         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_keep_alive_ack);
2692         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
2693     }
2694 }
2695 
2696 /* Prints results of the sequence number analysis concerning tcp duplicate ack */
2697 static void
tcp_sequence_number_analysis_print_duplicate(packet_info * pinfo,tvbuff_t * tvb,proto_tree * flags_tree,struct tcp_acked * ta,proto_tree * tree)2698 tcp_sequence_number_analysis_print_duplicate(packet_info * pinfo,
2699                           tvbuff_t * tvb,
2700                           proto_tree * flags_tree,
2701                           struct tcp_acked *ta,
2702                           proto_tree * tree
2703                         )
2704 {
2705     proto_item * flags_item;
2706 
2707     /* TCP Duplicate ACK */
2708     if (ta->dupack_num) {
2709         if (ta->flags & TCP_A_DUPLICATE_ACK ) {
2710             flags_item=proto_tree_add_none_format(flags_tree,
2711                                                   hf_tcp_analysis_duplicate_ack,
2712                                                   tvb, 0, 0,
2713                                                   "This is a TCP duplicate ack"
2714                 );
2715             proto_item_set_generated(flags_item);
2716             col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2717                                    "[TCP Dup ACK %u#%u] ",
2718                                    ta->dupack_frame,
2719                                    ta->dupack_num
2720                 );
2721 
2722         }
2723         flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num,
2724                                        tvb, 0, 0, ta->dupack_num);
2725         proto_item_set_generated(flags_item);
2726         flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
2727                                        tvb, 0, 0, ta->dupack_frame);
2728         proto_item_set_generated(flags_item);
2729         expert_add_info_format(pinfo, flags_item, &ei_tcp_analysis_duplicate_ack, "Duplicate ACK (#%u)", ta->dupack_num);
2730     }
2731 }
2732 
2733 /* Prints results of the sequence number analysis concerning tcp zero window */
2734 static void
tcp_sequence_number_analysis_print_zero_window(packet_info * pinfo,proto_item * flags_item,struct tcp_acked * ta)2735 tcp_sequence_number_analysis_print_zero_window(packet_info * pinfo,
2736                           proto_item * flags_item,
2737                           struct tcp_acked *ta
2738                         )
2739 {
2740     /* TCP Zero Window Probe */
2741     if (ta->flags & TCP_A_ZERO_WINDOW_PROBE) {
2742         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_zero_window_probe);
2743         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
2744     }
2745     /* TCP Zero Window */
2746     if (ta->flags&TCP_A_ZERO_WINDOW) {
2747         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_zero_window);
2748         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
2749     }
2750     /* TCP Zero Window Probe Ack */
2751     if (ta->flags & TCP_A_ZERO_WINDOW_PROBE_ACK) {
2752         expert_add_info(pinfo, flags_item, &ei_tcp_analysis_zero_window_probe_ack);
2753         col_prepend_fence_fstr(pinfo->cinfo, COL_INFO,
2754                                "[TCP ZeroWindowProbeAck] ");
2755     }
2756 }
2757 
2758 
2759 /* Prints results of the sequence number analysis concerning how many bytes of data are in flight */
2760 static void
tcp_sequence_number_analysis_print_bytes_in_flight(packet_info * pinfo _U_,tvbuff_t * tvb,proto_tree * flags_tree,struct tcp_acked * ta)2761 tcp_sequence_number_analysis_print_bytes_in_flight(packet_info * pinfo _U_,
2762                           tvbuff_t * tvb,
2763                           proto_tree * flags_tree,
2764                           struct tcp_acked *ta
2765                         )
2766 {
2767     proto_item * flags_item;
2768 
2769     if (tcp_track_bytes_in_flight) {
2770         flags_item=proto_tree_add_uint(flags_tree,
2771                                        hf_tcp_analysis_bytes_in_flight,
2772                                        tvb, 0, 0, ta->bytes_in_flight);
2773 
2774         proto_item_set_generated(flags_item);
2775     }
2776 }
2777 
2778 /* Generate the initial data sequence number and MPTCP connection token from the key. */
2779 static void
mptcp_cryptodata_sha1(const guint64 key,guint32 * token,guint64 * idsn)2780 mptcp_cryptodata_sha1(const guint64 key, guint32 *token, guint64 *idsn)
2781 {
2782     guint8 digest_buf[HASH_SHA1_LENGTH];
2783     guint64 pseudokey = GUINT64_TO_BE(key);
2784     guint32 _token;
2785     guint64 _isdn;
2786 
2787     gcry_md_hash_buffer(GCRY_MD_SHA1, digest_buf, (const guint8 *)&pseudokey, 8);
2788 
2789     /* memcpy to prevent -Wstrict-aliasing errors with GCC 4 */
2790     memcpy(&_token, digest_buf, sizeof(_token));
2791     *token = GUINT32_FROM_BE(_token);
2792     memcpy(&_isdn, digest_buf + HASH_SHA1_LENGTH - sizeof(_isdn), sizeof(_isdn));
2793     *idsn = GUINT64_FROM_BE(_isdn);
2794 }
2795 
2796 /* Generate the initial data sequence number and MPTCP connection token from the key. */
2797 static void
mptcp_cryptodata_sha256(const guint64 key,guint32 * token,guint64 * idsn)2798 mptcp_cryptodata_sha256(const guint64 key, guint32 *token, guint64 *idsn)
2799 {
2800     guint8 digest_buf[HASH_SHA2_256_LENGTH];
2801     guint64 pseudokey = GUINT64_TO_BE(key);
2802     guint32 _token;
2803     guint64 _isdn;
2804 
2805     gcry_md_hash_buffer(GCRY_MD_SHA256, digest_buf, (const guint8 *)&pseudokey, 8);
2806 
2807     /* memcpy to prevent -Wstrict-aliasing errors with GCC 4 */
2808     memcpy(&_token, digest_buf, sizeof(_token));
2809     *token = GUINT32_FROM_BE(_token);
2810     memcpy(&_isdn, digest_buf + HASH_SHA2_256_LENGTH - sizeof(_isdn), sizeof(_isdn));
2811     *idsn = GUINT64_FROM_BE(_isdn);
2812 }
2813 
2814 
2815 /* Print formatted list of tcp stream ids that are part of the connection */
2816 static void
mptcp_analysis_add_subflows(packet_info * pinfo,tvbuff_t * tvb,proto_tree * parent_tree,struct mptcp_analysis * mptcpd)2817 mptcp_analysis_add_subflows(packet_info *pinfo,  tvbuff_t *tvb,
2818     proto_tree *parent_tree, struct mptcp_analysis* mptcpd)
2819 {
2820     wmem_list_frame_t *it;
2821     proto_item *item;
2822 
2823     wmem_strbuf_t *val = wmem_strbuf_new(pinfo->pool, "");
2824 
2825     /* for the analysis, we set each subflow tcp stream id */
2826     for(it = wmem_list_head(mptcpd->subflows); it != NULL; it = wmem_list_frame_next(it)) {
2827         struct tcp_analysis *sf = (struct tcp_analysis *)wmem_list_frame_data(it);
2828         wmem_strbuf_append_printf(val, "%u ", sf->stream);
2829     }
2830 
2831     item = proto_tree_add_string(parent_tree, hf_mptcp_analysis_subflows, tvb, 0, 0, wmem_strbuf_get_str(val));
2832     proto_item_set_generated(item);
2833 }
2834 
2835 /* Compute raw dsn if relative tcp seq covered by DSS mapping */
2836 static gboolean
mptcp_map_relssn_to_rawdsn(mptcp_dss_mapping_t * mapping,guint32 relssn,guint64 * dsn)2837 mptcp_map_relssn_to_rawdsn(mptcp_dss_mapping_t *mapping, guint32 relssn, guint64 *dsn)
2838 {
2839     if( (relssn < mapping->ssn_low) || (relssn > mapping->ssn_high)) {
2840         return FALSE;
2841     }
2842 
2843     *dsn = mapping->rawdsn + (relssn - mapping->ssn_low);
2844     return TRUE;
2845 }
2846 
2847 
2848 /* Add duplicated data */
2849 static mptcp_dsn2packet_mapping_t *
mptcp_add_duplicated_dsn(packet_info * pinfo,proto_tree * tree,tvbuff_t * tvb,struct mptcp_subflow * subflow,guint64 rawdsn64low,guint64 rawdsn64high)2850 mptcp_add_duplicated_dsn(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, struct mptcp_subflow *subflow,
2851 guint64 rawdsn64low, guint64 rawdsn64high
2852 )
2853 {
2854     wmem_list_t *results = NULL;
2855     wmem_list_frame_t *packet_it = NULL;
2856     mptcp_dsn2packet_mapping_t *packet = NULL;
2857     proto_item *item = NULL;
2858 
2859     results = wmem_itree_find_intervals(subflow->dsn2packet_map,
2860                     pinfo->pool,
2861                     rawdsn64low,
2862                     rawdsn64high
2863                     );
2864 
2865     for(packet_it = wmem_list_head(results);
2866         packet_it != NULL;
2867         packet_it = wmem_list_frame_next(packet_it))
2868     {
2869 
2870         packet = (mptcp_dsn2packet_mapping_t *) wmem_list_frame_data(packet_it);
2871         DISSECTOR_ASSERT(packet);
2872 
2873         if(pinfo->num > packet->frame) {
2874             item = proto_tree_add_uint(tree, hf_mptcp_reinjection_of, tvb, 0, 0, packet->frame);
2875         }
2876         else {
2877             item = proto_tree_add_uint(tree, hf_mptcp_reinjected_in, tvb, 0, 0, packet->frame);
2878         }
2879         proto_item_set_generated(item);
2880     }
2881 
2882     return packet;
2883 }
2884 
2885 
2886 /* Lookup mappings that describe the packet and then converts the tcp seq number
2887  * into the MPTCP Data Sequence Number (DSN)
2888  */
2889 static void
mptcp_analysis_dsn_lookup(packet_info * pinfo,tvbuff_t * tvb,proto_tree * parent_tree,struct tcp_analysis * tcpd,struct tcpheader * tcph,mptcp_per_packet_data_t * mptcppd)2890 mptcp_analysis_dsn_lookup(packet_info *pinfo , tvbuff_t *tvb,
2891     proto_tree *parent_tree, struct tcp_analysis* tcpd, struct tcpheader * tcph, mptcp_per_packet_data_t *mptcppd)
2892 {
2893     struct mptcp_analysis* mptcpd = tcpd->mptcp_analysis;
2894     proto_item *item = NULL;
2895     mptcp_dss_mapping_t *mapping = NULL;
2896     guint32 relseq;
2897     guint64 rawdsn = 0;
2898     enum mptcp_dsn_conversion convert;
2899 
2900     if(!mptcp_analyze_mappings)
2901     {
2902         /* abort analysis */
2903         return;
2904     }
2905 
2906     /* for this to work, we need to know the original seq number from the SYN, not from a subsequent packet
2907     * hence, we abort if we didn't capture the SYN
2908     */
2909     if(!(tcpd->fwd->static_flags & ~TCP_S_BASE_SEQ_SET & (TCP_S_SAW_SYN | TCP_S_SAW_SYNACK))) {
2910         return;
2911     }
2912 
2913     /* if seq not relative yet, we compute it */
2914     relseq = (tcp_relative_seq) ? tcph->th_seq : tcph->th_seq - tcpd->fwd->base_seq;
2915 
2916     DISSECTOR_ASSERT(mptcpd);
2917     DISSECTOR_ASSERT(mptcppd);
2918 
2919     /* in case of a SYN, there is no mapping covering the DSN */
2920     if(tcph->th_flags & TH_SYN) {
2921 
2922         rawdsn = tcpd->fwd->mptcp_subflow->meta->base_dsn;
2923         convert = DSN_CONV_NONE;
2924     }
2925     /* if it's a non-syn packet without data (just used to convey TCP options)
2926      * then there would be no mappings */
2927     else if(relseq == 1 && tcph->th_seglen == 0) {
2928         rawdsn = tcpd->fwd->mptcp_subflow->meta->base_dsn + 1;
2929         convert = DSN_CONV_NONE;
2930     }
2931     else {
2932 
2933         wmem_list_frame_t *dss_it = NULL;
2934         wmem_list_t *results = NULL;
2935         guint32 ssn_low = relseq;
2936         guint32 seglen = tcph->th_seglen;
2937 
2938         results = wmem_itree_find_intervals(tcpd->fwd->mptcp_subflow->ssn2dsn_mappings,
2939                     pinfo->pool,
2940                     ssn_low,
2941                     (seglen) ? ssn_low + seglen - 1 : ssn_low
2942                     );
2943         dss_it = wmem_list_head(results); /* assume it's always ok */
2944         if(dss_it) {
2945             mapping = (mptcp_dss_mapping_t *) wmem_list_frame_data(dss_it);
2946         }
2947         if(dss_it == NULL || mapping == NULL) {
2948             expert_add_info(pinfo, parent_tree, &ei_mptcp_mapping_missing);
2949             return;
2950         }
2951         else {
2952             mptcppd->mapping = mapping;
2953         }
2954 
2955         DISSECTOR_ASSERT(mapping);
2956         if(seglen) {
2957             /* Finds mappings that cover the sent data and adds them to the dissection tree */
2958             for(dss_it = wmem_list_head(results);
2959                 dss_it != NULL;
2960                 dss_it = wmem_list_frame_next(dss_it))
2961             {
2962                 mapping = (mptcp_dss_mapping_t *) wmem_list_frame_data(dss_it);
2963                 DISSECTOR_ASSERT(mapping);
2964 
2965                 item = proto_tree_add_uint(parent_tree, hf_mptcp_related_mapping, tvb, 0, 0, mapping->frame);
2966                 proto_item_set_generated(item);
2967             }
2968         }
2969 
2970         convert = (mapping->extended_dsn) ? DSN_CONV_NONE : DSN_CONV_32_TO_64;
2971         DISSECTOR_ASSERT(mptcp_map_relssn_to_rawdsn(mapping, relseq, &rawdsn));
2972     }
2973 
2974     /* Make sure we have the 64bit raw DSN */
2975     if(mptcp_convert_dsn(rawdsn, tcpd->fwd->mptcp_subflow->meta,
2976         convert, FALSE, &tcph->th_mptcp->mh_rawdsn64)) {
2977 
2978         /* always display the rawdsn64 (helpful for debug) */
2979         item = proto_tree_add_uint64(parent_tree, hf_mptcp_rawdsn64, tvb, 0, 0, tcph->th_mptcp->mh_rawdsn64);
2980 
2981         /* converts to relative if required */
2982         if (mptcp_relative_seq
2983             && mptcp_convert_dsn(tcph->th_mptcp->mh_rawdsn64, tcpd->fwd->mptcp_subflow->meta, DSN_CONV_NONE, TRUE, &tcph->th_mptcp->mh_dsn)) {
2984             item = proto_tree_add_uint64(parent_tree, hf_mptcp_dsn, tvb, 0, 0, tcph->th_mptcp->mh_dsn);
2985             proto_item_append_text(item, " (Relative)");
2986         }
2987 
2988         /* register dsn->packet mapping */
2989         if(mptcp_intersubflows_retransmission
2990             && !PINFO_FD_VISITED(pinfo)
2991             && tcph->th_seglen > 0
2992           ) {
2993                 mptcp_dsn2packet_mapping_t *packet = 0;
2994                 packet = wmem_new0(wmem_file_scope(), mptcp_dsn2packet_mapping_t);
2995                 packet->frame = pinfo->fd->num;
2996                 packet->subflow = tcpd;
2997 
2998                 wmem_itree_insert(tcpd->fwd->mptcp_subflow->dsn2packet_map,
2999                         tcph->th_mptcp->mh_rawdsn64,
3000                         tcph->th_mptcp->mh_rawdsn64 + (tcph->th_seglen - 1 ),
3001                         packet
3002                         );
3003         }
3004         proto_item_set_generated(item);
3005 
3006         /* We can do this only if rawdsn64 is valid !
3007         if enabled, look for overlapping mappings on other subflows */
3008         if(mptcp_intersubflows_retransmission
3009             && tcph->th_have_seglen
3010             && tcph->th_seglen) {
3011 
3012             wmem_list_frame_t *subflow_it = NULL;
3013 
3014             /* results should be some kind of list in case 2 DSS are needed to cover this packet */
3015             for(subflow_it = wmem_list_head(mptcpd->subflows); subflow_it != NULL; subflow_it = wmem_list_frame_next(subflow_it)) {
3016                 struct tcp_analysis *sf_tcpd = (struct tcp_analysis *)wmem_list_frame_data(subflow_it);
3017                 struct mptcp_subflow *sf = mptcp_select_subflow_from_meta(sf_tcpd, tcpd->fwd->mptcp_subflow->meta);
3018 
3019                 /* for current subflow */
3020                 if (sf == tcpd->fwd->mptcp_subflow) {
3021                     /* skip, this is the current subflow */
3022                 }
3023                 /* in case there were retransmissions on other subflows */
3024                 else  {
3025                     mptcp_add_duplicated_dsn(pinfo, parent_tree, tvb, sf,
3026                                              tcph->th_mptcp->mh_rawdsn64,
3027                                              tcph->th_mptcp->mh_rawdsn64 + tcph->th_seglen-1);
3028                 }
3029             }
3030         }
3031     }
3032     else {
3033         /* could not get the rawdsn64, ignore and continue */
3034     }
3035 
3036 }
3037 
3038 
3039 /* Print subflow list */
3040 static void
mptcp_add_analysis_subtree(packet_info * pinfo,tvbuff_t * tvb,proto_tree * parent_tree,struct tcp_analysis * tcpd,struct mptcp_analysis * mptcpd,struct tcpheader * tcph)3041 mptcp_add_analysis_subtree(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree,
3042                           struct tcp_analysis *tcpd, struct mptcp_analysis *mptcpd, struct tcpheader * tcph)
3043 {
3044 
3045     proto_item *item = NULL;
3046     proto_tree *tree = NULL;
3047     mptcp_per_packet_data_t *mptcppd = NULL;
3048 
3049     if(mptcpd == NULL) {
3050         return;
3051     }
3052 
3053     item=proto_tree_add_item(parent_tree, hf_mptcp_analysis, tvb, 0, 0, ENC_NA);
3054     proto_item_set_generated(item);
3055     tree=proto_item_add_subtree(item, ett_mptcp_analysis);
3056     proto_item_set_generated(tree);
3057 
3058     /* set field with mptcp stream */
3059     if(mptcpd->master) {
3060 
3061         item = proto_tree_add_boolean_format_value(tree, hf_mptcp_analysis_master, tvb, 0,
3062                                      0, (mptcpd->master->stream == tcpd->stream) ? TRUE : FALSE
3063                                      , "Master is tcp stream %u", mptcpd->master->stream
3064                                      );
3065 
3066     }
3067     else {
3068           item = proto_tree_add_boolean(tree, hf_mptcp_analysis_master, tvb, 0,
3069                                      0, FALSE);
3070     }
3071 
3072     proto_item_set_generated(item);
3073 
3074     /* store the TCP Options related to MPTCP then we will avoid false DUP ACKs later */
3075     guint8 nbOptionsChanged = 0;
3076     if((tcpd->mptcp_analysis->mp_operations&(0x01))!=tcph->th_mptcp->mh_mpc) {
3077         tcpd->mptcp_analysis->mp_operations |= 0x01;
3078         nbOptionsChanged++;
3079     }
3080     if((tcpd->mptcp_analysis->mp_operations&(0x02))!=tcph->th_mptcp->mh_join) {
3081         tcpd->mptcp_analysis->mp_operations |= 0x02;
3082         nbOptionsChanged++;
3083     }
3084     if((tcpd->mptcp_analysis->mp_operations&(0x04))!=tcph->th_mptcp->mh_dss) {
3085         tcpd->mptcp_analysis->mp_operations |= 0x04;
3086         nbOptionsChanged++;
3087     }
3088     if((tcpd->mptcp_analysis->mp_operations&(0x08))!=tcph->th_mptcp->mh_add) {
3089         tcpd->mptcp_analysis->mp_operations |= 0x08;
3090         nbOptionsChanged++;
3091     }
3092     if((tcpd->mptcp_analysis->mp_operations&(0x10))!=tcph->th_mptcp->mh_remove) {
3093         tcpd->mptcp_analysis->mp_operations |= 0x10;
3094         nbOptionsChanged++;
3095     }
3096     if((tcpd->mptcp_analysis->mp_operations&(0x20))!=tcph->th_mptcp->mh_prio) {
3097         tcpd->mptcp_analysis->mp_operations |= 0x20;
3098         nbOptionsChanged++;
3099     }
3100     if((tcpd->mptcp_analysis->mp_operations&(0x40))!=tcph->th_mptcp->mh_fail) {
3101         tcpd->mptcp_analysis->mp_operations |= 0x40;
3102         nbOptionsChanged++;
3103     }
3104     if((tcpd->mptcp_analysis->mp_operations&(0x80))!=tcph->th_mptcp->mh_fastclose) {
3105         tcpd->mptcp_analysis->mp_operations |= 0x80;
3106         nbOptionsChanged++;
3107     }
3108     /* we could track MPTCP option changes here, with nbOptionsChanged */
3109 
3110     item = proto_tree_add_uint(tree, hf_mptcp_stream, tvb, 0, 0, mptcpd->stream);
3111     proto_item_set_generated(item);
3112 
3113     /* retrieve saved analysis of packets, else create it */
3114     mptcppd = (mptcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mptcp, pinfo->curr_layer_num);
3115     if(!mptcppd) {
3116         mptcppd = (mptcp_per_packet_data_t *)wmem_new0(wmem_file_scope(), mptcp_per_packet_data_t);
3117         p_add_proto_data(wmem_file_scope(), pinfo, proto_mptcp, pinfo->curr_layer_num, mptcppd);
3118     }
3119 
3120     /* Print formatted list of tcp stream ids that are part of the connection */
3121     mptcp_analysis_add_subflows(pinfo, tvb, tree, mptcpd);
3122 
3123     /* Converts TCP seq number into its MPTCP DSN */
3124     mptcp_analysis_dsn_lookup(pinfo, tvb, tree, tcpd, tcph, mptcppd);
3125 
3126 }
3127 
3128 
3129 static void
tcp_sequence_number_analysis_print_push_bytes_sent(packet_info * pinfo _U_,tvbuff_t * tvb,proto_tree * flags_tree,struct tcp_acked * ta)3130 tcp_sequence_number_analysis_print_push_bytes_sent(packet_info * pinfo _U_,
3131                           tvbuff_t * tvb,
3132                           proto_tree * flags_tree,
3133                           struct tcp_acked *ta
3134                         )
3135 {
3136     proto_item * flags_item;
3137 
3138     if (tcp_track_bytes_in_flight) {
3139         flags_item=proto_tree_add_uint(flags_tree,
3140                                        hf_tcp_analysis_push_bytes_sent,
3141                                        tvb, 0, 0, ta->push_bytes_sent);
3142 
3143         proto_item_set_generated(flags_item);
3144     }
3145 }
3146 
3147 static void
tcp_print_sequence_number_analysis(packet_info * pinfo,tvbuff_t * tvb,proto_tree * parent_tree,struct tcp_analysis * tcpd,guint32 seq,guint32 ack)3148 tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree,
3149                           struct tcp_analysis *tcpd, guint32 seq, guint32 ack)
3150 {
3151     struct tcp_acked *ta = NULL;
3152     proto_item *item;
3153     proto_tree *tree;
3154     proto_tree *flags_tree=NULL;
3155 
3156     if (!tcpd) {
3157         return;
3158     }
3159     if(!tcpd->ta) {
3160         tcp_analyze_get_acked_struct(pinfo->num, seq, ack, FALSE, tcpd);
3161     }
3162     ta=tcpd->ta;
3163     if(!ta) {
3164         return;
3165     }
3166 
3167     item=proto_tree_add_item(parent_tree, hf_tcp_analysis, tvb, 0, 0, ENC_NA);
3168     proto_item_set_generated(item);
3169     tree=proto_item_add_subtree(item, ett_tcp_analysis);
3170 
3171     /* encapsulate all proto_tree_add_xxx in ifs so we only print what
3172        data we actually have */
3173     if(ta->frame_acked) {
3174         item = proto_tree_add_uint(tree, hf_tcp_analysis_acks_frame,
3175             tvb, 0, 0, ta->frame_acked);
3176             proto_item_set_generated(item);
3177 
3178         /* only display RTT if we actually have something we are acking */
3179         if( ta->ts.secs || ta->ts.nsecs ) {
3180             item = proto_tree_add_time(tree, hf_tcp_analysis_ack_rtt,
3181             tvb, 0, 0, &ta->ts);
3182                 proto_item_set_generated(item);
3183         }
3184     }
3185     if (!nstime_is_zero(&tcpd->ts_first_rtt)) {
3186         item = proto_tree_add_time(tree, hf_tcp_analysis_first_rtt,
3187                 tvb, 0, 0, &(tcpd->ts_first_rtt));
3188         proto_item_set_generated(item);
3189     }
3190 
3191     if(ta->bytes_in_flight) {
3192         /* print results for amount of data in flight */
3193         tcp_sequence_number_analysis_print_bytes_in_flight(pinfo, tvb, tree, ta);
3194         tcp_sequence_number_analysis_print_push_bytes_sent(pinfo, tvb, tree, ta);
3195     }
3196 
3197     if(ta->flags) {
3198         item = proto_tree_add_item(tree, hf_tcp_analysis_flags, tvb, 0, 0, ENC_NA);
3199         proto_item_set_generated(item);
3200         flags_tree=proto_item_add_subtree(item, ett_tcp_analysis);
3201 
3202         /* print results for reused tcp ports */
3203         tcp_sequence_number_analysis_print_reused(pinfo, item, ta);
3204 
3205         /* print results for retransmission and out-of-order segments */
3206         tcp_sequence_number_analysis_print_retransmission(pinfo, tvb, flags_tree, item, ta);
3207 
3208         /* print results for lost tcp segments */
3209         tcp_sequence_number_analysis_print_lost(pinfo, item, ta);
3210 
3211         /* print results for tcp window information */
3212         tcp_sequence_number_analysis_print_window(pinfo, item, ta);
3213 
3214         /* print results for tcp keep alive information */
3215         tcp_sequence_number_analysis_print_keepalive(pinfo, item, ta);
3216 
3217         /* print results for tcp duplicate acks */
3218         tcp_sequence_number_analysis_print_duplicate(pinfo, tvb, flags_tree, ta, tree);
3219 
3220         /* print results for tcp zero window  */
3221         tcp_sequence_number_analysis_print_zero_window(pinfo, item, ta);
3222 
3223     }
3224 
3225 }
3226 
3227 static void
print_tcp_fragment_tree(fragment_head * ipfd_head,proto_tree * tree,proto_tree * tcp_tree,packet_info * pinfo,tvbuff_t * next_tvb)3228 print_tcp_fragment_tree(fragment_head *ipfd_head, proto_tree *tree, proto_tree *tcp_tree, packet_info *pinfo, tvbuff_t *next_tvb)
3229 {
3230     proto_item *tcp_tree_item, *frag_tree_item;
3231 
3232     /*
3233      * The subdissector thought it was completely
3234      * desegmented (although the stuff at the
3235      * end may, in turn, require desegmentation),
3236      * so we show a tree with all segments.
3237      */
3238     show_fragment_tree(ipfd_head, &tcp_segment_items,
3239         tree, pinfo, next_tvb, &frag_tree_item);
3240     /*
3241      * The toplevel fragment subtree is now
3242      * behind all desegmented data; move it
3243      * right behind the TCP tree.
3244      */
3245     tcp_tree_item = proto_tree_get_parent(tcp_tree);
3246     if(frag_tree_item && tcp_tree_item) {
3247         proto_tree_move_item(tree, tcp_tree_item, frag_tree_item);
3248     }
3249 }
3250 
3251 /* **************************************************************************
3252  * End of tcp sequence number analysis
3253  * **************************************************************************/
3254 
3255 
3256 /* Minimum TCP header length. */
3257 #define TCPH_MIN_LEN            20
3258 
3259 /* Desegmentation of TCP streams */
3260 static reassembly_table tcp_reassembly_table;
3261 
3262 /* functions to trace tcp segments */
3263 /* Enable desegmenting of TCP streams */
3264 static gboolean tcp_desegment = TRUE;
3265 
3266 /* Enable buffering of out-of-order TCP segments before passing it to a
3267  * subdissector (depends on "tcp_desegment"). */
3268 static gboolean tcp_reassemble_out_of_order = FALSE;
3269 
3270 /* Returns true iff any gap exists in the segments associated with msp up to the
3271  * given sequence number (it ignores any gaps after the sequence number). */
3272 static gboolean
missing_segments(packet_info * pinfo,struct tcp_multisegment_pdu * msp,guint32 seq)3273 missing_segments(packet_info *pinfo, struct tcp_multisegment_pdu *msp, guint32 seq)
3274 {
3275     fragment_head *fd_head;
3276     guint32 frag_offset = seq - msp->seq;
3277 
3278     if ((gint32)frag_offset <= 0) {
3279         return FALSE;
3280     }
3281 
3282     fd_head = fragment_get(&tcp_reassembly_table, pinfo, msp->first_frame, NULL);
3283     /* msp implies existence of fragments, this should never be NULL. */
3284     DISSECTOR_ASSERT(fd_head);
3285 
3286     /* Find length of contiguous fragments. */
3287     guint32 max = 0;
3288     for (fragment_item *frag = fd_head; frag; frag = frag->next) {
3289         guint32 frag_end = frag->offset + frag->len;
3290         if (frag->offset <= max && max < frag_end) {
3291             max = frag_end;
3292         }
3293     }
3294     return max < frag_offset;
3295 }
3296 
3297 static void
desegment_tcp(tvbuff_t * tvb,packet_info * pinfo,int offset,guint32 seq,guint32 nxtseq,guint32 sport,guint32 dport,proto_tree * tree,proto_tree * tcp_tree,struct tcp_analysis * tcpd,struct tcpinfo * tcpinfo)3298 desegment_tcp(tvbuff_t *tvb, packet_info *pinfo, int offset,
3299               guint32 seq, guint32 nxtseq,
3300               guint32 sport, guint32 dport,
3301               proto_tree *tree, proto_tree *tcp_tree,
3302               struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
3303 {
3304     fragment_head *ipfd_head;
3305     int last_fragment_len;
3306     gboolean must_desegment;
3307     gboolean called_dissector;
3308     int another_pdu_follows;
3309     int deseg_offset;
3310     guint32 deseg_seq;
3311     gint nbytes;
3312     proto_item *item;
3313     struct tcp_multisegment_pdu *msp;
3314     gboolean cleared_writable = col_get_writable(pinfo->cinfo, COL_PROTOCOL);
3315     const gboolean reassemble_ooo = tcp_analyze_seq && tcp_desegment && tcp_reassemble_out_of_order;
3316 
3317 again:
3318     ipfd_head = NULL;
3319     last_fragment_len = 0;
3320     must_desegment = FALSE;
3321     called_dissector = FALSE;
3322     another_pdu_follows = 0;
3323     msp = NULL;
3324 
3325     /*
3326      * Initialize these to assume no desegmentation.
3327      * If that's not the case, these will be set appropriately
3328      * by the subdissector.
3329      */
3330     pinfo->desegment_offset = 0;
3331     pinfo->desegment_len = 0;
3332 
3333     /*
3334      * Initialize this to assume that this segment will just be
3335      * added to the middle of a desegmented chunk of data, so
3336      * that we should show it all as data.
3337      * If that's not the case, it will be set appropriately.
3338      */
3339     deseg_offset = offset;
3340 
3341     if (tcpd) {
3342         /* Have we seen this PDU before (and is it the start of a multi-
3343          * segment PDU)?
3344          *
3345          * If the sequence number was seen before, it is part of a
3346          * retransmission if the whole segment fits within the MSP.
3347          * (But if this is this frame was already visited and the first frame of
3348          * the MSP matches the current frame, then it is not a retransmission,
3349          * but the start of a new MSP.)
3350          *
3351          * If only part of the segment fits in the MSP, then either:
3352          * - The previous segment included with the MSP was a Zero Window Probe
3353          *   with one byte of data and the subdissector just asked for one more
3354          *   byte. Do not mark it as retransmission (Bug 15427).
3355          * - Data was actually being retransmitted, but with additional data
3356          *   (Bug 13523). Do not mark it as retransmission to handle the extra
3357          *   bytes. (NOTE Due to the TCP_A_RETRANSMISSION check below, such
3358          *   extra data will still be ignored.)
3359          * - The MSP contains multiple segments, but the subdissector finished
3360          *   reassembly using a subset of the final segment (thus "msp->nxtpdu"
3361          *   is smaller than the nxtseq of the previous segment). If that final
3362          *   segment was retransmitted, then "nxtseq > msp->nxtpdu".
3363          *   Unfortunately that will *not* be marked as retransmission here.
3364          *   The next TCP_A_RETRANSMISSION hopefully takes care of it though.
3365          *
3366          * Only shortcircuit here when the first segment of the MSP is known,
3367          * and when this this first segment is not one to complete the MSP.
3368          */
3369         if ((msp = (struct tcp_multisegment_pdu *)wmem_tree_lookup32(tcpd->fwd->multisegment_pdus, seq)) &&
3370                 nxtseq <= msp->nxtpdu &&
3371                 !(msp->flags & MSP_FLAGS_MISSING_FIRST_SEGMENT) && msp->last_frame != pinfo->num) {
3372             const char* str;
3373             gboolean is_retransmission = FALSE;
3374 
3375             /* Yes.  This could be because we've dissected this frame before
3376              * or because this is a retransmission of a previously-seen
3377              * segment.  Either way, we don't need to hand it off to the
3378              * subdissector and we certainly don't want to re-add it to the
3379              * multisegment_pdus list: if we did, subsequent lookups would
3380              * find this retransmission instead of the original transmission
3381              * (breaking desegmentation if we'd already linked other segments
3382              * to the original transmission's entry).
3383              *
3384              * Cases to handle here:
3385              * - In-order stream, pinfo->num matches begin of MSP.
3386              * - In-order stream, but pinfo->num does not match the begin of the
3387              *   MSP. Must be a retransmission.
3388              * - OoO stream where this segment fills the gap in the begin of the
3389              *   MSP. msp->first_frame is the start where the gap was detected
3390              *   (and does NOT match pinfo->num).
3391              */
3392 
3393             if (msp->first_frame == pinfo->num || msp->first_frame_with_seq == pinfo->num) {
3394                 str = "";
3395                 col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[TCP segment of a reassembled PDU]");
3396             } else {
3397                 str = "Retransmitted ";
3398                 is_retransmission = TRUE;
3399                 /* TCP analysis already flags this (in COL_INFO) as a retransmission--if it's enabled */
3400             }
3401 
3402             /* Fix for bug 3264: look up ipfd for this (first) segment,
3403                so can add tcp.reassembled_in generated field on this code path. */
3404             if (!is_retransmission) {
3405                 ipfd_head = fragment_get(&tcp_reassembly_table, pinfo, msp->first_frame, NULL);
3406                 if (ipfd_head) {
3407                     if (ipfd_head->reassembled_in != 0) {
3408                         item = proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in, tvb, 0,
3409                                            0, ipfd_head->reassembled_in);
3410                         proto_item_set_generated(item);
3411                     }
3412                 }
3413             }
3414 
3415             nbytes = tvb_reported_length_remaining(tvb, offset);
3416 
3417             proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, offset,
3418                 nbytes, NULL, "%sTCP segment data (%u byte%s)", str, nbytes,
3419                 plurality(nbytes, "", "s"));
3420             return;
3421         }
3422 
3423         /* The above code only finds retransmission if the PDU boundaries and the seq coincide I think
3424          * If we have sequence analysis active use the TCP_A_RETRANSMISSION flag.
3425          * XXXX Could the above code be improved?
3426          * XXX the following check works great for filtering duplicate
3427          * retransmissions, but could there be a case where it prevents
3428          * "tcp_reassemble_out_of_order" from functioning due to skipping
3429          * retransmission of a lost segment?
3430          * If the latter is enabled, it could use use "maxnextseq" for ignoring
3431          * retransmitted single-segment PDUs (that would require storing
3432          * per-packet state (tcp_per_packet_data_t) to make it work for two-pass
3433          * and random access dissection). Retransmitted segments that are part
3434          * of a MSP should already be passed only once to subdissectors due to
3435          * the "reassembled_in" check below.
3436          */
3437         if(tcpd->ta) {
3438             /* Spurious Retransmission is the most obvious case to handle, just ignore it.
3439              * See issue 10289
3440              */
3441             if((tcpd->ta->flags&TCP_A_SPURIOUS_RETRANSMISSION) == TCP_A_SPURIOUS_RETRANSMISSION) {
3442                 return;
3443             }
3444             if((tcpd->ta->flags&TCP_A_RETRANSMISSION) == TCP_A_RETRANSMISSION) {
3445                 const char* str = "Retransmitted ";
3446                 nbytes = tvb_reported_length_remaining(tvb, offset);
3447                 proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, offset,
3448                     nbytes, NULL, "%sTCP segment data (%u byte%s)", str, nbytes,
3449                     plurality(nbytes, "", "s"));
3450                 return;
3451             }
3452         }
3453         /* Else, find the most previous PDU starting before this sequence number */
3454         if (!msp) {
3455             msp = (struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(tcpd->fwd->multisegment_pdus, seq-1);
3456         }
3457     }
3458 
3459     if (reassemble_ooo && tcpd && !(tcpd->fwd->flags & TCP_FLOW_REASSEMBLE_UNTIL_FIN) && !PINFO_FD_VISITED(pinfo)) {
3460         /* If there is a gap between this segment and any previous ones (that
3461          * is, seqno is larger than the maximum expected seqno), then it is
3462          * possibly an out-of-order segment. The very first segment is expected
3463          * to be in-order though (otherwise captures starting in midst of a
3464          * connection would never be reassembled).
3465          *
3466          * Do not bother checking for OoO segments for streams that are
3467          * reassembled at FIN, the order of segments before FIN does not matter
3468          * as reordering and reassembly occurs at FIN.
3469          */
3470         if (tcpd->fwd->maxnextseq) {
3471             /* Segments may be missing due to packet loss (assume later
3472              * retransmission) or out-of-order (assume it will appear later).
3473              *
3474              * Extend an unfinished MSP when (1) missing segments exist between
3475              * the start of the previous, (2) unfinished MSP and new segment.
3476              *
3477              * Create a new MSP when no (1) previous MSP exists and (2) a gap is
3478              * detected between the previous largest nxtseq and the new segment.
3479              */
3480             /* Whether a previous MSP exists with missing segments. */
3481             gboolean has_unfinished_msp = msp && !(msp->flags & MSP_FLAGS_GOT_ALL_SEGMENTS);
3482             /* Whether the new segment creates a new gap. */
3483             gboolean has_gap = LT_SEQ(tcpd->fwd->maxnextseq, seq);
3484 
3485             if (has_unfinished_msp && missing_segments(pinfo, msp, seq)) {
3486                 /* The last PDU is part of a MSP which still needed more data,
3487                  * extend it (if necessary) to cover the entire new segment.
3488                  */
3489                 if (LT_SEQ(msp->nxtpdu, nxtseq)) {
3490                     msp->nxtpdu = nxtseq;
3491                 }
3492             } else if (!has_unfinished_msp && has_gap) {
3493                 /* Either the previous segment was a single PDU that did not
3494                  * belong to a MSP, or the previous MSP was completed and cannot
3495                  * be extended.
3496                  * Create a new one starting at the expected next position and
3497                  * extend it to the end of the new segment.
3498                  */
3499                 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
3500                     tcpd->fwd->maxnextseq, nxtseq,
3501                     tcpd->fwd->multisegment_pdus);
3502 
3503                 msp->flags |= MSP_FLAGS_MISSING_FIRST_SEGMENT;
3504             }
3505             /* Now that the MSP is updated or created, continue adding the
3506              * segments to the MSP below. The subdissector will not be called as
3507              * the MSP is not complete yet. */
3508         }
3509         if (tcpd->fwd->maxnextseq == 0 || LT_SEQ(tcpd->fwd->maxnextseq, nxtseq)) {
3510             /* Update the maximum expected seqno if no SYN packet was seen
3511              * before, or if the new segment succeeds previous segments. */
3512             tcpd->fwd->maxnextseq = nxtseq;
3513         }
3514     }
3515 
3516     if (msp && LE_SEQ(msp->seq, seq) && GT_SEQ(msp->nxtpdu, seq)) {
3517         int len;
3518 
3519         if (!PINFO_FD_VISITED(pinfo)) {
3520             msp->last_frame=pinfo->num;
3521             msp->last_frame_time=pinfo->abs_ts;
3522         }
3523 
3524         /* OK, this PDU was found, which means the segment continues
3525          * a higher-level PDU and that we must desegment it.
3526          */
3527         if (msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
3528             /* The dissector asked for the entire segment */
3529             len = tvb_captured_length_remaining(tvb, offset);
3530         } else {
3531             /* Wraparound is possible, so subtraction does not
3532              * distribute across MIN(x, y)
3533              */
3534             len = MIN(nxtseq - seq, msp->nxtpdu - seq);
3535         }
3536         last_fragment_len = len;
3537 
3538 
3539         if (reassemble_ooo && tcpd && !(tcpd->fwd->flags & TCP_FLOW_REASSEMBLE_UNTIL_FIN)) {
3540             /*
3541              * If the previous segment requested more data (setting
3542              * FD_PARTIAL_REASSEMBLY as the next segment length is unknown), but
3543              * subsequently an OoO segment was received (for an earlier hole),
3544              * then "fragment_add" would truncate the reassembled PDU to the end
3545              * of this OoO segment. To prevent that, explicitly specify the MSP
3546              * length before calling "fragment_add".
3547              *
3548              * When a subdissector requests reassembly at the end of the
3549              * connection (DESEGMENT_UNTIL_FIN), then it is not
3550              * possible for an earlier segment to complete reassembly
3551              * (more_frags for fragment_add is always TRUE). Thus we do not
3552              * have to worry about increasing the fragment length here.
3553              */
3554             fragment_reset_tot_len(&tcp_reassembly_table, pinfo,
3555                                    msp->first_frame, NULL,
3556                                    MAX(seq + len, msp->nxtpdu) - msp->seq);
3557         }
3558 
3559         ipfd_head = fragment_add(&tcp_reassembly_table, tvb, offset,
3560                                  pinfo, msp->first_frame, NULL,
3561                                  seq - msp->seq, len,
3562                                  (LT_SEQ (nxtseq,msp->nxtpdu)) );
3563 
3564         if (!PINFO_FD_VISITED(pinfo)
3565         && msp->flags & MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
3566             msp->flags &= (~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT);
3567 
3568             /* If we consumed the entire segment there is no
3569              * other pdu starting anywhere inside this segment.
3570              * So update nxtpdu to point at least to the start
3571              * of the next segment.
3572              * (If the subdissector asks for even more data we
3573              * will advance nxtpdu even further later down in
3574              * the code.)
3575              */
3576             msp->nxtpdu = nxtseq;
3577         }
3578 
3579         if (reassemble_ooo && !PINFO_FD_VISITED(pinfo)) {
3580             /* If the first segment of the MSP was seen, remember it. */
3581             if (msp->seq == seq && msp->flags & MSP_FLAGS_MISSING_FIRST_SEGMENT) {
3582                 msp->first_frame_with_seq = pinfo->num;
3583                 msp->flags &= ~MSP_FLAGS_MISSING_FIRST_SEGMENT;
3584             }
3585             /* Remember when all segments are ready to avoid subsequent
3586              * out-of-order packets from extending this MSP. If a subsdissector
3587              * needs more segments, the flag will be cleared below. */
3588             if (ipfd_head) {
3589                 msp->flags |= MSP_FLAGS_GOT_ALL_SEGMENTS;
3590             }
3591         }
3592 
3593         if( (msp->nxtpdu < nxtseq)
3594         &&  (msp->nxtpdu >= seq)
3595         &&  (len > 0)) {
3596             another_pdu_follows=msp->nxtpdu - seq;
3597         }
3598     } else {
3599         /* This segment was not found in our table, so it doesn't
3600          * contain a continuation of a higher-level PDU.
3601          * Call the normal subdissector.
3602          */
3603 
3604         /*
3605          * Supply the sequence number of this segment. We set this here
3606          * because this segment could be after another in the same packet,
3607          * in which case seq was incremented at the end of the loop.
3608          */
3609         tcpinfo->seq = seq;
3610 
3611         process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree,
3612                             sport, dport, 0, 0, FALSE, tcpd, tcpinfo);
3613         called_dissector = TRUE;
3614 
3615         /* Did the subdissector ask us to desegment some more data
3616          * before it could handle the packet?
3617          * If so we have to create some structures in our table but
3618          * this is something we only do the first time we see this
3619          * packet.
3620          */
3621         if(pinfo->desegment_len) {
3622             if (!PINFO_FD_VISITED(pinfo))
3623                 must_desegment = TRUE;
3624 
3625             /*
3626              * Set "deseg_offset" to the offset in "tvb"
3627              * of the first byte of data that the
3628              * subdissector didn't process.
3629              */
3630             deseg_offset = offset + pinfo->desegment_offset;
3631         }
3632 
3633         /* Either no desegmentation is necessary, or this is
3634          * segment contains the beginning but not the end of
3635          * a higher-level PDU and thus isn't completely
3636          * desegmented.
3637          */
3638         ipfd_head = NULL;
3639     }
3640 
3641 
3642     /* is it completely desegmented? */
3643     if (ipfd_head) {
3644         /*
3645          * Yes, we think it is.
3646          * We only call subdissector for the last segment.
3647          * Note that the last segment may include more than what
3648          * we needed.
3649          */
3650         if(ipfd_head->reassembled_in == pinfo->num) {
3651             /*
3652              * OK, this is the last segment.
3653              * Let's call the subdissector with the desegmented
3654              * data.
3655              */
3656             tvbuff_t *next_tvb;
3657             int old_len;
3658 
3659             /* create a new TVB structure for desegmented data */
3660             next_tvb = tvb_new_chain(tvb, ipfd_head->tvb_data);
3661 
3662             /* add desegmented data to the data source list */
3663             add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
3664 
3665             /*
3666              * Supply the sequence number of the first of the
3667              * reassembled bytes.
3668              */
3669             tcpinfo->seq = msp->seq;
3670 
3671             /* indicate that this is reassembled data */
3672             tcpinfo->is_reassembled = TRUE;
3673 
3674             /* call subdissector */
3675             process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, sport,
3676                                 dport, 0, 0, FALSE, tcpd, tcpinfo);
3677             called_dissector = TRUE;
3678 
3679             /*
3680              * OK, did the subdissector think it was completely
3681              * desegmented, or does it think we need even more
3682              * data?
3683              */
3684             if (reassemble_ooo && !PINFO_FD_VISITED(pinfo) && pinfo->desegment_len) {
3685                 /* "desegment_len" isn't 0, so it needs more data to extend the MSP. */
3686                 msp->flags &= ~MSP_FLAGS_GOT_ALL_SEGMENTS;
3687             }
3688             old_len = (int)(tvb_reported_length(next_tvb) - last_fragment_len);
3689             if (pinfo->desegment_len &&
3690                 pinfo->desegment_offset<=old_len) {
3691                 /*
3692                  * "desegment_len" isn't 0, so it needs more
3693                  * data for something - and "desegment_offset"
3694                  * is before "old_len", so it needs more data
3695                  * to dissect the stuff we thought was
3696                  * completely desegmented (as opposed to the
3697                  * stuff at the beginning being completely
3698                  * desegmented, but the stuff at the end
3699                  * being a new higher-level PDU that also
3700                  * needs desegmentation).
3701                  *
3702                  * If "desegment_offset" is 0, then nothing in the reassembled
3703                  * TCP segments was dissected, so remove the data source.
3704                  */
3705                 if (pinfo->desegment_offset == 0)
3706                     remove_last_data_source(pinfo);
3707                 fragment_set_partial_reassembly(&tcp_reassembly_table,
3708                                                 pinfo, msp->first_frame, NULL);
3709 
3710                 /* Update msp->nxtpdu to point to the new next
3711                  * pdu boundary.
3712                  */
3713                 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
3714                     /* We want reassembly of at least one
3715                      * more segment so set the nxtpdu
3716                      * boundary to one byte into the next
3717                      * segment.
3718                      * This means that the next segment
3719                      * will complete reassembly even if it
3720                      * is only one single byte in length.
3721                      * If this is an OoO segment, then increment the MSP end.
3722                      */
3723                     msp->nxtpdu = MAX(seq + tvb_reported_length_remaining(tvb, offset), msp->nxtpdu) + 1;
3724                     msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
3725                 } else if (pinfo->desegment_len == DESEGMENT_UNTIL_FIN) {
3726                     tcpd->fwd->flags |= TCP_FLOW_REASSEMBLE_UNTIL_FIN;
3727                     /* This is not the first segment, and we thought the
3728                      * reassembly would be done now, but now know we must
3729                      * desgment until FIN. (E.g., HTTP Response with headers
3730                      * split across segments, and no Content-Length or
3731                      * Transfer-Encoding (RFC 7230, Section 3.3.3, case 7.)
3732                      * For the same reasons as below when we encounter
3733                      * DESEGMENT_UNTIL_FIN on the first segment, give
3734                      * msp->nxtpdu a big (but not too big) offset so reassembly
3735                      * will pick up the segments later.
3736                      */
3737                     msp->nxtpdu = msp->seq + 0x40000000;
3738                 } else {
3739                     if (seq + last_fragment_len >= msp->nxtpdu) {
3740                         /* This is the segment (overlapping) the end of the MSP. */
3741                         msp->nxtpdu = seq + last_fragment_len + pinfo->desegment_len;
3742                     } else {
3743                         /* This is a segment before the end of the MSP, so it
3744                          * must be an out-of-order segmented that completed the
3745                          * MSP. The requested additional data is relative to
3746                          * that end.
3747                          */
3748                         msp->nxtpdu += pinfo->desegment_len;
3749                     }
3750                 }
3751 
3752                 /* Since we need at least some more data
3753                  * there can be no pdu following in the
3754                  * tail of this segment.
3755                  */
3756                 another_pdu_follows = 0;
3757                 offset += last_fragment_len;
3758                 seq += last_fragment_len;
3759                 if (tvb_captured_length_remaining(tvb, offset) > 0)
3760                     goto again;
3761             } else {
3762                 /*
3763                  * Show the stuff in this TCP segment as
3764                  * just raw TCP segment data.
3765                  */
3766                 nbytes = another_pdu_follows > 0
3767                     ? another_pdu_follows
3768                     : tvb_reported_length_remaining(tvb, offset);
3769                 proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, offset,
3770                     nbytes, NULL, "TCP segment data (%u byte%s)", nbytes,
3771                     plurality(nbytes, "", "s"));
3772 
3773                 print_tcp_fragment_tree(ipfd_head, tree, tcp_tree, pinfo, next_tvb);
3774 
3775                 /* Did the subdissector ask us to desegment
3776                  * some more data?  This means that the data
3777                  * at the beginning of this segment completed
3778                  * a higher-level PDU, but the data at the
3779                  * end of this segment started a higher-level
3780                  * PDU but didn't complete it.
3781                  *
3782                  * If so, we have to create some structures
3783                  * in our table, but this is something we
3784                  * only do the first time we see this packet.
3785                  */
3786                 if(pinfo->desegment_len) {
3787                     if (!PINFO_FD_VISITED(pinfo))
3788                         must_desegment = TRUE;
3789 
3790                     /* The stuff we couldn't dissect
3791                      * must have come from this segment,
3792                      * so it's all in "tvb".
3793                      *
3794                      * "pinfo->desegment_offset" is
3795                      * relative to the beginning of
3796                      * "next_tvb"; we want an offset
3797                      * relative to the beginning of "tvb".
3798                      *
3799                      * First, compute the offset relative
3800                      * to the *end* of "next_tvb" - i.e.,
3801                      * the number of bytes before the end
3802                      * of "next_tvb" at which the
3803                      * subdissector stopped.  That's the
3804                      * length of "next_tvb" minus the
3805                      * offset, relative to the beginning
3806                      * of "next_tvb, at which the
3807                      * subdissector stopped.
3808                      */
3809                     deseg_offset = ipfd_head->datalen - pinfo->desegment_offset;
3810 
3811                     /* "tvb" and "next_tvb" end at the
3812                      * same byte of data, so the offset
3813                      * relative to the end of "next_tvb"
3814                      * of the byte at which we stopped
3815                      * is also the offset relative to
3816                      * the end of "tvb" of the byte at
3817                      * which we stopped.
3818                      *
3819                      * Convert that back into an offset
3820                      * relative to the beginning of
3821                      * "tvb", by taking the length of
3822                      * "tvb" and subtracting the offset
3823                      * relative to the end.
3824                      */
3825                     deseg_offset = tvb_reported_length(tvb) - deseg_offset;
3826                 }
3827             }
3828         }
3829     }
3830 
3831     if (must_desegment) {
3832         /* If the dissector requested "reassemble until FIN"
3833          * just set this flag for the flow and let reassembly
3834          * proceed at normal.  We will check/pick up these
3835          * reassembled PDUs later down in dissect_tcp() when checking
3836          * for the FIN flag.
3837          */
3838         if (tcpd && pinfo->desegment_len == DESEGMENT_UNTIL_FIN) {
3839             tcpd->fwd->flags |= TCP_FLOW_REASSEMBLE_UNTIL_FIN;
3840         }
3841         /*
3842          * The sequence number at which the stuff to be desegmented
3843          * starts is the sequence number of the byte at an offset
3844          * of "deseg_offset" into "tvb".
3845          *
3846          * The sequence number of the byte at an offset of "offset"
3847          * is "seq", i.e. the starting sequence number of this
3848          * segment, so the sequence number of the byte at
3849          * "deseg_offset" is "seq + (deseg_offset - offset)".
3850          */
3851         deseg_seq = seq + (deseg_offset - offset);
3852 
3853         if (tcpd && ((nxtseq - deseg_seq) <= 1024*1024)
3854             && (!PINFO_FD_VISITED(pinfo))) {
3855             if(pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
3856                 /* The subdissector asked to reassemble using the
3857                  * entire next segment.
3858                  * Just ask reassembly for one more byte
3859                  * but set this msp flag so we can pick it up
3860                  * above.
3861                  */
3862                 msp = pdu_store_sequencenumber_of_next_pdu(pinfo, deseg_seq,
3863                     nxtseq+1, tcpd->fwd->multisegment_pdus);
3864                 msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
3865             } else if (pinfo->desegment_len == DESEGMENT_UNTIL_FIN) {
3866                 /*
3867                  * The subdissector asked to reassemble at the end of the
3868                  * connection. That will be done in dissect_tcp, but here we
3869                  * have to ask reassembly to collect all future segments.
3870                  * Note that TCP_FLOW_REASSEMBLE_UNTIL_FIN was set before, this
3871                  * ensures that OoO detection is skipped.
3872                  * The exact nxtpdu offset does not matter, but it should be
3873                  * smaller than half of the maximum 32-bit unsigned integer to
3874                  * allow detection of sequence number wraparound, and larger
3875                  * than the largest possible stream size. Hopefully 1GiB
3876                  * (0x40000000 bytes) should be enough.
3877                  */
3878                 msp = pdu_store_sequencenumber_of_next_pdu(pinfo, deseg_seq,
3879                     nxtseq+0x40000000, tcpd->fwd->multisegment_pdus);
3880             } else {
3881                 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
3882                     deseg_seq, nxtseq+pinfo->desegment_len, tcpd->fwd->multisegment_pdus);
3883             }
3884 
3885             /* add this segment as the first one for this new pdu */
3886             fragment_add(&tcp_reassembly_table, tvb, deseg_offset,
3887                          pinfo, msp->first_frame, NULL,
3888                          0, nxtseq - deseg_seq,
3889                          LT_SEQ(nxtseq, msp->nxtpdu));
3890         }
3891     }
3892 
3893     if (!called_dissector || pinfo->desegment_len != 0) {
3894         if (ipfd_head != NULL && ipfd_head->reassembled_in != 0 &&
3895             !(ipfd_head->flags & FD_PARTIAL_REASSEMBLY)) {
3896             /*
3897              * We know what frame this PDU is reassembled in;
3898              * let the user know.
3899              */
3900             item = proto_tree_add_uint(tcp_tree, hf_tcp_reassembled_in, tvb, 0,
3901                                        0, ipfd_head->reassembled_in);
3902             proto_item_set_generated(item);
3903         }
3904 
3905         /*
3906          * Either we didn't call the subdissector at all (i.e.,
3907          * this is a segment that contains the middle of a
3908          * higher-level PDU, but contains neither the beginning
3909          * nor the end), or the subdissector couldn't dissect it
3910          * all, as some data was missing (i.e., it set
3911          * "pinfo->desegment_len" to the amount of additional
3912          * data it needs).
3913          */
3914         if (pinfo->desegment_offset == 0) {
3915             /*
3916              * It couldn't, in fact, dissect any of it (the
3917              * first byte it couldn't dissect is at an offset
3918              * of "pinfo->desegment_offset" from the beginning
3919              * of the payload, and that's 0).
3920              * Just mark this as TCP.
3921              */
3922             col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
3923             col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[TCP segment of a reassembled PDU]");
3924         }
3925 
3926         /*
3927          * Show what's left in the packet as just raw TCP segment
3928          * data.
3929          * XXX - remember what protocol the last subdissector
3930          * was, and report it as a continuation of that, instead?
3931          */
3932         nbytes = tvb_reported_length_remaining(tvb, deseg_offset);
3933 
3934         proto_tree_add_bytes_format(tcp_tree, hf_tcp_segment_data, tvb, deseg_offset,
3935             -1, NULL, "TCP segment data (%u byte%s)", nbytes,
3936             plurality(nbytes, "", "s"));
3937     }
3938     pinfo->can_desegment = 0;
3939     pinfo->desegment_offset = 0;
3940     pinfo->desegment_len = 0;
3941 
3942     if(another_pdu_follows) {
3943         /* there was another pdu following this one. */
3944         pinfo->can_desegment = 2;
3945         /* we also have to prevent the dissector from changing the
3946          * PROTOCOL and INFO columns since what follows may be an
3947          * incomplete PDU and we don't want it be changed back from
3948          *  <Protocol>   to <TCP>
3949          */
3950         col_set_fence(pinfo->cinfo, COL_INFO);
3951         cleared_writable |= col_get_writable(pinfo->cinfo, COL_PROTOCOL);
3952         col_set_writable(pinfo->cinfo, COL_PROTOCOL, FALSE);
3953         offset += another_pdu_follows;
3954         seq += another_pdu_follows;
3955         goto again;
3956     } else {
3957         /* remove any blocking set above otherwise the
3958          * proto,colinfo tap will break
3959          */
3960         if(cleared_writable) {
3961             col_set_writable(pinfo->cinfo, COL_PROTOCOL, TRUE);
3962         }
3963     }
3964 }
3965 
3966 void
tcp_dissect_pdus(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,gboolean proto_desegment,guint fixed_len,guint (* get_pdu_len)(packet_info *,tvbuff_t *,int,void *),dissector_t dissect_pdu,void * dissector_data)3967 tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3968                  gboolean proto_desegment, guint fixed_len,
3969                  guint (*get_pdu_len)(packet_info *, tvbuff_t *, int, void*),
3970                  dissector_t dissect_pdu, void* dissector_data)
3971 {
3972     volatile int offset = 0;
3973     int offset_before;
3974     guint captured_length_remaining;
3975     volatile guint plen;
3976     guint length;
3977     tvbuff_t *next_tvb;
3978     proto_item *item=NULL;
3979     const char *saved_proto;
3980     guint8 curr_layer_num;
3981     wmem_list_frame_t *frame;
3982 
3983     while (tvb_reported_length_remaining(tvb, offset) > 0) {
3984         /*
3985          * We use "tvb_ensure_captured_length_remaining()" to make
3986          * sure there actually *is* data remaining.  The protocol
3987          * we're handling could conceivably consists of a sequence of
3988          * fixed-length PDUs, and therefore the "get_pdu_len" routine
3989          * might not actually fetch anything from the tvbuff, and thus
3990          * might not cause an exception to be thrown if we've run past
3991          * the end of the tvbuff.
3992          *
3993          * This means we're guaranteed that "captured_length_remaining" is positive.
3994          */
3995         captured_length_remaining = tvb_ensure_captured_length_remaining(tvb, offset);
3996 
3997         /*
3998          * Can we do reassembly?
3999          */
4000         if (proto_desegment && pinfo->can_desegment) {
4001             /*
4002              * Yes - is the fixed-length part of the PDU split across segment
4003              * boundaries?
4004              */
4005             if (captured_length_remaining < fixed_len) {
4006                 /*
4007                  * Yes.  Tell the TCP dissector where the data for this message
4008                  * starts in the data it handed us and that we need "some more
4009                  * data."  Don't tell it exactly how many bytes we need because
4010                  * if/when we ask for even more (after the header) that will
4011                  * break reassembly.
4012                  */
4013                 pinfo->desegment_offset = offset;
4014                 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
4015                 return;
4016             }
4017         }
4018 
4019         /*
4020          * Get the length of the PDU.
4021          */
4022         plen = (*get_pdu_len)(pinfo, tvb, offset, dissector_data);
4023         if (plen == 0) {
4024             /*
4025              * Support protocols which have a variable length which cannot
4026              * always be determined within the given fixed_len.
4027              */
4028             DISSECTOR_ASSERT(proto_desegment && pinfo->can_desegment);
4029             pinfo->desegment_offset = offset;
4030             pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
4031             return;
4032         }
4033         if (plen < fixed_len) {
4034             /*
4035              * Either:
4036              *
4037              *  1) the length value extracted from the fixed-length portion
4038              *     doesn't include the fixed-length portion's length, and
4039              *     was so large that, when the fixed-length portion's
4040              *     length was added to it, the total length overflowed;
4041              *
4042              *  2) the length value extracted from the fixed-length portion
4043              *     includes the fixed-length portion's length, and the value
4044              *     was less than the fixed-length portion's length, i.e. it
4045              *     was bogus.
4046              *
4047              * Report this as a bounds error.
4048              */
4049             show_reported_bounds_error(tvb, pinfo, tree);
4050             return;
4051         }
4052 
4053         /* give a hint to TCP where the next PDU starts
4054          * so that it can attempt to find it in case it starts
4055          * somewhere in the middle of a segment.
4056          */
4057         if(!pinfo->fd->visited && tcp_analyze_seq) {
4058             guint remaining_bytes;
4059             remaining_bytes = tvb_reported_length_remaining(tvb, offset);
4060             if(plen>remaining_bytes) {
4061                 pinfo->want_pdu_tracking=2;
4062                 pinfo->bytes_until_next_pdu=plen-remaining_bytes;
4063             }
4064         }
4065 
4066         /*
4067          * Can we do reassembly?
4068          */
4069         if (proto_desegment && pinfo->can_desegment) {
4070             /*
4071              * Yes - is the PDU split across segment boundaries?
4072              */
4073             if (captured_length_remaining < plen) {
4074                 /*
4075                  * Yes.  Tell the TCP dissector where the data for this message
4076                  * starts in the data it handed us, and how many more bytes we
4077                  * need, and return.
4078                  */
4079                 pinfo->desegment_offset = offset;
4080                 pinfo->desegment_len = plen - captured_length_remaining;
4081                 return;
4082             }
4083         }
4084 
4085         curr_layer_num = pinfo->curr_layer_num-1;
4086         frame = wmem_list_frame_prev(wmem_list_tail(pinfo->layers));
4087         while (frame && (proto_tcp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame)))) {
4088             frame = wmem_list_frame_prev(frame);
4089             curr_layer_num--;
4090         }
4091 #if 0
4092         if (captured_length_remaining >= plen || there are more packets)
4093         {
4094 #endif
4095                 /*
4096                  * Display the PDU length as a field
4097                  */
4098                 item=proto_tree_add_uint((proto_tree *)p_get_proto_data(pinfo->pool, pinfo, proto_tcp, curr_layer_num),
4099                                          hf_tcp_pdu_size,
4100                                          tvb, offset, plen, plen);
4101                 proto_item_set_generated(item);
4102 #if 0
4103         } else {
4104                 item = proto_tree_add_expert_format((proto_tree *)p_get_proto_data(pinfo->pool, pinfo, proto_tcp, curr_layer_num),
4105                                         tvb, offset, -1,
4106                     "PDU Size: %u cut short at %u",plen,captured_length_remaining);
4107                 proto_item_set_generated(item);
4108         }
4109 #endif
4110 
4111         /*
4112          * Construct a tvbuff containing the amount of the payload we have
4113          * available.  Make its reported length the amount of data in the PDU.
4114          */
4115         length = captured_length_remaining;
4116         if (length > plen)
4117             length = plen;
4118         next_tvb = tvb_new_subset_length_caplen(tvb, offset, length, plen);
4119 
4120         /*
4121          * Dissect the PDU.
4122          *
4123          * If it gets an error that means there's no point in
4124          * dissecting any more PDUs, rethrow the exception in
4125          * question.
4126          *
4127          * If it gets any other error, report it and continue, as that
4128          * means that PDU got an error, but that doesn't mean we should
4129          * stop dissecting PDUs within this frame or chunk of reassembled
4130          * data.
4131          */
4132         saved_proto = pinfo->current_proto;
4133         TRY {
4134             (*dissect_pdu)(next_tvb, pinfo, tree, dissector_data);
4135         }
4136         CATCH_NONFATAL_ERRORS {
4137             show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
4138 
4139             /*
4140              * Restore the saved protocol as well; we do this after
4141              * show_exception(), so that the "Malformed packet" indication
4142              * shows the protocol for which dissection failed.
4143              */
4144             pinfo->current_proto = saved_proto;
4145         }
4146         ENDTRY;
4147 
4148         /*
4149          * Step to the next PDU.
4150          * Make sure we don't overflow.
4151          */
4152         offset_before = offset;
4153         offset += plen;
4154         if (offset <= offset_before)
4155             break;
4156     }
4157 }
4158 
4159 static void
tcp_info_append_uint(packet_info * pinfo,const char * abbrev,guint32 val)4160 tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
4161 {
4162     /* fstr(" %s=%u", abbrev, val) */
4163     col_append_str_uint(pinfo->cinfo, COL_INFO, abbrev, val, " ");
4164 }
4165 
4166 static gboolean
tcp_option_len_check(proto_item * length_item,packet_info * pinfo,guint len,guint optlen)4167 tcp_option_len_check(proto_item* length_item, packet_info *pinfo, guint len, guint optlen)
4168 {
4169     if (len != optlen) {
4170         /* Bogus - option length isn't what it's supposed to be for this option. */
4171         expert_add_info_format(pinfo, length_item, &ei_tcp_opt_len_invalid,
4172                                "option length should be %u", optlen);
4173         return FALSE;
4174     }
4175 
4176     return TRUE;
4177 }
4178 
4179 static int
dissect_tcpopt_unknown(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4180 dissect_tcpopt_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
4181 {
4182     proto_item *item;
4183     proto_tree *exp_tree;
4184     int offset = 0, optlen = tvb_reported_length(tvb);
4185 
4186     item = proto_tree_add_item(tree, proto_tcp_option_unknown, tvb, offset, -1, ENC_NA);
4187     exp_tree = proto_item_add_subtree(item, ett_tcp_unknown_opt);
4188 
4189     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4190     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4191     if (optlen > 2)
4192         proto_tree_add_item(exp_tree, hf_tcp_option_unknown_payload, tvb, offset + 2, optlen - 2, ENC_NA);
4193 
4194     return tvb_captured_length(tvb);
4195 }
4196 
4197 static int
dissect_tcpopt_default_option(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett)4198 dissect_tcpopt_default_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto, int ett)
4199 {
4200     proto_item *item;
4201     proto_tree *exp_tree;
4202     proto_item *length_item;
4203     int offset = 0;
4204 
4205     item = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA);
4206     exp_tree = proto_item_add_subtree(item, ett);
4207 
4208     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4209     length_item = proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4210 
4211     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), 2))
4212         return tvb_captured_length(tvb);
4213 
4214     return tvb_captured_length(tvb);
4215 }
4216 
4217 static int
dissect_tcpopt_recbound(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4218 dissect_tcpopt_recbound(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4219 {
4220     return dissect_tcpopt_default_option(tvb, pinfo, tree, proto_tcp_option_scpsrec, ett_tcp_opt_recbound);
4221 }
4222 
4223 static int
dissect_tcpopt_correxp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4224 dissect_tcpopt_correxp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4225 {
4226     return dissect_tcpopt_default_option(tvb, pinfo, tree, proto_tcp_option_scpscor, ett_tcp_opt_scpscor);
4227 }
4228 
4229 static void
dissect_tcpopt_tfo_payload(tvbuff_t * tvb,int offset,guint optlen,packet_info * pinfo,proto_tree * exp_tree,void * data)4230 dissect_tcpopt_tfo_payload(tvbuff_t *tvb, int offset, guint optlen,
4231     packet_info *pinfo, proto_tree *exp_tree, void *data)
4232 {
4233     proto_item *ti;
4234     struct tcpheader *tcph = (struct tcpheader*)data;
4235     struct tcp_analysis *tcpd;
4236 
4237     if (optlen == 2) {
4238         /* Fast Open Cookie Request */
4239         proto_tree_add_item(exp_tree, hf_tcp_option_fast_open_cookie_request,
4240                             tvb, offset, 2, ENC_NA);
4241         col_append_str(pinfo->cinfo, COL_INFO, " TFO=R");
4242     } else if (optlen > 2) {
4243         /* Fast Open Cookie */
4244         ti = proto_tree_add_item(exp_tree, hf_tcp_option_fast_open_cookie,
4245                             tvb, offset + 2, optlen - 2, ENC_NA);
4246         col_append_str(pinfo->cinfo, COL_INFO, " TFO=C");
4247         if ((tcph->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) {
4248             expert_add_info(pinfo, ti, &ei_tcp_analysis_tfo_syn);
4249 
4250             /* Is this a SYN with data and the cookie? */
4251             if (tcph->th_have_seglen && tcph->th_seglen) {
4252                 tcpd = get_tcp_conversation_data(NULL, pinfo);
4253                 if (tcpd) {
4254                     tcpd->tfo_syn_data = 1;
4255                 }
4256             }
4257         }
4258     }
4259 }
4260 
4261 static int
dissect_tcpopt_tfo(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4262 dissect_tcpopt_tfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4263 {
4264     proto_item *item;
4265     proto_tree *exp_tree;
4266     int offset = 0;
4267 
4268     item = proto_tree_add_item(tree, proto_tcp_option_tfo, tvb, offset, -1, ENC_NA);
4269     exp_tree = proto_item_add_subtree(item, ett_tcp_option_exp);
4270     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4271     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4272 
4273     dissect_tcpopt_tfo_payload(tvb, offset, tvb_reported_length(tvb), pinfo, exp_tree, data);
4274     return tvb_captured_length(tvb);
4275 }
4276 
4277 static int
dissect_tcpopt_exp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4278 dissect_tcpopt_exp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4279 {
4280     proto_item *item;
4281     proto_tree *exp_tree;
4282     guint16 magic;
4283     gint offset = 0, optlen = tvb_reported_length(tvb);
4284 
4285     item = proto_tree_add_item(tree, proto_tcp_option_exp, tvb, offset, -1, ENC_NA);
4286     exp_tree = proto_item_add_subtree(item, ett_tcp_option_exp);
4287 
4288     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4289     proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4290     if (tcp_exp_options_with_magic && ((optlen - 2) > 0)) {
4291         magic = tvb_get_ntohs(tvb, offset + 2);
4292         proto_tree_add_item(exp_tree, hf_tcp_option_exp_magic_number, tvb,
4293                             offset + 2, 2, ENC_BIG_ENDIAN);
4294         switch (magic) {
4295         case 0xf989:  /* RFC7413, TCP Fast Open */
4296             dissect_tcpopt_tfo_payload(tvb, offset+2, optlen-2, pinfo, exp_tree, data);
4297             break;
4298         default:
4299             /* Unknown magic number */
4300             break;
4301         }
4302     } else {
4303         proto_tree_add_item(exp_tree, hf_tcp_option_exp_data, tvb,
4304                             offset + 2, optlen - 2, ENC_NA);
4305         tcp_info_append_uint(pinfo, "Expxx", TRUE);
4306     }
4307     return tvb_captured_length(tvb);
4308 }
4309 
4310 static int
dissect_tcpopt_sack_perm(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4311 dissect_tcpopt_sack_perm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4312 {
4313     proto_item *item;
4314     proto_tree *exp_tree;
4315     proto_item *length_item;
4316     int offset = 0;
4317 
4318     item = proto_tree_add_item(tree, proto_tcp_option_sack_perm, tvb, offset, -1, ENC_NA);
4319     exp_tree = proto_item_add_subtree(item, ett_tcp_option_sack_perm);
4320 
4321     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4322     length_item = proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4323 
4324     tcp_info_append_uint(pinfo, "SACK_PERM", TRUE);
4325 
4326     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_SACK_PERM))
4327         return tvb_captured_length(tvb);
4328 
4329     return tvb_captured_length(tvb);
4330 }
4331 
4332 static int
dissect_tcpopt_mss(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4333 dissect_tcpopt_mss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
4334 {
4335     proto_item *item;
4336     proto_tree *exp_tree;
4337     proto_item *length_item;
4338     int offset = 0;
4339     struct tcpheader *tcph = (struct tcpheader *)data;
4340     guint32 mss;
4341 
4342     item = proto_tree_add_item(tree, proto_tcp_option_mss, tvb, offset, -1, ENC_NA);
4343     exp_tree = proto_item_add_subtree(item, ett_tcp_option_mss);
4344 
4345     if (!(tcph->th_flags & TH_SYN))
4346     {
4347         expert_add_info(pinfo, item, &ei_tcp_option_mss_present);
4348     }
4349 
4350     proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4351     length_item = proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4352 
4353     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_MSS))
4354         return tvb_captured_length(tvb);
4355 
4356     proto_tree_add_item_ret_uint(exp_tree, hf_tcp_option_mss_val, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &mss);
4357     proto_item_append_text(item, ": %u bytes", mss);
4358     tcp_info_append_uint(pinfo, "MSS", mss);
4359 
4360     return tvb_captured_length(tvb);
4361 }
4362 
4363 /* The window scale extension is defined in RFC 1323 */
4364 static int
dissect_tcpopt_wscale(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4365 dissect_tcpopt_wscale(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4366 {
4367     guint8 val;
4368     guint32 shift;
4369     proto_item *wscale_pi, *shift_pi, *gen_pi;
4370     proto_tree *wscale_tree;
4371     proto_item *length_item;
4372     int offset = 0;
4373     struct tcp_analysis *tcpd;
4374 
4375     tcpd=get_tcp_conversation_data(NULL,pinfo);
4376 
4377     wscale_pi = proto_tree_add_item(tree, proto_tcp_option_wscale, tvb, offset, -1, ENC_NA);
4378     wscale_tree = proto_item_add_subtree(wscale_pi, ett_tcp_option_wscale);
4379 
4380     proto_tree_add_item(wscale_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4381     offset += 1;
4382 
4383     length_item = proto_tree_add_item(wscale_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
4384     offset += 1;
4385 
4386     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_WINDOW))
4387         return tvb_captured_length(tvb);
4388 
4389     shift_pi = proto_tree_add_item_ret_uint(wscale_tree, hf_tcp_option_wscale_shift, tvb, offset, 1, ENC_BIG_ENDIAN, &shift);
4390     if (shift > 14) {
4391         /* RFC 1323: "If a Window Scale option is received with a shift.cnt
4392          * value exceeding 14, the TCP should log the error but use 14 instead
4393          * of the specified value." */
4394         shift = 14;
4395         expert_add_info(pinfo, shift_pi, &ei_tcp_option_wscale_shift_invalid);
4396     }
4397 
4398     gen_pi = proto_tree_add_uint(wscale_tree, hf_tcp_option_wscale_multiplier, tvb,
4399                                  offset, 1, 1 << shift);
4400     proto_item_set_generated(gen_pi);
4401     val = tvb_get_guint8(tvb, offset);
4402 
4403     proto_item_append_text(wscale_pi, ": %u (multiply by %u)", val, 1 << shift);
4404 
4405     tcp_info_append_uint(pinfo, "WS", 1 << shift);
4406 
4407     if(!pinfo->fd->visited) {
4408         pdu_store_window_scale_option(shift, tcpd);
4409     }
4410 
4411     return tvb_captured_length(tvb);
4412 }
4413 
4414 static int
dissect_tcpopt_sack(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4415 dissect_tcpopt_sack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
4416 {
4417     proto_tree *field_tree = NULL;
4418     proto_item *tf, *ti;
4419     guint32 leftedge, rightedge;
4420     struct tcp_analysis *tcpd=NULL;
4421     struct tcpheader *tcph = (struct tcpheader *)data;
4422     guint32 base_ack=0;
4423     guint  num_sack_ranges = 0;
4424     int offset = 0;
4425     int sackoffset;
4426     int optlen = tvb_reported_length(tvb);
4427 
4428     /*
4429      * SEQ analysis is the condition for both relative analysis obviously,
4430      * and SACK handling for the in-flight update
4431      */
4432     if(tcp_analyze_seq) {
4433         /* find(or create if needed) the conversation for this tcp session */
4434         tcpd=get_tcp_conversation_data(NULL,pinfo);
4435 
4436         if (tcpd) {
4437             if (tcp_relative_seq) {
4438                 base_ack=tcpd->rev->base_seq;
4439             }
4440 
4441             /*
4442              * initialize the number of SACK blocks to 0, it will be
4443              * updated some lines later
4444              */
4445             if (tcp_track_bytes_in_flight && tcpd->fwd->tcp_analyze_seq_info) {
4446                 tcpd->fwd->tcp_analyze_seq_info->num_sack_ranges = 0;
4447             }
4448         }
4449     }
4450 
4451     ti = proto_tree_add_item(tree, proto_tcp_option_sack, tvb, offset, -1, ENC_NA);
4452     field_tree = proto_item_add_subtree(ti, ett_tcp_option_sack);
4453 
4454     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
4455                         offset, 1, ENC_BIG_ENDIAN);
4456     proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
4457                         offset + 1, 1, ENC_BIG_ENDIAN);
4458 
4459     offset += 2;    /* skip past type and length */
4460     optlen -= 2;    /* subtract size of type and length */
4461 
4462     sackoffset = offset;
4463     while (optlen > 0) {
4464         if (optlen < 4) {
4465             proto_tree_add_expert(field_tree, pinfo, &ei_tcp_suboption_malformed, tvb, offset, optlen);
4466             break;
4467         }
4468         leftedge = tvb_get_ntohl(tvb, offset)-base_ack;
4469         proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sle, tvb,
4470                                    offset, 4, leftedge,
4471                                    "left edge = %u%s", leftedge,
4472                                    (tcp_analyze_seq && tcp_relative_seq) ? " (relative)" : "");
4473         optlen -= 4;
4474         if (optlen < 4) {
4475             proto_tree_add_expert(field_tree, pinfo, &ei_tcp_suboption_malformed, tvb, offset, optlen);
4476             break;
4477         }
4478         /* XXX - check whether it goes past end of packet */
4479         rightedge = tvb_get_ntohl(tvb, offset + 4)-base_ack;
4480         optlen -= 4;
4481         proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_sre, tvb,
4482                                    offset+4, 4, rightedge,
4483                                    "right edge = %u%s", rightedge,
4484                                    (tcp_analyze_seq && tcp_relative_seq) ? " (relative)" : "");
4485         tcp_info_append_uint(pinfo, "SLE", leftedge);
4486         tcp_info_append_uint(pinfo, "SRE", rightedge);
4487         num_sack_ranges++;
4488 
4489         /* Store blocks for BiF analysis */
4490         if (tcp_analyze_seq && tcpd->fwd->tcp_analyze_seq_info && tcp_track_bytes_in_flight && num_sack_ranges < MAX_TCP_SACK_RANGES) {
4491             tcpd->fwd->tcp_analyze_seq_info->num_sack_ranges = num_sack_ranges;
4492             tcpd->fwd->tcp_analyze_seq_info->sack_left_edge[num_sack_ranges] = leftedge;
4493             tcpd->fwd->tcp_analyze_seq_info->sack_right_edge[num_sack_ranges] = rightedge;
4494         }
4495 
4496         /* Update tap info */
4497         if (tcph != NULL && (tcph->num_sack_ranges < MAX_TCP_SACK_RANGES)) {
4498             tcph->sack_left_edge[tcph->num_sack_ranges] = leftedge;
4499             tcph->sack_right_edge[tcph->num_sack_ranges] = rightedge;
4500             tcph->num_sack_ranges++;
4501         }
4502 
4503         proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
4504         offset += 8;
4505     }
4506 
4507 
4508     /* Show number of SACK ranges in this option as a generated field */
4509     tf = proto_tree_add_uint(field_tree, hf_tcp_option_sack_range_count,
4510                              tvb, 0, 0, num_sack_ranges);
4511     proto_item_set_generated(tf);
4512 
4513     /* RFC 2883 "An Extension to the Selective Acknowledgement (SACK) Option for TCP" aka "D-SACK"
4514      * Section 4
4515      *   Conditions: Either the first sack-block is inside the already acknowledged range or
4516      *               the first sack block is inside the second sack block.
4517      *
4518      * Maybe add later:
4519      * (1) A D-SACK block is only used to report a duplicate contiguous sequence of data received by
4520      *     the receiver in the most recent packet.
4521      */
4522     if (LE_SEQ(tcph->sack_right_edge[0], tcph->th_ack) ||
4523          (tcph->num_sack_ranges > 1 &&
4524           LT_SEQ(tcph->sack_left_edge[1], tcph->sack_right_edge[0]) &&
4525           GE_SEQ(tcph->sack_right_edge[1], tcph->sack_right_edge[0]))
4526     ) {
4527         leftedge = tvb_get_ntohl(tvb, sackoffset)-base_ack;
4528         tf = proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_dsack_le, tvb, sackoffset, 4, leftedge,
4529             "D-SACK Left Edge = %u%s", leftedge, (tcp_analyze_seq && tcp_relative_seq) ? " (relative)" : "");
4530         proto_item_set_generated(tf);
4531         rightedge = tvb_get_ntohl(tvb, sackoffset+4)-base_ack;
4532         tf = proto_tree_add_uint_format(field_tree, hf_tcp_option_sack_dsack_re, tvb, sackoffset+4, 4, rightedge,
4533             "D-SACK Right Edge = %u%s", rightedge, (tcp_analyze_seq && tcp_relative_seq) ? " (relative)" : "");
4534         proto_item_set_generated(tf);
4535         proto_tree_add_expert(field_tree, pinfo, &ei_tcp_option_sack_dsack, tvb, sackoffset, 8);
4536     }
4537 
4538     return tvb_captured_length(tvb);
4539 }
4540 
4541 static int
dissect_tcpopt_echo(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4542 dissect_tcpopt_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4543 {
4544     proto_tree *field_tree;
4545     proto_item *item;
4546     proto_item *length_item;
4547     guint32 echo;
4548     int offset = 0;
4549 
4550     item = proto_tree_add_item(tree, proto_tcp_option_echo, tvb, offset, -1, ENC_NA);
4551     field_tree = proto_item_add_subtree(item, ett_tcp_opt_echo);
4552 
4553     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
4554                         offset, 1, ENC_BIG_ENDIAN);
4555     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
4556                         offset + 1, 1, ENC_BIG_ENDIAN);
4557 
4558     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_ECHO))
4559         return tvb_captured_length(tvb);
4560 
4561     proto_tree_add_item_ret_uint(field_tree, hf_tcp_option_echo, tvb,
4562                         offset + 2, 4, ENC_BIG_ENDIAN, &echo);
4563 
4564     proto_item_append_text(item, ": %u", echo);
4565     tcp_info_append_uint(pinfo, "ECHO", echo);
4566 
4567     return tvb_captured_length(tvb);
4568 }
4569 
4570 /* If set, do not put the TCP timestamp information on the summary line */
4571 static gboolean tcp_ignore_timestamps = FALSE;
4572 
4573 static int
dissect_tcpopt_timestamp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4574 dissect_tcpopt_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4575 {
4576     proto_item *ti;
4577     proto_tree *ts_tree;
4578     proto_item *length_item;
4579     int offset = 0;
4580     guint32 ts_val, ts_ecr;
4581     int len = tvb_reported_length(tvb);
4582 
4583     ti = proto_tree_add_item(tree, proto_tcp_option_timestamp, tvb, offset, -1, ENC_NA);
4584     ts_tree = proto_item_add_subtree(ti, ett_tcp_option_timestamp);
4585 
4586     proto_tree_add_item(ts_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4587     offset += 1;
4588 
4589     length_item = proto_tree_add_item(ts_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
4590     offset += 1;
4591 
4592     if (!tcp_option_len_check(length_item, pinfo, len, TCPOLEN_TIMESTAMP))
4593         return tvb_captured_length(tvb);
4594 
4595     proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsval, tvb, offset,
4596                         4, ENC_BIG_ENDIAN, &ts_val);
4597     offset += 4;
4598 
4599     proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsecr, tvb, offset,
4600                         4, ENC_BIG_ENDIAN, &ts_ecr);
4601     /* offset += 4; */
4602 
4603     proto_item_append_text(ti, ": TSval %u, TSecr %u", ts_val, ts_ecr);
4604     if (tcp_ignore_timestamps == FALSE) {
4605         tcp_info_append_uint(pinfo, "TSval", ts_val);
4606         tcp_info_append_uint(pinfo, "TSecr", ts_ecr);
4607     }
4608 
4609     return tvb_captured_length(tvb);
4610 }
4611 
4612 static struct mptcp_analysis*
mptcp_alloc_analysis(struct tcp_analysis * tcpd)4613 mptcp_alloc_analysis(struct tcp_analysis* tcpd) {
4614 
4615     struct mptcp_analysis* mptcpd;
4616 
4617     DISSECTOR_ASSERT(tcpd->mptcp_analysis == 0);
4618 
4619     mptcpd = (struct mptcp_analysis*)wmem_new0(wmem_file_scope(), struct mptcp_analysis);
4620     mptcpd->subflows = wmem_list_new(wmem_file_scope());
4621 
4622     mptcpd->stream = mptcp_stream_count++;
4623     tcpd->mptcp_analysis = mptcpd;
4624 
4625     memset(&mptcpd->meta_flow, 0, 2*sizeof(mptcp_meta_flow_t));
4626 
4627     /* arbitrary assignment. Callers may override this */
4628     tcpd->fwd->mptcp_subflow->meta = &mptcpd->meta_flow[0];
4629     tcpd->rev->mptcp_subflow->meta = &mptcpd->meta_flow[1];
4630 
4631     return mptcpd;
4632 }
4633 
4634 
4635 /* will create necessary structure if fails to find a match on the token */
4636 static struct mptcp_analysis*
mptcp_get_meta_from_token(struct tcp_analysis * tcpd,tcp_flow_t * tcp_flow,guint32 token)4637 mptcp_get_meta_from_token(struct tcp_analysis* tcpd, tcp_flow_t *tcp_flow, guint32 token) {
4638 
4639     struct mptcp_analysis* result = NULL;
4640     struct mptcp_analysis* mptcpd = tcpd->mptcp_analysis;
4641     guint8 assignedMetaId = 0;  /* array id < 2 */
4642 
4643     DISSECTOR_ASSERT(tcp_flow == tcpd->fwd || tcp_flow == tcpd->rev);
4644 
4645 
4646 
4647     /* if token already set for this meta */
4648     if( tcp_flow->mptcp_subflow->meta  && (tcp_flow->mptcp_subflow->meta->static_flags & MPTCP_META_HAS_TOKEN)) {
4649         return mptcpd;
4650     }
4651 
4652     /* else look for a registered meta with this token */
4653     result = (struct mptcp_analysis*)wmem_tree_lookup32(mptcp_tokens, token);
4654 
4655     /* if token already registered than just share it across TCP connections */
4656     if(result) {
4657         mptcpd = result;
4658         mptcp_attach_subflow(mptcpd, tcpd);
4659     }
4660     else {
4661         /* we create it if this connection */
4662         if(!mptcpd) {
4663             /* don't care which meta to choose assign each meta to a direction */
4664             mptcpd = mptcp_alloc_analysis(tcpd);
4665             mptcp_attach_subflow(mptcpd, tcpd);
4666         }
4667         else {
4668 
4669             /* already exists, thus some meta may already have been configured */
4670             if(mptcpd->meta_flow[0].static_flags & MPTCP_META_HAS_TOKEN) {
4671                 assignedMetaId = 1;
4672             }
4673             else if(mptcpd->meta_flow[1].static_flags & MPTCP_META_HAS_TOKEN) {
4674                 assignedMetaId = 0;
4675             }
4676             else {
4677                 DISSECTOR_ASSERT_NOT_REACHED();
4678             }
4679             tcp_flow->mptcp_subflow->meta = &mptcpd->meta_flow[assignedMetaId];
4680         }
4681         DISSECTOR_ASSERT(tcp_flow->mptcp_subflow->meta);
4682 
4683         tcp_flow->mptcp_subflow->meta->token = token;
4684         tcp_flow->mptcp_subflow->meta->static_flags |= MPTCP_META_HAS_TOKEN;
4685 
4686         wmem_tree_insert32(mptcp_tokens, token, mptcpd);
4687     }
4688 
4689     DISSECTOR_ASSERT(mptcpd);
4690 
4691 
4692     /* compute the meta id assigned to tcp_flow */
4693     assignedMetaId = (tcp_flow->mptcp_subflow->meta == &mptcpd->meta_flow[0]) ? 0 : 1;
4694 
4695     /* computes the metaId tcpd->fwd should be assigned to */
4696     assignedMetaId = (tcp_flow == tcpd->fwd) ? assignedMetaId : (assignedMetaId +1) %2;
4697 
4698     tcpd->fwd->mptcp_subflow->meta = &mptcpd->meta_flow[ (assignedMetaId) ];
4699     tcpd->rev->mptcp_subflow->meta = &mptcpd->meta_flow[ (assignedMetaId +1) %2];
4700 
4701     return mptcpd;
4702 }
4703 
4704 /* setup from_key */
4705 static
4706 struct mptcp_analysis*
get_or_create_mptcpd_from_key(struct tcp_analysis * tcpd,tcp_flow_t * fwd,guint8 version,guint64 key,guint8 hmac_algo _U_)4707 get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint8 version, guint64 key, guint8 hmac_algo _U_) {
4708 
4709     guint32 token = 0;
4710     guint64 expected_idsn= 0;
4711     struct mptcp_analysis* mptcpd = tcpd->mptcp_analysis;
4712 
4713     if(fwd->mptcp_subflow->meta && (fwd->mptcp_subflow->meta->static_flags & MPTCP_META_HAS_KEY)) {
4714         return mptcpd;
4715     }
4716 
4717     /* MPTCP v0 only standardizes SHA1, and v1 SHA256. */
4718     if (version == 0)
4719         mptcp_cryptodata_sha1(key, &token, &expected_idsn);
4720     else if (version == 1)
4721         mptcp_cryptodata_sha256(key, &token, &expected_idsn);
4722 
4723     mptcpd = mptcp_get_meta_from_token(tcpd, fwd, token);
4724 
4725     DISSECTOR_ASSERT(fwd->mptcp_subflow->meta);
4726 
4727     fwd->mptcp_subflow->meta->version = version;
4728     fwd->mptcp_subflow->meta->key = key;
4729     fwd->mptcp_subflow->meta->static_flags |= MPTCP_META_HAS_KEY;
4730     fwd->mptcp_subflow->meta->base_dsn = expected_idsn;
4731     return mptcpd;
4732 }
4733 
4734 /* record this mapping */
4735 static
analyze_mapping(struct tcp_analysis * tcpd,packet_info * pinfo,guint16 len,guint64 dsn,gboolean extended,guint32 ssn)4736 void analyze_mapping(struct tcp_analysis *tcpd, packet_info *pinfo, guint16 len, guint64 dsn, gboolean extended, guint32 ssn) {
4737 
4738     /* store mapping only if analysis is enabled and mapping is not unlimited */
4739     if (!mptcp_analyze_mappings || !len) {
4740         return;
4741     }
4742 
4743     if (PINFO_FD_VISITED(pinfo)) {
4744         return;
4745     }
4746 
4747     /* register SSN range described by the mapping into a subflow interval_tree */
4748     mptcp_dss_mapping_t *mapping = NULL;
4749     mapping = wmem_new0(wmem_file_scope(), mptcp_dss_mapping_t);
4750 
4751     mapping->rawdsn  = dsn;
4752     mapping->extended_dsn = extended;
4753     mapping->frame = pinfo->fd->num;
4754     mapping->ssn_low = ssn;
4755     mapping->ssn_high = ssn + len - 1;
4756 
4757     wmem_itree_insert(tcpd->fwd->mptcp_subflow->ssn2dsn_mappings,
4758         mapping->ssn_low,
4759         mapping->ssn_high,
4760         mapping
4761         );
4762 }
4763 
4764 /*
4765  * The TCP Extensions for Multipath Operation with Multiple Addresses
4766  * are defined in RFC 6824
4767  *
4768  * https://tools.ietf.org/html/rfc6824
4769  *
4770  * Author: Andrei Maruseac <andrei.maruseac@intel.com>
4771  *         Matthieu Coudron <matthieu.coudron@lip6.fr>
4772  *
4773  * This function just generates the mptcpheader, i.e. the generation of
4774  * datastructures is delayed/delegated to mptcp_analyze
4775  */
4776 static int
dissect_tcpopt_mptcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4777 dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
4778 {
4779     proto_item *item,*main_item;
4780     proto_tree *mptcp_tree;
4781 
4782     guint32 version;
4783     guint8 subtype;
4784     guint8 ipver;
4785     int offset = 0;
4786     int optlen = tvb_reported_length(tvb);
4787     int start_offset = offset;
4788     struct tcp_analysis *tcpd = NULL;
4789     struct mptcp_analysis* mptcpd = NULL;
4790     struct tcpheader *tcph = (struct tcpheader *)data;
4791 
4792     /* There may be several MPTCP options per packet, don't duplicate the structure */
4793     struct mptcpheader* mph = tcph->th_mptcp;
4794 
4795     if(!mph) {
4796         mph = wmem_new0(pinfo->pool, struct mptcpheader);
4797         tcph->th_mptcp = mph;
4798     }
4799 
4800     tcpd=get_tcp_conversation_data(NULL,pinfo);
4801     mptcpd=tcpd->mptcp_analysis;
4802 
4803     /* seeing an MPTCP packet on the subflow automatically qualifies it as an mptcp subflow */
4804     if(!tcpd->fwd->mptcp_subflow) {
4805          mptcp_init_subflow(tcpd->fwd);
4806     }
4807     if(!tcpd->rev->mptcp_subflow) {
4808          mptcp_init_subflow(tcpd->rev);
4809     }
4810 
4811     col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPTCP");
4812     main_item = proto_tree_add_item(tree, proto_mptcp, tvb, offset, -1, ENC_NA);
4813     mptcp_tree = proto_item_add_subtree(main_item, ett_tcp_option_mptcp);
4814 
4815     proto_tree_add_item(mptcp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
4816     offset += 1;
4817 
4818     proto_tree_add_item(mptcp_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
4819     offset += 1;
4820 
4821     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_subtype, tvb,
4822                         offset, 1, ENC_BIG_ENDIAN);
4823 
4824     subtype = tvb_get_guint8(tvb, offset) >> 4;
4825     proto_item_append_text(main_item, ": %s", val_to_str(subtype, mptcp_subtype_vs, "Unknown (%d)"));
4826 
4827     /** preemptively allocate mptcpd when subtype won't allow to find a meta */
4828     if(!mptcpd && (subtype > TCPOPT_MPTCP_MP_JOIN)) {
4829         mptcpd = mptcp_alloc_analysis(tcpd);
4830     }
4831 
4832     switch (subtype) {
4833         case TCPOPT_MPTCP_MP_CAPABLE:
4834             mph->mh_mpc = TRUE;
4835 
4836             proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_version, tvb,
4837                         offset, 1, ENC_BIG_ENDIAN, &version);
4838             offset += 1;
4839 
4840             item = proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
4841                          ett_tcp_option_mptcp,
4842                          version == 1 ? tcp_option_mptcp_capable_v1_flags : tcp_option_mptcp_capable_v0_flags,
4843                          ENC_BIG_ENDIAN);
4844             mph->mh_capable_flags = tvb_get_guint8(tvb, offset);
4845             if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) == 0) {
4846                 expert_add_info(pinfo, item, &ei_mptcp_analysis_missing_algorithm);
4847             }
4848             if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) != MPTCP_HMAC_SHA) {
4849                 expert_add_info(pinfo, item, &ei_mptcp_analysis_unsupported_algorithm);
4850             }
4851             offset += 1;
4852 
4853             /* optlen == 12 => SYN or SYN/ACK; optlen == 20 => ACK;
4854              * optlen == 22 => ACK + data (v1 only);
4855              * optlen == 24 => ACK + data + csum (v1 only)
4856              */
4857             if (optlen == 12 || optlen == 20 || optlen == 22 || optlen == 24) {
4858 
4859                 mph->mh_key = tvb_get_ntoh64(tvb,offset);
4860                 proto_tree_add_uint64(mptcp_tree, hf_tcp_option_mptcp_sender_key, tvb, offset, 8, mph->mh_key);
4861                 offset += 8;
4862 
4863                 mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->fwd, version, mph->mh_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK);
4864                 mptcpd->master = tcpd;
4865 
4866                 item = proto_tree_add_uint(mptcp_tree,
4867                       hf_mptcp_expected_token, tvb, offset, 0, tcpd->fwd->mptcp_subflow->meta->token);
4868                 proto_item_set_generated(item);
4869 
4870                 item = proto_tree_add_uint64(mptcp_tree,
4871                       hf_mptcp_expected_idsn, tvb, offset, 0, tcpd->fwd->mptcp_subflow->meta->base_dsn);
4872                 proto_item_set_generated(item);
4873 
4874                 /* last ACK of 3WHS, repeats both keys */
4875                 if (optlen >= 20) {
4876                     guint64 recv_key = tvb_get_ntoh64(tvb,offset);
4877                     proto_tree_add_uint64(mptcp_tree, hf_tcp_option_mptcp_recv_key, tvb, offset, 8, recv_key);
4878                     offset += 8;
4879 
4880                     if(tcpd->rev->mptcp_subflow->meta
4881                         && (tcpd->rev->mptcp_subflow->meta->static_flags & MPTCP_META_HAS_KEY)) {
4882 
4883                         /* compare the echoed key with the server key */
4884                         if(tcpd->rev->mptcp_subflow->meta->key != recv_key) {
4885                             expert_add_info(pinfo, item, &ei_mptcp_analysis_echoed_key_mismatch);
4886                         }
4887                     }
4888                     else {
4889                         mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->rev, version, recv_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK);
4890                     }
4891                 }
4892 
4893                 /* MPTCP v1 ACK + data, contains data_len and optional checksum */
4894                 if (optlen >= 22) {
4895                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_data_lvl_len, tvb, offset, 2, ENC_BIG_ENDIAN);
4896                     mph->mh_dss_length = tvb_get_ntohs(tvb,offset);
4897                     offset += 2;
4898 
4899                     if (mph->mh_dss_length == 0) {
4900                         expert_add_info(pinfo, mptcp_tree, &ei_mptcp_infinite_mapping);
4901                     }
4902 
4903                     /* when data len is present, this MP_CAPABLE also carries an implicit mapping ... */
4904                     analyze_mapping(tcpd, pinfo, mph->mh_dss_length, tcpd->fwd->mptcp_subflow->meta->base_dsn + 1, TRUE, tcph->th_seq);
4905 
4906                     /* ... with optional checksum */
4907                     if (optlen == 24)
4908                     {
4909                         proto_tree_add_checksum(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
4910                     }
4911                 }
4912             }
4913             break;
4914 
4915         case TCPOPT_MPTCP_MP_JOIN:
4916             mph->mh_join = TRUE;
4917             if(optlen != 12 && !mptcpd) {
4918                 mptcpd = mptcp_alloc_analysis(tcpd);
4919             }
4920             switch (optlen) {
4921                 /* Syn */
4922                 case 12:
4923                     {
4924                     proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
4925                          ett_tcp_option_mptcp, tcp_option_mptcp_join_flags,
4926                          ENC_BIG_ENDIAN);
4927                     offset += 1;
4928                     tcpd->fwd->mptcp_subflow->address_id = tvb_get_guint8(tvb, offset);
4929                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_address_id, tvb, offset,
4930                             1, ENC_BIG_ENDIAN);
4931                     offset += 1;
4932 
4933                     proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_recv_token, tvb, offset,
4934                             4, ENC_BIG_ENDIAN, &mph->mh_token);
4935                     offset += 4;
4936 
4937                     mptcpd = mptcp_get_meta_from_token(tcpd, tcpd->rev, mph->mh_token);
4938                     if (tcpd->fwd->mptcp_subflow->meta->version == 1) {
4939                         mptcp_meta_flow_t *tmp = tcpd->fwd->mptcp_subflow->meta;
4940 
4941                         /* if the negotiated version is v1 the first key was exchanged on SYN/ACK packet: we must swap the meta */
4942                         tcpd->fwd->mptcp_subflow->meta = tcpd->rev->mptcp_subflow->meta;
4943                         tcpd->rev->mptcp_subflow->meta = tmp;
4944                     }
4945 
4946                     proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_sender_rand, tvb, offset,
4947                             4, ENC_BIG_ENDIAN, &tcpd->fwd->mptcp_subflow->nonce);
4948 
4949                     }
4950                     break;
4951 
4952 
4953                 case 16:    /* Syn/Ack */
4954                     proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
4955                          ett_tcp_option_mptcp, tcp_option_mptcp_join_flags,
4956                          ENC_BIG_ENDIAN);
4957                     offset += 1;
4958 
4959                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_address_id, tvb, offset,
4960                             1, ENC_BIG_ENDIAN);
4961                     offset += 1;
4962 
4963                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_sender_trunc_hmac, tvb, offset,
4964                             8, ENC_BIG_ENDIAN);
4965                     offset += 8;
4966 
4967                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_sender_rand, tvb, offset,
4968                             4, ENC_BIG_ENDIAN);
4969                     break;
4970 
4971                 case 24:    /* Ack */
4972                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_reserved, tvb, offset,
4973                             2, ENC_BIG_ENDIAN);
4974                     offset += 2;
4975 
4976                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_sender_hmac, tvb, offset,
4977                                 20, ENC_NA);
4978                     break;
4979 
4980                 default:
4981                     break;
4982             }
4983             break;
4984 
4985         /* display only *raw* values since it is harder to guess a correct value than for TCP.
4986         One needs to enable mptcp_analysis to get more interesting data
4987          */
4988         case TCPOPT_MPTCP_DSS:
4989             mph->mh_dss = TRUE;
4990 
4991             offset += 1;
4992             mph->mh_dss_flags = tvb_get_guint8(tvb, offset) & 0x1F;
4993 
4994             proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
4995                          ett_tcp_option_mptcp, tcp_option_mptcp_dss_flags,
4996                          ENC_BIG_ENDIAN);
4997             offset += 1;
4998 
4999             /* displays "raw" DataAck , ie does not convert it to its 64 bits form
5000             to do so you need to enable
5001             */
5002             if (mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_PRESENT) {
5003 
5004                 guint64 dack64;
5005 
5006                 /* 64bits ack */
5007                 if (mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_8BYTES) {
5008 
5009                     mph->mh_dss_rawack = tvb_get_ntoh64(tvb,offset);
5010                     proto_tree_add_uint64_format_value(mptcp_tree, hf_tcp_option_mptcp_data_ack_raw, tvb, offset, 8, mph->mh_dss_rawack, "%" G_GINT64_MODIFIER "u (64bits)", mph->mh_dss_rawack);
5011                     offset += 8;
5012                 }
5013                 /* 32bits ack */
5014                 else {
5015                     mph->mh_dss_rawack = tvb_get_ntohl(tvb,offset);
5016                     proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_data_ack_raw, tvb, offset, 4, ENC_BIG_ENDIAN);
5017                     offset += 4;
5018                 }
5019 
5020                 if(mptcp_convert_dsn(mph->mh_dss_rawack, tcpd->rev->mptcp_subflow->meta,
5021                     (mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_8BYTES) ? DSN_CONV_NONE : DSN_CONV_32_TO_64, mptcp_relative_seq, &dack64)) {
5022                     item = proto_tree_add_uint64(mptcp_tree, hf_mptcp_ack, tvb, 0, 0, dack64);
5023                     if (mptcp_relative_seq) {
5024                         proto_item_append_text(item, " (Relative)");
5025                     }
5026 
5027                     proto_item_set_generated(item);
5028                 }
5029                 else {
5030                     /* ignore and continue */
5031                 }
5032 
5033             }
5034 
5035             /* Mapping present */
5036             if (mph->mh_dss_flags & MPTCP_DSS_FLAG_MAPPING_PRESENT) {
5037 
5038                 guint64 dsn;
5039 
5040                 if (mph->mh_dss_flags & MPTCP_DSS_FLAG_DSN_8BYTES) {
5041 
5042                     dsn = tvb_get_ntoh64(tvb,offset);
5043                     proto_tree_add_uint64_format_value(mptcp_tree, hf_tcp_option_mptcp_data_seq_no_raw, tvb, offset, 8, dsn,  "%" G_GINT64_MODIFIER "u  (64bits version)", dsn);
5044 
5045                     /* if we have the opportunity to complete the 32 Most Significant Bits of the
5046                      *
5047                      */
5048                     if(!(tcpd->fwd->mptcp_subflow->meta->static_flags & MPTCP_META_HAS_BASE_DSN_MSB)) {
5049                         tcpd->fwd->mptcp_subflow->meta->static_flags |= MPTCP_META_HAS_BASE_DSN_MSB;
5050                         tcpd->fwd->mptcp_subflow->meta->base_dsn |= (dsn & (guint32) 0);
5051                     }
5052                     offset += 8;
5053                 } else {
5054                     dsn = tvb_get_ntohl(tvb,offset);
5055                     proto_tree_add_uint64_format_value(mptcp_tree, hf_tcp_option_mptcp_data_seq_no_raw, tvb, offset, 4, dsn,  "%" G_GINT64_MODIFIER "u  (32bits version)", dsn);
5056                     offset += 4;
5057                 }
5058                 mph->mh_dss_rawdsn = dsn;
5059 
5060                 proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_subflow_seq_no, tvb, offset, 4, ENC_BIG_ENDIAN, &mph->mh_dss_ssn);
5061                 offset += 4;
5062 
5063                 proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_data_lvl_len, tvb, offset, 2, ENC_BIG_ENDIAN);
5064                 mph->mh_dss_length = tvb_get_ntohs(tvb,offset);
5065                 offset += 2;
5066 
5067                 if(mph->mh_dss_length == 0) {
5068                     expert_add_info(pinfo, mptcp_tree, &ei_mptcp_infinite_mapping);
5069                 }
5070 
5071                 /* print head & tail dsn */
5072                 if(mptcp_convert_dsn(mph->mh_dss_rawdsn, tcpd->fwd->mptcp_subflow->meta,
5073                     (mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_8BYTES) ? DSN_CONV_NONE : DSN_CONV_32_TO_64, mptcp_relative_seq, &dsn)) {
5074                     item = proto_tree_add_uint64(mptcp_tree, hf_mptcp_dss_dsn, tvb, 0, 0, dsn);
5075                     if (mptcp_relative_seq) {
5076                             proto_item_append_text(item, " (Relative)");
5077                     }
5078 
5079                     proto_item_set_generated(item);
5080                 }
5081                 else {
5082                     /* ignore and continue */
5083                 }
5084 
5085                 analyze_mapping(tcpd, pinfo, mph->mh_dss_length, mph->mh_dss_rawdsn, mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_8BYTES, mph->mh_dss_ssn);
5086 
5087                 if ((int)optlen >= offset-start_offset+4)
5088                 {
5089                     proto_tree_add_checksum(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
5090                 }
5091             }
5092             break;
5093 
5094         case TCPOPT_MPTCP_ADD_ADDR:
5095             mph->mh_add = TRUE;
5096             ipver = tvb_get_guint8(tvb, offset) & 0x0F;
5097             if (ipver == 4 || ipver == 6)
5098                 proto_tree_add_item(mptcp_tree,
5099                             hf_tcp_option_mptcp_ipver, tvb, offset, 1, ENC_BIG_ENDIAN);
5100             else
5101                 proto_tree_add_item(mptcp_tree,
5102                             hf_tcp_option_mptcp_echo, tvb, offset, 1, ENC_BIG_ENDIAN);
5103             offset += 1;
5104 
5105             proto_tree_add_item(mptcp_tree,
5106                     hf_tcp_option_mptcp_address_id, tvb, offset, 1, ENC_BIG_ENDIAN);
5107             offset += 1;
5108 
5109             if (optlen == 8 || optlen == 10 || optlen == 16 || optlen == 18) {
5110                 proto_tree_add_item(mptcp_tree,
5111                             hf_tcp_option_mptcp_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
5112                 offset += 4;
5113             }
5114 
5115             if (optlen == 20 || optlen == 22 || optlen == 28 || optlen == 30) {
5116                 proto_tree_add_item(mptcp_tree,
5117                             hf_tcp_option_mptcp_ipv6, tvb, offset, 16, ENC_NA);
5118                 offset += 16;
5119             }
5120 
5121             if (optlen == 10 || optlen == 18 || optlen == 22 || optlen == 30) {
5122                 proto_tree_add_item(mptcp_tree,
5123                             hf_tcp_option_mptcp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
5124                 offset += 2;
5125             }
5126 
5127             if (optlen == 16 || optlen == 18 || optlen == 28 || optlen == 30) {
5128                 proto_tree_add_item(mptcp_tree,
5129                             hf_tcp_option_mptcp_addaddr_trunc_hmac, tvb, offset, 8, ENC_BIG_ENDIAN);
5130             }
5131             break;
5132 
5133         case TCPOPT_MPTCP_REMOVE_ADDR:
5134             mph->mh_remove = TRUE;
5135             item = proto_tree_add_uint(mptcp_tree, hf_mptcp_number_of_removed_addresses, tvb, start_offset+2,
5136                 1, optlen - 3);
5137             proto_item_set_generated(item);
5138             offset += 1;
5139             while(offset < start_offset + (int)optlen) {
5140                 proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_address_id, tvb, offset,
5141                                 1, ENC_BIG_ENDIAN);
5142                 offset += 1;
5143             }
5144             break;
5145 
5146         case TCPOPT_MPTCP_MP_PRIO:
5147             mph->mh_prio = TRUE;
5148             proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
5149                          ett_tcp_option_mptcp, tcp_option_mptcp_join_flags,
5150                          ENC_BIG_ENDIAN);
5151             offset += 1;
5152 
5153             if (optlen == 4) {
5154                 proto_tree_add_item(mptcp_tree,
5155                         hf_tcp_option_mptcp_address_id, tvb, offset, 1, ENC_BIG_ENDIAN);
5156             }
5157             break;
5158 
5159         case TCPOPT_MPTCP_MP_FAIL:
5160             mph->mh_fail = TRUE;
5161             proto_tree_add_item(mptcp_tree,
5162                     hf_tcp_option_mptcp_reserved, tvb, offset,2, ENC_BIG_ENDIAN);
5163             offset += 2;
5164 
5165             proto_tree_add_item(mptcp_tree,
5166                     hf_tcp_option_mptcp_data_seq_no_raw, tvb, offset, 8, ENC_BIG_ENDIAN);
5167             break;
5168 
5169         case TCPOPT_MPTCP_MP_FASTCLOSE:
5170             mph->mh_fastclose = TRUE;
5171             proto_tree_add_item(mptcp_tree,
5172                     hf_tcp_option_mptcp_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
5173             offset += 2;
5174 
5175             proto_tree_add_item(mptcp_tree,
5176                     hf_tcp_option_mptcp_recv_key, tvb, offset, 8, ENC_BIG_ENDIAN);
5177             mph->mh_key = tvb_get_ntoh64(tvb,offset);
5178             break;
5179 
5180         case TCPOPT_MPTCP_MP_TCPRST:
5181             mph->mh_tcprst = TRUE;
5182             proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags,
5183                                    ett_tcp_option_mptcp, tcp_option_mptcp_tcprst_flags,
5184                                    ENC_BIG_ENDIAN);
5185             offset += 1;
5186             proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_tcprst_reason, tvb,  offset, 1,
5187                                 ENC_BIG_ENDIAN);
5188             break;
5189 
5190         default:
5191             break;
5192     }
5193 
5194     if ((mptcpd != NULL) && (tcpd->mptcp_analysis != NULL)) {
5195 
5196         /* if mptcpd just got allocated, remember the initial addresses
5197          * which will serve as identifiers for the conversation filter
5198          */
5199         if(tcpd->fwd->mptcp_subflow->meta->ip_src.len == 0) {
5200 
5201             copy_address_wmem(wmem_file_scope(), &tcpd->fwd->mptcp_subflow->meta->ip_src, &tcph->ip_src);
5202             copy_address_wmem(wmem_file_scope(), &tcpd->fwd->mptcp_subflow->meta->ip_dst, &tcph->ip_dst);
5203 
5204             copy_address_shallow(&tcpd->rev->mptcp_subflow->meta->ip_src, &tcpd->fwd->mptcp_subflow->meta->ip_dst);
5205             copy_address_shallow(&tcpd->rev->mptcp_subflow->meta->ip_dst, &tcpd->fwd->mptcp_subflow->meta->ip_src);
5206 
5207             tcpd->fwd->mptcp_subflow->meta->sport = tcph->th_sport;
5208             tcpd->fwd->mptcp_subflow->meta->dport = tcph->th_dport;
5209         }
5210 
5211         mph->mh_stream = tcpd->mptcp_analysis->stream;
5212     }
5213 
5214     return tvb_captured_length(tvb);
5215 }
5216 
5217 static int
dissect_tcpopt_cc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5218 dissect_tcpopt_cc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5219 {
5220     proto_tree *field_tree;
5221     proto_item *item;
5222     proto_item *length_item;
5223     int offset = 0;
5224     guint32 cc;
5225 
5226     item = proto_tree_add_item(tree, proto_tcp_option_cc, tvb, offset, -1, ENC_NA);
5227     field_tree = proto_item_add_subtree(item, ett_tcp_opt_cc);
5228 
5229     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5230                         offset, 1, ENC_BIG_ENDIAN);
5231     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5232                         offset + 1, 1, ENC_BIG_ENDIAN);
5233 
5234     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_CC))
5235         return tvb_captured_length(tvb);
5236 
5237     proto_tree_add_item_ret_uint(field_tree, hf_tcp_option_cc, tvb,
5238                         offset + 2, 4, ENC_BIG_ENDIAN, &cc);
5239 
5240     tcp_info_append_uint(pinfo, "CC", cc);
5241     return tvb_captured_length(tvb);
5242 }
5243 
5244 static int
dissect_tcpopt_md5(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5245 dissect_tcpopt_md5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5246 {
5247     proto_tree *field_tree;
5248     proto_item *item;
5249     proto_item *length_item;
5250     int offset = 0, optlen = tvb_reported_length(tvb);
5251 
5252     item = proto_tree_add_item(tree, proto_tcp_option_md5, tvb, offset, -1, ENC_NA);
5253     field_tree = proto_item_add_subtree(item, ett_tcp_opt_md5);
5254 
5255     col_append_lstr(pinfo->cinfo, COL_INFO, " MD5", COL_ADD_LSTR_TERMINATOR);
5256     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5257                         offset, 1, ENC_BIG_ENDIAN);
5258     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5259                                       offset + 1, 1, ENC_BIG_ENDIAN);
5260 
5261     if (!tcp_option_len_check(length_item, pinfo, optlen, TCPOLEN_MD5))
5262         return tvb_captured_length(tvb);
5263 
5264     proto_tree_add_item(field_tree, hf_tcp_option_md5_digest, tvb,
5265                         offset + 2, optlen - 2, ENC_NA);
5266 
5267     return tvb_captured_length(tvb);
5268 }
5269 
5270 static int
dissect_tcpopt_ao(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5271 dissect_tcpopt_ao(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5272 {
5273     proto_tree *field_tree;
5274     proto_item *item;
5275     proto_item *length_item;
5276     int offset = 0, optlen = tvb_reported_length(tvb);
5277 
5278     item = proto_tree_add_item(tree, proto_tcp_option_ao, tvb, offset, -1, ENC_NA);
5279     field_tree = proto_item_add_subtree(item, ett_tcp_opt_ao);
5280 
5281     col_append_lstr(pinfo->cinfo, COL_INFO, "TCP AO", COL_ADD_LSTR_TERMINATOR);
5282     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5283                         offset, 1, ENC_BIG_ENDIAN);
5284     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5285                                       offset + 1, 1, ENC_BIG_ENDIAN);
5286 
5287     if (optlen < 4) {
5288         expert_add_info_format(pinfo, length_item, &ei_tcp_opt_len_invalid,
5289                                "option length should be >= than 4");
5290         return tvb_captured_length(tvb);
5291     }
5292 
5293     proto_tree_add_item(field_tree, hf_tcp_option_ao_keyid, tvb,
5294                         offset + 2, 1, ENC_NA);
5295 
5296     proto_tree_add_item(field_tree, hf_tcp_option_ao_rnextkeyid, tvb,
5297                         offset + 3, 1, ENC_NA);
5298 
5299     if (optlen > 4)
5300         proto_tree_add_item(field_tree, hf_tcp_option_ao_mac, tvb,
5301                             offset + 4, optlen - 4, ENC_NA);
5302 
5303     return tvb_captured_length(tvb);
5304 }
5305 
5306 static int
dissect_tcpopt_qs(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5307 dissect_tcpopt_qs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5308 {
5309     proto_tree *field_tree;
5310     proto_item *item;
5311     proto_item *length_item;
5312     guint8 rate;
5313     int offset = 0;
5314 
5315     item = proto_tree_add_item(tree, proto_tcp_option_qs, tvb, offset, -1, ENC_NA);
5316     field_tree = proto_item_add_subtree(item, ett_tcp_opt_qs);
5317 
5318     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5319                         offset, 1, ENC_BIG_ENDIAN);
5320     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5321                                       offset + 1, 1, ENC_BIG_ENDIAN);
5322 
5323     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_QS))
5324         return tvb_captured_length(tvb);
5325 
5326     rate = tvb_get_guint8(tvb, offset + 2) & 0x0f;
5327     col_append_lstr(pinfo->cinfo, COL_INFO,
5328         " QSresp=", val_to_str_ext_const(rate, &qs_rate_vals_ext, "Unknown"),
5329         COL_ADD_LSTR_TERMINATOR);
5330     proto_tree_add_item(field_tree, hf_tcp_option_qs_rate, tvb,
5331                         offset + 2, 1, ENC_BIG_ENDIAN);
5332     proto_tree_add_item(field_tree, hf_tcp_option_qs_ttl_diff, tvb,
5333                         offset + 3, 1, ENC_BIG_ENDIAN);
5334 
5335     return tvb_captured_length(tvb);
5336 }
5337 
5338 static int
dissect_tcpopt_scps(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5339 dissect_tcpopt_scps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5340 {
5341     struct tcp_analysis *tcpd;
5342     proto_tree *field_tree = NULL;
5343     tcp_flow_t *flow;
5344     int         direction;
5345     proto_item *tf = NULL, *item;
5346     proto_tree *flags_tree = NULL;
5347     guint8      capvector;
5348     guint8      connid;
5349     int         offset = 0, optlen = tvb_reported_length(tvb);
5350 
5351     tcpd = get_tcp_conversation_data(NULL,pinfo);
5352 
5353     /* check direction and get ua lists */
5354     direction=cmp_address(&pinfo->src, &pinfo->dst);
5355 
5356     /* if the addresses are equal, match the ports instead */
5357     if(direction==0) {
5358         direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
5359     }
5360 
5361     if(direction>=0)
5362         flow =&(tcpd->flow1);
5363     else
5364         flow =&(tcpd->flow2);
5365 
5366     item = proto_tree_add_item(tree, proto_tcp_option_scps,
5367                                tvb, offset, -1, ENC_NA);
5368     field_tree = proto_item_add_subtree(item, ett_tcp_option_scps);
5369 
5370     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5371                         offset, 1, ENC_BIG_ENDIAN);
5372     proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5373                         offset + 1, 1, ENC_BIG_ENDIAN);
5374 
5375     /* If the option length == 4, this is a real SCPS capability option
5376      * See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS Transport Protocol
5377      * (SCPS-TP)" Section 3.2.3 for definition.
5378      */
5379     if (optlen == 4) {
5380         tf = proto_tree_add_item(field_tree, hf_tcp_option_scps_vector, tvb,
5381                                  offset + 2, 1, ENC_BIG_ENDIAN);
5382         flags_tree = proto_item_add_subtree(tf, ett_tcp_scpsoption_flags);
5383         proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_bets, tvb,
5384                             offset + 2, 1, ENC_BIG_ENDIAN);
5385         proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_snack1, tvb,
5386                             offset + 2, 1, ENC_BIG_ENDIAN);
5387         proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_snack2, tvb,
5388                             offset + 2, 1, ENC_BIG_ENDIAN);
5389         proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_compress, tvb,
5390                             offset + 2, 1, ENC_BIG_ENDIAN);
5391         proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_nlts, tvb,
5392                             offset + 2, 1, ENC_BIG_ENDIAN);
5393         proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_reserved, tvb,
5394                             offset + 2, 1, ENC_BIG_ENDIAN);
5395         capvector = tvb_get_guint8(tvb, offset + 2);
5396 
5397         if (capvector) {
5398             struct capvec
5399             {
5400                 guint8 mask;
5401                 const gchar *str;
5402             } capvecs[] = {
5403                 {0x80, "BETS"},
5404                 {0x40, "SNACK1"},
5405                 {0x20, "SNACK2"},
5406                 {0x10, "COMP"},
5407                 {0x08, "NLTS"},
5408                 {0x07, "RESERVED"}
5409             };
5410             gboolean anyflag = FALSE;
5411             guint i;
5412 
5413             col_append_str(pinfo->cinfo, COL_INFO, " SCPS[");
5414             for (i = 0; i < sizeof(capvecs)/sizeof(struct capvec); i++) {
5415                 if (capvector & capvecs[i].mask) {
5416                     proto_item_append_text(tf, "%s%s", anyflag ? ", " : " (",
5417                                            capvecs[i].str);
5418                     col_append_lstr(pinfo->cinfo, COL_INFO,
5419                                     anyflag ? ", " : "",
5420                                     capvecs[i].str,
5421                                     COL_ADD_LSTR_TERMINATOR);
5422                     anyflag = TRUE;
5423                 }
5424             }
5425             col_append_str(pinfo->cinfo, COL_INFO, "]");
5426             proto_item_append_text(tf, ")");
5427         }
5428 
5429         proto_tree_add_item(field_tree, hf_tcp_scpsoption_connection_id, tvb,
5430                             offset + 3, 1, ENC_BIG_ENDIAN);
5431         connid = tvb_get_guint8(tvb, offset + 3);
5432         flow->scps_capable = 1;
5433 
5434         if (connid)
5435             tcp_info_append_uint(pinfo, "Connection ID", connid);
5436     } else {
5437         /* The option length != 4, so this is an infamous "extended capabilities
5438          * option. See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
5439          * Transport Protocol (SCPS-TP)" Section 3.2.5 for definition.
5440          *
5441          *  As the format of this option is only partially defined (it is
5442          * a community (or more likely vendor) defined format beyond that, so
5443          * at least for now, we only parse the standardized portion of the option.
5444          */
5445         guint8 local_offset = 2;
5446         guint8 binding_space;
5447         guint8 extended_cap_length;
5448 
5449         if (flow->scps_capable != 1) {
5450             /* There was no SCPS capabilities option preceding this */
5451             proto_item_set_text(item,
5452                                 "Illegal SCPS Extended Capabilities (%u bytes)",
5453                                 optlen);
5454         } else {
5455             proto_item_set_text(item,
5456                                 "SCPS Extended Capabilities (%u bytes)",
5457                                 optlen);
5458 
5459             /* There may be multiple binding spaces included in a single option,
5460              * so we will semi-parse each of the stacked binding spaces - skipping
5461              * over the octets following the binding space identifier and length.
5462              */
5463             while (optlen > local_offset) {
5464 
5465                 /* 1st octet is Extended Capability Binding Space */
5466                 binding_space = tvb_get_guint8(tvb, (offset + local_offset));
5467 
5468                 /* 2nd octet (upper 4-bits) has binding space length in 16-bit words.
5469                  * As defined by the specification, this length is exclusive of the
5470                  * octets containing the extended capability type and length
5471                  */
5472                 extended_cap_length =
5473                     (tvb_get_guint8(tvb, (offset + local_offset + 1)) >> 4);
5474 
5475                 /* Convert the extended capabilities length into bytes for display */
5476                 extended_cap_length = (extended_cap_length << 1);
5477 
5478                 proto_tree_add_item(field_tree, hf_tcp_option_scps_binding, tvb, offset + local_offset, 1, ENC_BIG_ENDIAN);
5479                 proto_tree_add_uint(field_tree, hf_tcp_option_scps_binding_len, tvb, offset + local_offset + 1, 1, extended_cap_length);
5480 
5481                 /* Step past the binding space and length octets */
5482                 local_offset += 2;
5483 
5484                 proto_tree_add_item(field_tree, hf_tcp_option_scps_binding_data, tvb, offset + local_offset, extended_cap_length, ENC_NA);
5485 
5486                 tcp_info_append_uint(pinfo, "EXCAP", binding_space);
5487 
5488                 /* Step past the Extended capability data
5489                  * Treat the extended capability data area as opaque;
5490                  * If one desires to parse the extended capability data
5491                  * (say, in a vendor aware build of wireshark), it would
5492                  * be triggered here.
5493                  */
5494                 local_offset += extended_cap_length;
5495             }
5496         }
5497     }
5498 
5499     return tvb_captured_length(tvb);
5500 }
5501 
5502 static int
dissect_tcpopt_user_to(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5503 dissect_tcpopt_user_to(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5504 {
5505     proto_item *tf;
5506     proto_tree *field_tree;
5507     proto_item *length_item;
5508     guint16 to;
5509     int offset = 0;
5510 
5511     tf = proto_tree_add_item(tree, proto_tcp_option_user_to, tvb, offset, -1, ENC_NA);
5512     field_tree = proto_item_add_subtree(tf, ett_tcp_option_user_to);
5513 
5514     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5515                         offset, 1, ENC_BIG_ENDIAN);
5516     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5517                                       offset + 1, 1, ENC_BIG_ENDIAN);
5518 
5519     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_USER_TO))
5520         return tvb_captured_length(tvb);
5521 
5522     proto_tree_add_item(field_tree, hf_tcp_option_user_to_granularity, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
5523     to = tvb_get_ntohs(tvb, offset + 2) & 0x7FFF;
5524     proto_tree_add_item(field_tree, hf_tcp_option_user_to_val, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
5525 
5526     tcp_info_append_uint(pinfo, "USER_TO", to);
5527     return tvb_captured_length(tvb);
5528 }
5529 
5530 /* This is called for SYN+ACK packets and the purpose is to verify that
5531  * the SCPS capabilities option has been successfully negotiated for the flow.
5532  * If the SCPS capabilities option was offered by only one party, the
5533  * proactively set scps_capable attribute of the flow (set upon seeing
5534  * the first instance of the SCPS option) is revoked.
5535  */
5536 static void
verify_scps(packet_info * pinfo,proto_item * tf_syn,struct tcp_analysis * tcpd)5537 verify_scps(packet_info *pinfo,  proto_item *tf_syn, struct tcp_analysis *tcpd)
5538 {
5539     tf_syn = 0x0;
5540 
5541     if(tcpd) {
5542         if ((!(tcpd->flow1.scps_capable)) || (!(tcpd->flow2.scps_capable))) {
5543             tcpd->flow1.scps_capable = 0;
5544             tcpd->flow2.scps_capable = 0;
5545         } else {
5546             expert_add_info(pinfo, tf_syn, &ei_tcp_scps_capable);
5547         }
5548     }
5549 }
5550 
5551 /* See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS
5552  * Transport Protocol (SCPS-TP)" Section 3.5 for definition of the SNACK option
5553  */
5554 static int
dissect_tcpopt_snack(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5555 dissect_tcpopt_snack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5556 {
5557     struct tcp_analysis *tcpd=NULL;
5558     guint32 relative_hole_offset;
5559     guint32 relative_hole_size;
5560     guint16 base_mss = 0;
5561     guint32 ack;
5562     guint32 hole_start;
5563     guint32 hole_end;
5564     int     offset = 0;
5565     proto_item *hidden_item, *tf;
5566     proto_tree *field_tree;
5567     proto_item *length_item;
5568 
5569     tf = proto_tree_add_item(tree, proto_tcp_option_snack, tvb, offset, -1, ENC_NA);
5570     field_tree = proto_item_add_subtree(tf, ett_tcp_option_snack);
5571 
5572     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5573                         offset, 1, ENC_BIG_ENDIAN);
5574     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5575                                       offset + 1, 1, ENC_BIG_ENDIAN);
5576 
5577     if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_SNACK))
5578         return tvb_captured_length(tvb);
5579 
5580     tcpd = get_tcp_conversation_data(NULL,pinfo);
5581 
5582     /* The SNACK option reports missing data with a granularity of segments. */
5583     proto_tree_add_item_ret_uint(field_tree, hf_tcp_option_snack_offset,
5584                                       tvb, offset + 2, 2, ENC_BIG_ENDIAN, &relative_hole_offset);
5585 
5586     proto_tree_add_item_ret_uint(field_tree, hf_tcp_option_snack_size,
5587                                       tvb, offset + 4, 2, ENC_BIG_ENDIAN, &relative_hole_size);
5588 
5589     ack   = tvb_get_ntohl(tvb, 8);
5590 
5591     if (tcp_analyze_seq && tcp_relative_seq) {
5592         ack -= tcpd->rev->base_seq;
5593     }
5594 
5595     /* To aid analysis, we can use a simple but generally effective heuristic
5596      * to report the most likely boundaries of the missing data.  If the
5597      * flow is scps_capable, we track the maximum sized segment that was
5598      * acknowledged by the receiver and use that as the reporting granularity.
5599      * This may be different from the negotiated MTU due to PMTUD or flows
5600      * that do not send max-sized segments.
5601      */
5602     base_mss = tcpd->fwd->maxsizeacked;
5603 
5604     if (base_mss) {
5605         /* Scale the reported offset and hole size by the largest segment acked */
5606         hole_start = ack + (base_mss * relative_hole_offset);
5607         hole_end   = hole_start + (base_mss * relative_hole_size);
5608 
5609         hidden_item = proto_tree_add_uint(field_tree, hf_tcp_option_snack_le,
5610                                           tvb, offset + 2, 2, hole_start);
5611         proto_item_set_hidden(hidden_item);
5612 
5613         hidden_item = proto_tree_add_uint(field_tree, hf_tcp_option_snack_re,
5614                                           tvb, offset + 4, 2, hole_end);
5615         proto_item_set_hidden(hidden_item);
5616 
5617         proto_tree_add_expert_format(field_tree, pinfo, &ei_tcp_option_snack_sequence, tvb, offset+2, 4,
5618                             "SNACK Sequence %u - %u%s", hole_start, hole_end, ((tcp_analyze_seq && tcp_relative_seq) ? " (relative)" : ""));
5619 
5620         tcp_info_append_uint(pinfo, "SNLE", hole_start);
5621         tcp_info_append_uint(pinfo, "SNRE", hole_end);
5622     }
5623 
5624     return tvb_captured_length(tvb);
5625 }
5626 
5627 enum
5628 {
5629     PROBE_VERSION_UNSPEC = 0,
5630     PROBE_VERSION_1      = 1,
5631     PROBE_VERSION_2      = 2,
5632     PROBE_VERSION_MAX
5633 };
5634 
5635 /* Probe type definition. */
5636 enum
5637 {
5638     PROBE_QUERY          = 0,
5639     PROBE_RESPONSE       = 1,
5640     PROBE_INTERNAL       = 2,
5641     PROBE_TRACE          = 3,
5642     PROBE_QUERY_SH       = 4,
5643     PROBE_RESPONSE_SH    = 5,
5644     PROBE_QUERY_INFO     = 6,
5645     PROBE_RESPONSE_INFO  = 7,
5646     PROBE_QUERY_INFO_SH  = 8,
5647     PROBE_QUERY_INFO_SID = 9,
5648     PROBE_RST            = 10,
5649     PROBE_TYPE_MAX
5650 };
5651 
5652 static const value_string rvbd_probe_type_vs[] = {
5653     { PROBE_QUERY,          "Probe Query" },
5654     { PROBE_RESPONSE,       "Probe Response" },
5655     { PROBE_INTERNAL,       "Probe Internal" },
5656     { PROBE_TRACE,          "Probe Trace" },
5657     { PROBE_QUERY_SH,       "Probe Query SH" },
5658     { PROBE_RESPONSE_SH,    "Probe Response SH" },
5659     { PROBE_QUERY_INFO,     "Probe Query Info" },
5660     { PROBE_RESPONSE_INFO,  "Probe Response Info" },
5661     { PROBE_QUERY_INFO_SH,  "Probe Query Info SH" },
5662     { PROBE_QUERY_INFO_SID, "Probe Query Info Store ID" },
5663     { PROBE_RST,            "Probe Reset" },
5664     { 0, NULL }
5665 };
5666 
5667 #define PROBE_OPTLEN_OFFSET            1
5668 
5669 #define PROBE_VERSION_TYPE_OFFSET      2
5670 #define PROBE_V1_RESERVED_OFFSET       3
5671 #define PROBE_V1_PROBER_OFFSET         4
5672 #define PROBE_V1_APPLI_VERSION_OFFSET  8
5673 #define PROBE_V1_PROXY_ADDR_OFFSET     8
5674 #define PROBE_V1_PROXY_PORT_OFFSET    12
5675 #define PROBE_V1_SH_CLIENT_ADDR_OFFSET 8
5676 #define PROBE_V1_SH_PROXY_ADDR_OFFSET 12
5677 #define PROBE_V1_SH_PROXY_PORT_OFFSET 16
5678 
5679 #define PROBE_V2_INFO_OFFSET           3
5680 
5681 #define PROBE_V2_INFO_CLIENT_ADDR_OFFSET 4
5682 #define PROBE_V2_INFO_STOREID_OFFSET   4
5683 
5684 #define PROBE_VERSION_MASK          0x01
5685 
5686 /* Probe Query Extra Info flags */
5687 #define RVBD_FLAGS_PROBE_LAST       0x01
5688 #define RVBD_FLAGS_PROBE_NCFE       0x04
5689 
5690 /* Probe Response Extra Info flags */
5691 #define RVBD_FLAGS_PROBE_SERVER     0x01
5692 #define RVBD_FLAGS_PROBE_SSLCERT    0x02
5693 #define RVBD_FLAGS_PROBE            0x10
5694 
5695 typedef struct rvbd_option_data
5696 {
5697     gboolean valid;
5698     guint8 type;
5699     guint8 probe_flags;
5700 
5701 } rvbd_option_data;
5702 
5703 static void
rvbd_probe_decode_version_type(const guint8 vt,guint8 * ver,guint8 * type)5704 rvbd_probe_decode_version_type(const guint8 vt, guint8 *ver, guint8 *type)
5705 {
5706     if (vt & PROBE_VERSION_MASK) {
5707         *ver = PROBE_VERSION_1;
5708         *type = vt >> 4;
5709     } else {
5710         *ver = PROBE_VERSION_2;
5711         *type = vt >> 1;
5712     }
5713 }
5714 
5715 static void
rvbd_probe_resp_add_info(proto_item * pitem,packet_info * pinfo,tvbuff_t * tvb,int ip_offset,guint16 port)5716 rvbd_probe_resp_add_info(proto_item *pitem, packet_info *pinfo, tvbuff_t *tvb, int ip_offset, guint16 port)
5717 {
5718     proto_item_append_text(pitem, ", Server Steelhead: %s:%u", tvb_ip_to_str(pinfo->pool, tvb, ip_offset), port);
5719 
5720     col_prepend_fstr(pinfo->cinfo, COL_INFO, "SA+, ");
5721 }
5722 
5723 static int
dissect_tcpopt_rvbd_probe(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5724 dissect_tcpopt_rvbd_probe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
5725 {
5726     guint8 ver, type;
5727     proto_tree *field_tree;
5728     proto_item *pitem;
5729     proto_item *length_item;
5730     int offset = 0,
5731         optlen = tvb_reported_length(tvb);
5732     struct tcpheader *tcph = (struct tcpheader*)data;
5733 
5734     pitem = proto_tree_add_item(tree, proto_tcp_option_rvbd_probe, tvb, offset, -1, ENC_NA);
5735     field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_probe);
5736 
5737     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5738                         offset, 1, ENC_BIG_ENDIAN);
5739     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5740                                       offset + 1, 1, ENC_BIG_ENDIAN);
5741 
5742     if (optlen < TCPOLEN_RVBD_PROBE_MIN) {
5743         /* Bogus - option length is less than what it's supposed to be for
5744            this option. */
5745         expert_add_info_format(pinfo, length_item, &ei_tcp_opt_len_invalid,
5746                             "option length should be >= %u)",
5747                             TCPOLEN_RVBD_PROBE_MIN);
5748         return tvb_captured_length(tvb);
5749     }
5750 
5751     rvbd_probe_decode_version_type(
5752         tvb_get_guint8(tvb, offset + PROBE_VERSION_TYPE_OFFSET),
5753         &ver, &type);
5754 
5755     proto_item_append_text(pitem, ": %s", val_to_str_const(type, rvbd_probe_type_vs, "Probe Unknown"));
5756 
5757     if (type >= PROBE_TYPE_MAX)
5758         return tvb_captured_length(tvb);
5759 
5760     if (ver == PROBE_VERSION_1) {
5761         guint16 port;
5762 
5763         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_type1, tvb,
5764                             offset + PROBE_VERSION_TYPE_OFFSET, 1, ENC_BIG_ENDIAN);
5765         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_version1, tvb,
5766                             offset + PROBE_VERSION_TYPE_OFFSET, 1, ENC_BIG_ENDIAN);
5767 
5768         if (type == PROBE_INTERNAL)
5769             return offset + PROBE_VERSION_TYPE_OFFSET;
5770 
5771         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_reserved, tvb, offset + PROBE_V1_RESERVED_OFFSET, 1, ENC_BIG_ENDIAN);
5772 
5773         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_prober, tvb,
5774                             offset + PROBE_V1_PROBER_OFFSET, 4, ENC_BIG_ENDIAN);
5775 
5776         switch (type) {
5777 
5778         case PROBE_QUERY:
5779         case PROBE_QUERY_SH:
5780         case PROBE_TRACE:
5781             {
5782             rvbd_option_data* option_data;
5783             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_appli_ver, tvb,
5784                                 offset + PROBE_V1_APPLI_VERSION_OFFSET, 2,
5785                                 ENC_BIG_ENDIAN);
5786 
5787             proto_item_append_text(pitem, ", CSH IP: %s", tvb_ip_to_str(pinfo->pool, tvb, offset + PROBE_V1_PROBER_OFFSET));
5788 
5789             option_data = (rvbd_option_data*)p_get_proto_data(pinfo->pool, pinfo, proto_tcp_option_rvbd_probe, pinfo->curr_layer_num);
5790             if (option_data == NULL)
5791             {
5792                 option_data = wmem_new0(pinfo->pool, rvbd_option_data);
5793                 p_add_proto_data(pinfo->pool, pinfo, proto_tcp_option_rvbd_probe, pinfo->curr_layer_num, option_data);
5794             }
5795 
5796             option_data->valid = TRUE;
5797             option_data->type = type;
5798 
5799             }
5800             break;
5801 
5802         case PROBE_RESPONSE:
5803             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy, tvb,
5804                                 offset + PROBE_V1_PROXY_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
5805 
5806             port = tvb_get_ntohs(tvb, offset + PROBE_V1_PROXY_PORT_OFFSET);
5807             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy_port, tvb,
5808                                 offset + PROBE_V1_PROXY_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
5809 
5810             rvbd_probe_resp_add_info(pitem, pinfo, tvb, offset + PROBE_V1_PROXY_ADDR_OFFSET, port);
5811             break;
5812 
5813         case PROBE_RESPONSE_SH:
5814             proto_tree_add_item(field_tree,
5815                                 hf_tcp_option_rvbd_probe_client, tvb,
5816                                 offset + PROBE_V1_SH_CLIENT_ADDR_OFFSET, 4,
5817                                 ENC_BIG_ENDIAN);
5818 
5819             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy, tvb,
5820                                 offset + PROBE_V1_SH_PROXY_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
5821 
5822             port = tvb_get_ntohs(tvb, offset + PROBE_V1_SH_PROXY_PORT_OFFSET);
5823             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_proxy_port, tvb,
5824                                 offset + PROBE_V1_SH_PROXY_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
5825 
5826             rvbd_probe_resp_add_info(pitem, pinfo, tvb, offset + PROBE_V1_SH_PROXY_ADDR_OFFSET, port);
5827             break;
5828         }
5829     }
5830     else if (ver == PROBE_VERSION_2) {
5831         proto_item *ver_pi;
5832         proto_item *flag_pi;
5833         proto_tree *flag_tree;
5834         guint8 flags;
5835 
5836         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_type2, tvb,
5837                             offset + PROBE_VERSION_TYPE_OFFSET, 1, ENC_BIG_ENDIAN);
5838 
5839         proto_tree_add_uint_format_value(
5840             field_tree, hf_tcp_option_rvbd_probe_version2, tvb,
5841             offset + PROBE_VERSION_TYPE_OFFSET, 1, ver, "%u", ver);
5842         /* Use version1 for filtering purposes because version2 packet
5843            value is 0, but filtering is usually done for value 2 */
5844         ver_pi = proto_tree_add_uint(field_tree, hf_tcp_option_rvbd_probe_version1, tvb,
5845                                      offset + PROBE_VERSION_TYPE_OFFSET, 1, ver);
5846         proto_item_set_hidden(ver_pi);
5847 
5848         switch (type) {
5849 
5850         case PROBE_QUERY_INFO:
5851         case PROBE_QUERY_INFO_SH:
5852         case PROBE_QUERY_INFO_SID:
5853             flags = tvb_get_guint8(tvb, offset + PROBE_V2_INFO_OFFSET);
5854             flag_pi = proto_tree_add_uint(field_tree, hf_tcp_option_rvbd_probe_flags,
5855                                           tvb, offset + PROBE_V2_INFO_OFFSET,
5856                                           1, flags);
5857 
5858             flag_tree = proto_item_add_subtree(flag_pi, ett_tcp_opt_rvbd_probe_flags);
5859             proto_tree_add_item(flag_tree,
5860                                 hf_tcp_option_rvbd_probe_flag_not_cfe,
5861                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
5862             proto_tree_add_item(flag_tree,
5863                                 hf_tcp_option_rvbd_probe_flag_last_notify,
5864                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
5865 
5866             switch (type)
5867             {
5868             case PROBE_QUERY_INFO:
5869                 {
5870                     rvbd_option_data* option_data = (rvbd_option_data*)p_get_proto_data(pinfo->pool, pinfo, proto_tcp_option_rvbd_probe, pinfo->curr_layer_num);
5871                     if (option_data == NULL)
5872                     {
5873                         option_data = wmem_new0(pinfo->pool, rvbd_option_data);
5874                         p_add_proto_data(pinfo->pool, pinfo, proto_tcp_option_rvbd_probe, pinfo->curr_layer_num, option_data);
5875                     }
5876 
5877                     option_data->probe_flags = flags;
5878                 }
5879                 break;
5880             case PROBE_QUERY_INFO_SH:
5881                 proto_tree_add_item(flag_tree,
5882                                     hf_tcp_option_rvbd_probe_client, tvb,
5883                                     offset + PROBE_V2_INFO_CLIENT_ADDR_OFFSET,
5884                                     4, ENC_BIG_ENDIAN);
5885                 break;
5886             case PROBE_QUERY_INFO_SID:
5887                 proto_tree_add_item(flag_tree,
5888                                     hf_tcp_option_rvbd_probe_storeid, tvb,
5889                                     offset + PROBE_V2_INFO_STOREID_OFFSET,
5890                                     4, ENC_BIG_ENDIAN);
5891                 break;
5892             }
5893 
5894             if (type != PROBE_QUERY_INFO_SID &&
5895                 tcph != NULL &&
5896                 (tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK) &&
5897                 (flags & RVBD_FLAGS_PROBE_LAST)) {
5898                 col_prepend_fstr(pinfo->cinfo, COL_INFO, "SA++, ");
5899             }
5900 
5901             break;
5902 
5903         case PROBE_RESPONSE_INFO:
5904             flag_pi = proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_flags,
5905                                           tvb, offset + PROBE_V2_INFO_OFFSET,
5906                                           1, ENC_BIG_ENDIAN);
5907 
5908             flag_tree = proto_item_add_subtree(flag_pi, ett_tcp_opt_rvbd_probe_flags);
5909             proto_tree_add_item(flag_tree,
5910                                 hf_tcp_option_rvbd_probe_flag_probe_cache,
5911                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
5912             proto_tree_add_item(flag_tree,
5913                                 hf_tcp_option_rvbd_probe_flag_sslcert,
5914                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
5915             proto_tree_add_item(flag_tree,
5916                                 hf_tcp_option_rvbd_probe_flag_server_connected,
5917                                 tvb, offset + PROBE_V2_INFO_OFFSET, 1, ENC_BIG_ENDIAN);
5918             break;
5919 
5920         case PROBE_RST:
5921             proto_tree_add_item(field_tree, hf_tcp_option_rvbd_probe_flags,
5922                                   tvb, offset + PROBE_V2_INFO_OFFSET,
5923                                   1, ENC_BIG_ENDIAN);
5924             break;
5925         }
5926     }
5927 
5928     return tvb_captured_length(tvb);
5929 }
5930 
5931 enum {
5932     TRPY_OPTNUM_OFFSET        = 0,
5933     TRPY_OPTLEN_OFFSET        = 1,
5934 
5935     TRPY_OPTIONS_OFFSET       = 2,
5936     TRPY_SRC_ADDR_OFFSET      = 4,
5937     TRPY_DST_ADDR_OFFSET      = 8,
5938     TRPY_SRC_PORT_OFFSET      = 12,
5939     TRPY_DST_PORT_OFFSET      = 14,
5940     TRPY_CLIENT_PORT_OFFSET   = 16
5941 };
5942 
5943 /* Trpy Flags */
5944 #define RVBD_FLAGS_TRPY_MODE         0x0001
5945 #define RVBD_FLAGS_TRPY_OOB          0x0002
5946 #define RVBD_FLAGS_TRPY_CHKSUM       0x0004
5947 #define RVBD_FLAGS_TRPY_FW_RST       0x0100
5948 #define RVBD_FLAGS_TRPY_FW_RST_INNER 0x0200
5949 #define RVBD_FLAGS_TRPY_FW_RST_PROBE 0x0400
5950 
5951 static const true_false_string trpy_mode_str = {
5952     "Port Transparency",
5953     "Full Transparency"
5954 };
5955 
5956 static int
dissect_tcpopt_rvbd_trpy(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5957 dissect_tcpopt_rvbd_trpy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5958 {
5959     proto_tree *field_tree;
5960     proto_item *pitem;
5961     proto_item *length_item;
5962     guint16 sport, dport, flags;
5963     int offset = 0,
5964         optlen = tvb_reported_length(tvb);
5965     static int * const rvbd_trpy_flags[] = {
5966         &hf_tcp_option_rvbd_trpy_flag_fw_rst_probe,
5967         &hf_tcp_option_rvbd_trpy_flag_fw_rst_inner,
5968         &hf_tcp_option_rvbd_trpy_flag_fw_rst,
5969         &hf_tcp_option_rvbd_trpy_flag_chksum,
5970         &hf_tcp_option_rvbd_trpy_flag_oob,
5971         &hf_tcp_option_rvbd_trpy_flag_mode,
5972         NULL
5973     };
5974 
5975     col_prepend_fstr(pinfo->cinfo, COL_INFO, "TRPY, ");
5976 
5977     pitem = proto_tree_add_item(tree, proto_tcp_option_rvbd_trpy, tvb, offset, -1, ENC_NA);
5978     field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_trpy);
5979 
5980     proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
5981                         offset, 1, ENC_BIG_ENDIAN);
5982     length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
5983                                       offset + 1, 1, ENC_BIG_ENDIAN);
5984 
5985     if (!tcp_option_len_check(length_item, pinfo, optlen, TCPOLEN_RVBD_TRPY_MIN))
5986         return tvb_captured_length(tvb);
5987 
5988     flags = tvb_get_ntohs(tvb, offset + TRPY_OPTIONS_OFFSET);
5989     proto_tree_add_bitmask_with_flags(field_tree, tvb, offset + TRPY_OPTIONS_OFFSET, hf_tcp_option_rvbd_trpy_flags,
5990                         ett_tcp_opt_rvbd_trpy_flags, rvbd_trpy_flags, ENC_NA, BMT_NO_APPEND);
5991 
5992     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_src,
5993                         tvb, offset + TRPY_SRC_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
5994 
5995     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_dst,
5996                         tvb, offset + TRPY_DST_ADDR_OFFSET, 4, ENC_BIG_ENDIAN);
5997 
5998     sport = tvb_get_ntohs(tvb, offset + TRPY_SRC_PORT_OFFSET);
5999     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_src_port,
6000                         tvb, offset + TRPY_SRC_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
6001 
6002     dport = tvb_get_ntohs(tvb, offset + TRPY_DST_PORT_OFFSET);
6003     proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_dst_port,
6004                         tvb, offset + TRPY_DST_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
6005 
6006     proto_item_append_text(pitem, " %s:%u -> %s:%u",
6007                            tvb_ip_to_str(pinfo->pool, tvb, offset + TRPY_SRC_ADDR_OFFSET), sport,
6008                            tvb_ip_to_str(pinfo->pool, tvb, offset + TRPY_DST_ADDR_OFFSET), dport);
6009 
6010     /* Client port only set on SYN: optlen == 18 */
6011     if ((flags & RVBD_FLAGS_TRPY_OOB) && (optlen > TCPOLEN_RVBD_TRPY_MIN))
6012         proto_tree_add_item(field_tree, hf_tcp_option_rvbd_trpy_client_port,
6013                             tvb, offset + TRPY_CLIENT_PORT_OFFSET, 2, ENC_BIG_ENDIAN);
6014 
6015     /* Despite that we have the right TCP ports for other protocols,
6016      * the data is related to the Riverbed Optimization Protocol and
6017      * not understandable by normal protocol dissectors. If the sport
6018      * protocol is available then use that, otherwise just output it
6019      * as a hex-dump.
6020      */
6021     if (sport_handle != NULL) {
6022         conversation_t *conversation;
6023         conversation = find_or_create_conversation(pinfo);
6024         if (conversation_get_dissector(conversation, pinfo->num) != sport_handle) {
6025             conversation_set_dissector(conversation, sport_handle);
6026         }
6027     } else if (data_handle != NULL) {
6028         conversation_t *conversation;
6029         conversation = find_or_create_conversation(pinfo);
6030         if (conversation_get_dissector(conversation, pinfo->num) != data_handle) {
6031             conversation_set_dissector(conversation, data_handle);
6032         }
6033     }
6034 
6035     return tvb_captured_length(tvb);
6036 }
6037 
6038  /* Started as a copy of dissect_ip_tcp_options(), but was changed to support
6039     options as a dissector table */
6040 static void
tcp_dissect_options(tvbuff_t * tvb,int offset,guint length,int eol,packet_info * pinfo,proto_tree * opt_tree,proto_item * opt_item,void * data)6041 tcp_dissect_options(tvbuff_t *tvb, int offset, guint length, int eol,
6042                        packet_info *pinfo, proto_tree *opt_tree,
6043                        proto_item *opt_item, void * data)
6044 {
6045     guchar            opt;
6046     guint             optlen, nop_count = 0;
6047     proto_tree       *field_tree;
6048     const char       *name;
6049     dissector_handle_t option_dissector;
6050     tvbuff_t         *next_tvb;
6051     struct tcpheader *tcph = (struct tcpheader *)data;
6052     gboolean          mss_seen = FALSE;
6053 
6054     while (length > 0) {
6055         opt = tvb_get_guint8(tvb, offset);
6056         --length;      /* account for type byte */
6057         if ((opt == TCPOPT_EOL) || (opt == TCPOPT_NOP)) {
6058             int local_proto;
6059             proto_item* field_item;
6060 
6061             /* We assume that the only options with no length are EOL and
6062                NOP options, so that we can treat unknown options as having
6063                a minimum length of 2, and at least be able to move on to
6064                the next option by using the length in the option. */
6065             if (opt == TCPOPT_EOL) {
6066                 local_proto = proto_tcp_option_eol;
6067             } else if (opt == TCPOPT_NOP) {
6068                 local_proto = proto_tcp_option_nop;
6069 
6070                 if (opt_item && (nop_count == 0 || offset % 4)) {
6071                     /* Count number of NOP in a row within a uint32 */
6072                     nop_count++;
6073 
6074                     if (nop_count == 4) {
6075                         expert_add_info(pinfo, opt_item, &ei_tcp_nop);
6076                     }
6077                 } else {
6078                     nop_count = 0;
6079                 }
6080             } else {
6081                 DISSECTOR_ASSERT_NOT_REACHED();
6082             }
6083 
6084             field_item = proto_tree_add_item(opt_tree, local_proto, tvb, offset, 1, ENC_NA);
6085             field_tree = proto_item_add_subtree(field_item, ett_tcp_option_other);
6086             proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
6087             proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s", proto_get_protocol_short_name(find_protocol_by_id(local_proto)));
6088             offset += 1;
6089         } else {
6090             option_dissector = dissector_get_uint_handle(tcp_option_table, opt);
6091             if (option_dissector == NULL) {
6092                 name = wmem_strdup_printf(pinfo->pool, "Unknown (0x%02x)", opt);
6093                 option_dissector = tcp_opt_unknown_handle;
6094             } else {
6095                 name = dissector_handle_get_short_name(option_dissector);
6096             }
6097 
6098             /* Option has a length. Is it in the packet? */
6099             if (length == 0) {
6100                 /* Bogus - packet must at least include option code byte and
6101                     length byte! */
6102                 proto_tree_add_expert_format(opt_tree, pinfo, &ei_tcp_opt_len_invalid, tvb, offset, 1,
6103                                                 "%s (length byte past end of options)", name);
6104                 return;
6105             }
6106 
6107             optlen = tvb_get_guint8(tvb, offset + 1);  /* total including type, len */
6108             --length;    /* account for length byte */
6109 
6110             if (optlen < 2) {
6111                 /* Bogus - option length is too short to include option code and
6112                     option length. */
6113                 proto_tree_add_expert_format(opt_tree, pinfo, &ei_tcp_opt_len_invalid, tvb, offset, 2,
6114                                     "%s (with too-short option length = %u byte%s)",
6115                                     name, optlen, plurality(optlen, "", "s"));
6116                 return;
6117             } else if (optlen - 2 > length) {
6118                 /* Bogus - option goes past the end of the header. */
6119                 proto_tree_add_expert_format(opt_tree, pinfo, &ei_tcp_opt_len_invalid, tvb, offset, length,
6120                                     "%s (option length = %u byte%s says option goes past end of options)",
6121                                     name, optlen, plurality(optlen, "", "s"));
6122                 return;
6123             }
6124 
6125             if (opt == TCPOPT_MSS)
6126             {
6127                 mss_seen = TRUE;
6128             }
6129 
6130             next_tvb = tvb_new_subset_length(tvb, offset, optlen);
6131             call_dissector_with_data(option_dissector, next_tvb, pinfo, opt_tree/* tree */, data);
6132             proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s", name);
6133 
6134             offset += optlen;
6135             length -= (optlen-2); //already accounted for type and len bytes
6136         }
6137 
6138         if (opt == eol)
6139             break;
6140     }
6141 
6142     if ((tcph->th_flags & TH_SYN) && (mss_seen != TRUE))
6143     {
6144         expert_add_info(pinfo, opt_item, &ei_tcp_option_mss_absent);
6145     }
6146 }
6147 
6148 /* Determine if there is a sub-dissector and call it; return TRUE
6149    if there was a sub-dissector, FALSE otherwise.
6150 
6151    This has been separated into a stand alone routine to other protocol
6152    dissectors can call to it, e.g., SOCKS. */
6153 
6154 static gboolean try_heuristic_first = FALSE;
6155 
6156 
6157 /* this function can be called with tcpd==NULL as from the msproxy dissector */
6158 gboolean
decode_tcp_ports(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,int src_port,int dst_port,struct tcp_analysis * tcpd,struct tcpinfo * tcpinfo)6159 decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
6160     proto_tree *tree, int src_port, int dst_port,
6161     struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
6162 {
6163     tvbuff_t *next_tvb;
6164     int low_port, high_port;
6165     int save_desegment_offset;
6166     guint32 save_desegment_len;
6167     heur_dtbl_entry_t *hdtbl_entry;
6168     exp_pdu_data_t *exp_pdu_data;
6169 
6170     /* Don't call subdissectors for keepalives.  Even though they do contain
6171      * payload "data", it's just garbage.  Display any data the keepalive
6172      * packet might contain though.
6173      */
6174     if(tcpd && tcpd->ta) {
6175         if(tcpd->ta->flags&TCP_A_KEEP_ALIVE) {
6176             next_tvb = tvb_new_subset_remaining(tvb, offset);
6177             call_dissector(data_handle, next_tvb, pinfo, tree);
6178             return TRUE;
6179         }
6180     }
6181 
6182     if (tcp_no_subdissector_on_error && !(tcp_desegment && tcp_reassemble_out_of_order) &&
6183         tcpd && tcpd->ta && tcpd->ta->flags & (TCP_A_RETRANSMISSION | TCP_A_OUT_OF_ORDER)) {
6184         /* Don't try to dissect a retransmission high chance that it will mess
6185          * subdissectors for protocols that require in-order delivery of the
6186          * PDUs. (i.e. DCE/RPCoverHTTP and encryption)
6187          * If OoO reassembly is enabled and if this segment was previously lost,
6188          * then this retransmission could have finished reassembly, so continue.
6189          * XXX should this option be removed? "tcp_reassemble_out_of_order"
6190          * should have addressed the above in-order requirement.
6191          */
6192         return FALSE;
6193     }
6194     next_tvb = tvb_new_subset_remaining(tvb, offset);
6195 
6196     save_desegment_offset = pinfo->desegment_offset;
6197     save_desegment_len = pinfo->desegment_len;
6198 
6199 /* determine if this packet is part of a conversation and call dissector */
6200 /* for the conversation if available */
6201 
6202     if (try_conversation_dissector(&pinfo->src, &pinfo->dst, ENDPOINT_TCP,
6203                                    src_port, dst_port, next_tvb, pinfo, tree, tcpinfo, 0)) {
6204         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6205         handle_export_pdu_conversation(pinfo, next_tvb, src_port, dst_port, tcpinfo);
6206         return TRUE;
6207     }
6208 
6209     if (try_heuristic_first) {
6210         /* do lookup with the heuristic subdissector table */
6211         if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, tcpinfo)) {
6212             pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6213             handle_export_pdu_heuristic(pinfo, next_tvb, hdtbl_entry, tcpinfo);
6214             return TRUE;
6215         }
6216     }
6217 
6218     /* Do lookups with the subdissector table.
6219        Try the server port captured on the SYN or SYN|ACK packet.  After that
6220        try the port number with the lower value first, followed by the
6221        port number with the higher value.  This means that, for packets
6222        where a dissector is registered for *both* port numbers:
6223 
6224        1) we pick the same dissector for traffic going in both directions;
6225 
6226        2) we prefer the port number that's more likely to be the right
6227        one (as that prefers well-known ports to reserved ports);
6228 
6229        although there is, of course, no guarantee that any such strategy
6230        will always pick the right port number.
6231 
6232        XXX - we ignore port numbers of 0, as some dissectors use a port
6233        number of 0 to disable the port. */
6234 
6235     if (tcpd && tcpd->server_port != 0 &&
6236         dissector_try_uint_new(subdissector_table, tcpd->server_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
6237         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6238         handle_export_pdu_dissection_table(pinfo, next_tvb, tcpd->server_port, tcpinfo);
6239         return TRUE;
6240     }
6241 
6242     if (src_port > dst_port) {
6243         low_port = dst_port;
6244         high_port = src_port;
6245     } else {
6246         low_port = src_port;
6247         high_port = dst_port;
6248     }
6249 
6250     if (low_port != 0 &&
6251         dissector_try_uint_new(subdissector_table, low_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
6252         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6253         handle_export_pdu_dissection_table(pinfo, next_tvb, low_port, tcpinfo);
6254         return TRUE;
6255     }
6256     if (high_port != 0 &&
6257         dissector_try_uint_new(subdissector_table, high_port, next_tvb, pinfo, tree, TRUE, tcpinfo)) {
6258         pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6259         handle_export_pdu_dissection_table(pinfo, next_tvb, high_port, tcpinfo);
6260         return TRUE;
6261     }
6262 
6263     if (!try_heuristic_first) {
6264         /* do lookup with the heuristic subdissector table */
6265         if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, tcpinfo)) {
6266             pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6267             handle_export_pdu_heuristic(pinfo, next_tvb, hdtbl_entry, tcpinfo);
6268             return TRUE;
6269         }
6270     }
6271 
6272     /*
6273      * heuristic / conversation / port registered dissectors rejected the packet;
6274      * make sure they didn't also request desegmentation (we could just override
6275      * the request, but rejecting a packet *and* requesting desegmentation is a sign
6276      * of the dissector's code needing clearer thought, so we fail so that the
6277      * problem is made more obvious).
6278      */
6279     DISSECTOR_ASSERT(save_desegment_offset == pinfo->desegment_offset &&
6280                      save_desegment_len == pinfo->desegment_len);
6281 
6282     /* Oh, well, we don't know this; dissect it as data. */
6283     call_dissector(data_handle,next_tvb, pinfo, tree);
6284 
6285     pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
6286     if (have_tap_listener(exported_pdu_tap)) {
6287         exp_pdu_data = export_pdu_create_common_tags(pinfo, "data", EXP_PDU_TAG_PROTO_NAME);
6288         exp_pdu_data->tvb_captured_length = tvb_captured_length(next_tvb);
6289         exp_pdu_data->tvb_reported_length = tvb_reported_length(next_tvb);
6290         exp_pdu_data->pdu_tvb = next_tvb;
6291 
6292         tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
6293     }
6294     return FALSE;
6295 }
6296 
6297 static void
process_tcp_payload(tvbuff_t * tvb,volatile int offset,packet_info * pinfo,proto_tree * tree,proto_tree * tcp_tree,int src_port,int dst_port,guint32 seq,guint32 nxtseq,gboolean is_tcp_segment,struct tcp_analysis * tcpd,struct tcpinfo * tcpinfo)6298 process_tcp_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
6299     proto_tree *tree, proto_tree *tcp_tree, int src_port, int dst_port,
6300     guint32 seq, guint32 nxtseq, gboolean is_tcp_segment,
6301     struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
6302 {
6303     pinfo->want_pdu_tracking=0;
6304 
6305     TRY {
6306         if(is_tcp_segment) {
6307             /*qqq   see if it is an unaligned PDU */
6308             if(tcpd && tcp_analyze_seq && (!tcp_desegment)) {
6309                 if(seq || nxtseq) {
6310                     offset=scan_for_next_pdu(tvb, tcp_tree, pinfo, offset,
6311                         seq, nxtseq, tcpd->fwd->multisegment_pdus);
6312                 }
6313             }
6314         }
6315         /* if offset is -1 this means that this segment is known
6316          * to be fully inside a previously detected pdu
6317          * so we don't even need to try to dissect it either.
6318          */
6319         if( (offset!=-1) &&
6320             decode_tcp_ports(tvb, offset, pinfo, tree, src_port,
6321                 dst_port, tcpd, tcpinfo) ) {
6322             /*
6323              * We succeeded in handing off to a subdissector.
6324              *
6325              * Is this a TCP segment or a reassembled chunk of
6326              * TCP payload?
6327              */
6328             if(is_tcp_segment) {
6329                 /* if !visited, check want_pdu_tracking and
6330                    store it in table */
6331                 if(tcpd && (!pinfo->fd->visited) &&
6332                     tcp_analyze_seq && pinfo->want_pdu_tracking) {
6333                     if(seq || nxtseq) {
6334                         pdu_store_sequencenumber_of_next_pdu(
6335                             pinfo,
6336                             seq,
6337                             nxtseq+pinfo->bytes_until_next_pdu,
6338                             tcpd->fwd->multisegment_pdus);
6339                     }
6340                 }
6341             }
6342         }
6343     }
6344     CATCH_ALL {
6345         /* We got an exception. At this point the dissection is
6346          * completely aborted and execution will be transferred back
6347          * to (probably) the frame dissector.
6348          * Here we have to place whatever we want the dissector
6349          * to do before aborting the tcp dissection.
6350          */
6351         /*
6352          * Is this a TCP segment or a reassembled chunk of TCP
6353          * payload?
6354          */
6355         if(is_tcp_segment) {
6356             /*
6357              * It's from a TCP segment.
6358              *
6359              * if !visited, check want_pdu_tracking and store it
6360              * in table
6361              */
6362             if(tcpd && (!pinfo->fd->visited) && tcp_analyze_seq && pinfo->want_pdu_tracking) {
6363                 if(seq || nxtseq) {
6364                     pdu_store_sequencenumber_of_next_pdu(pinfo,
6365                         seq,
6366                         nxtseq+pinfo->bytes_until_next_pdu,
6367                         tcpd->fwd->multisegment_pdus);
6368                 }
6369             }
6370         }
6371         RETHROW;
6372     }
6373     ENDTRY;
6374 }
6375 
6376 void
dissect_tcp_payload(tvbuff_t * tvb,packet_info * pinfo,int offset,guint32 seq,guint32 nxtseq,guint32 sport,guint32 dport,proto_tree * tree,proto_tree * tcp_tree,struct tcp_analysis * tcpd,struct tcpinfo * tcpinfo)6377 dissect_tcp_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, guint32 seq,
6378             guint32 nxtseq, guint32 sport, guint32 dport,
6379             proto_tree *tree, proto_tree *tcp_tree,
6380             struct tcp_analysis *tcpd, struct tcpinfo *tcpinfo)
6381 {
6382     gint nbytes;
6383     gboolean save_fragmented;
6384 
6385     nbytes = tvb_reported_length_remaining(tvb, offset);
6386     proto_tree_add_bytes_format(tcp_tree, hf_tcp_payload, tvb, offset,
6387         -1, NULL, "TCP payload (%u byte%s)", nbytes,
6388         plurality(nbytes, "", "s"));
6389 
6390     /* Can we desegment this segment? */
6391     if (pinfo->can_desegment) {
6392         /* Yes. */
6393         desegment_tcp(tvb, pinfo, offset, seq, nxtseq, sport, dport, tree,
6394                       tcp_tree, tcpd, tcpinfo);
6395     } else {
6396         /* No - just call the subdissector.
6397            Mark this as fragmented, so if somebody throws an exception,
6398            we don't report it as a malformed frame. */
6399         save_fragmented = pinfo->fragmented;
6400         pinfo->fragmented = TRUE;
6401 
6402         process_tcp_payload(tvb, offset, pinfo, tree, tcp_tree, sport, dport,
6403                             seq, nxtseq, TRUE, tcpd, tcpinfo);
6404         pinfo->fragmented = save_fragmented;
6405     }
6406 }
6407 
6408 static gboolean
capture_tcp(const guchar * pd,int offset,int len,capture_packet_info_t * cpinfo,const union wtap_pseudo_header * pseudo_header)6409 capture_tcp(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
6410 {
6411     guint16 src_port, dst_port, low_port, high_port;
6412 
6413     if (!BYTES_ARE_IN_FRAME(offset, len, 4))
6414         return FALSE;
6415 
6416     capture_dissector_increment_count(cpinfo, proto_tcp);
6417 
6418     src_port = pntoh16(&pd[offset]);
6419     dst_port = pntoh16(&pd[offset+2]);
6420 
6421     if (src_port > dst_port) {
6422         low_port = dst_port;
6423         high_port = src_port;
6424     } else {
6425         low_port = src_port;
6426         high_port = dst_port;
6427     }
6428 
6429     if (low_port != 0 &&
6430         try_capture_dissector("tcp.port", low_port, pd, offset+20, len, cpinfo, pseudo_header))
6431         return TRUE;
6432 
6433     if (high_port != 0 &&
6434         try_capture_dissector("tcp.port", high_port, pd, offset+20, len, cpinfo, pseudo_header))
6435         return TRUE;
6436 
6437     /* We've at least identified one type of packet, so this shouldn't be "other" */
6438     return TRUE;
6439 }
6440 
6441 static int
dissect_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6442 dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
6443 {
6444     guint8  th_off_x2; /* combines th_off and th_x2 */
6445     guint16 th_sum;
6446     guint32 th_urp;
6447     proto_tree *tcp_tree = NULL, *field_tree = NULL;
6448     proto_item *ti = NULL, *tf, *hidden_item;
6449     proto_item *options_item, *hide_seqack_abs_item;
6450     proto_tree *options_tree;
6451     int        offset = 0;
6452     char       *flags_str, *flags_str_first_letter;
6453     guint      optlen;
6454     guint32    nxtseq = 0;
6455     guint      reported_len;
6456     vec_t      cksum_vec[4];
6457     guint32    phdr[2];
6458     guint16    computed_cksum;
6459     guint16    real_window;
6460     guint      captured_length_remaining;
6461     gboolean   desegment_ok;
6462     struct tcpinfo tcpinfo;
6463     struct tcpheader *tcph;
6464     proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL, *scaled_pi;
6465     conversation_t *conv=NULL, *other_conv;
6466     guint32 save_last_frame = 0;
6467     struct tcp_analysis *tcpd=NULL;
6468     struct tcp_per_packet_data_t *tcppd=NULL;
6469     proto_item *item;
6470     proto_tree *checksum_tree;
6471     gboolean    icmp_ip = FALSE;
6472     guint8     conversation_completeness = 0;
6473     gboolean   conversation_is_new = FALSE;
6474 
6475     tcph = wmem_new0(pinfo->pool, struct tcpheader);
6476     tcph->th_sport = tvb_get_ntohs(tvb, offset);
6477     tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
6478     copy_address_shallow(&tcph->ip_src, &pinfo->src);
6479     copy_address_shallow(&tcph->ip_dst, &pinfo->dst);
6480 
6481     col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
6482     col_clear(pinfo->cinfo, COL_INFO);
6483     col_append_ports(pinfo->cinfo, COL_INFO, PT_TCP, tcph->th_sport, tcph->th_dport);
6484 
6485     if (tree) {
6486         ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, ENC_NA);
6487         if (tcp_summary_in_tree) {
6488             proto_item_append_text(ti, ", Src Port: %s, Dst Port: %s",
6489                     port_with_resolution_to_str(pinfo->pool, PT_TCP, tcph->th_sport),
6490                     port_with_resolution_to_str(pinfo->pool, PT_TCP, tcph->th_dport));
6491         }
6492         tcp_tree = proto_item_add_subtree(ti, ett_tcp);
6493         p_add_proto_data(pinfo->pool, pinfo, proto_tcp, pinfo->curr_layer_num, tcp_tree);
6494 
6495         proto_tree_add_item(tcp_tree, hf_tcp_srcport, tvb, offset, 2, ENC_BIG_ENDIAN);
6496         proto_tree_add_item(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
6497         hidden_item = proto_tree_add_item(tcp_tree, hf_tcp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
6498         proto_item_set_hidden(hidden_item);
6499         hidden_item = proto_tree_add_item(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
6500         proto_item_set_hidden(hidden_item);
6501 
6502         /*  If we're dissecting the headers of a TCP packet in an ICMP packet
6503          *  then go ahead and put the sequence numbers in the tree now (because
6504          *  they won't be put in later because the ICMP packet only contains up
6505          *  to the sequence number).
6506          *  We should only need to do this for IPv4 since IPv6 will hopefully
6507          *  carry enough TCP payload for this dissector to put the sequence
6508          *  numbers in via the regular code path.
6509          */
6510         {
6511             wmem_list_frame_t *frame;
6512             frame = wmem_list_frame_prev(wmem_list_tail(pinfo->layers));
6513             if (proto_ip == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame))) {
6514                 frame = wmem_list_frame_prev(frame);
6515                 if (proto_icmp == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame))) {
6516                     proto_tree_add_item(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
6517                     icmp_ip = TRUE;
6518                 }
6519             }
6520         }
6521     }
6522 
6523     /* Set the source and destination port numbers as soon as we get them,
6524        so that they're available to the "Follow TCP Stream" code even if
6525        we throw an exception dissecting the rest of the TCP header. */
6526     pinfo->ptype = PT_TCP;
6527     pinfo->srcport = tcph->th_sport;
6528     pinfo->destport = tcph->th_dport;
6529 
6530     p_add_proto_data(pinfo->pool, pinfo, hf_tcp_srcport, pinfo->curr_layer_num, GUINT_TO_POINTER(tcph->th_sport));
6531     p_add_proto_data(pinfo->pool, pinfo, hf_tcp_dstport, pinfo->curr_layer_num, GUINT_TO_POINTER(tcph->th_dport));
6532 
6533     tcph->th_rawseq = tvb_get_ntohl(tvb, offset + 4);
6534     tcph->th_seq = tcph->th_rawseq;
6535     tcph->th_rawack = tvb_get_ntohl(tvb, offset + 8);
6536     tcph->th_ack = tcph->th_rawack;
6537     th_off_x2 = tvb_get_guint8(tvb, offset + 12);
6538     tcpinfo.flags = tcph->th_flags = tvb_get_ntohs(tvb, offset + 12) & TH_MASK;
6539     tcph->th_win = tvb_get_ntohs(tvb, offset + 14);
6540     real_window = tcph->th_win;
6541     tcph->th_hlen = hi_nibble(th_off_x2) * 4;  /* TCP header length, in bytes */
6542 
6543     /* find(or create if needed) the conversation for this tcp session
6544      * This is a slight deviation from find_or_create_conversation so it's
6545      * done manually.  This is done to save the last frame of the conversation
6546      * in case a new conversation is found and the previous conversation needs
6547      * to be adjusted,
6548      */
6549     if((conv = find_conversation_pinfo(pinfo, 0)) != NULL) {
6550         /* Update how far the conversation reaches */
6551         if (pinfo->num > conv->last_frame) {
6552             save_last_frame = conv->last_frame;
6553             conv->last_frame = pinfo->num;
6554         }
6555     }
6556     else {
6557         conv = conversation_new(pinfo->num, &pinfo->src,
6558                      &pinfo->dst, ENDPOINT_TCP,
6559                      pinfo->srcport, pinfo->destport, 0);
6560         /* we need to know when a conversation is new then we initialize the completeness correctly */
6561         conversation_is_new = TRUE;
6562     }
6563     tcpd=get_tcp_conversation_data(conv,pinfo);
6564 
6565     /* If this is a SYN packet, then check if its seq-nr is different
6566      * from the base_seq of the retrieved conversation. If this is the
6567      * case, create a new conversation with the same addresses and ports
6568      * and set the TA_PORTS_REUSED flag. If the seq-nr is the same as
6569      * the base_seq, then restore some flow values to avoid buggy
6570      * analysis. In the latter case, it will also be marked as a
6571      * retransmission later.
6572      * XXX - Is this affected by MPTCP which can use multiple SYNs?
6573      */
6574     if(tcpd && ((tcph->th_flags&(TH_SYN|TH_ACK))==TH_SYN) &&
6575        (tcpd->fwd->static_flags & TCP_S_BASE_SEQ_SET)) {
6576         if(tcph->th_seq!=tcpd->fwd->base_seq) {
6577             if (!(pinfo->fd->visited)) {
6578                 /* Reset the last frame seen in the conversation */
6579                 if (save_last_frame > 0)
6580                     conv->last_frame = save_last_frame;
6581 
6582                 conv=conversation_new(pinfo->num, &pinfo->src, &pinfo->dst, ENDPOINT_TCP, pinfo->srcport, pinfo->destport, 0);
6583                 tcpd=get_tcp_conversation_data(conv,pinfo);
6584 
6585                 if(!tcpd->ta)
6586                     tcp_analyze_get_acked_struct(pinfo->num, tcph->th_seq, tcph->th_ack, TRUE, tcpd);
6587                 tcpd->ta->flags|=TCP_A_REUSED_PORTS;
6588 
6589                 /* As above, a new conversation starting with a SYN implies conversation completeness value 1 */
6590                 tcpd->conversation_completeness = 1;
6591             }
6592         }
6593         else {
6594             if (!(pinfo->fd->visited)) {
6595                 /*
6596                  * Sometimes we need to restore the nextseq value.
6597                  * As stated in RFC 793 3.4 a RST packet might be
6598                  * sent with SEQ being equal to the ACK received,
6599                  * thus breaking our flow monitoring. (issue 17616)
6600                  */
6601                 tcpd->fwd->tcp_analyze_seq_info->nextseq = tcpd->fwd->tcp_analyze_seq_info->maxseqtobeacked;
6602 
6603                 if(!tcpd->ta)
6604                     tcp_analyze_get_acked_struct(pinfo->num, tcph->th_seq, tcph->th_ack, TRUE, tcpd);
6605                 tcpd->ta->flags|=TCP_A_REUSED_PORTS;
6606             }
6607         }
6608     }
6609 
6610     /* If this is a SYN/ACK packet, then check if its seq-nr is different
6611      * from the base_seq of the retrieved conversation. If this is the
6612      * case, try to find a conversation with the same addresses and ports
6613      * and set the TA_PORTS_REUSED flag. If the seq-nr is the same as
6614      * the base_seq, then do nothing so it will be marked as a retrans-
6615      * mission later.
6616      * XXX - Is this affected by MPTCP which can use multiple SYNs?
6617      */
6618     if(tcpd && ((tcph->th_flags&(TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) &&
6619         (tcpd->fwd->static_flags & TCP_S_BASE_SEQ_SET) &&
6620         (tcph->th_seq!=tcpd->fwd->base_seq) ) {
6621         if (!(pinfo->fd->visited)) {
6622             /* Reset the last frame seen in the conversation */
6623             if (save_last_frame > 0)
6624                 conv->last_frame = save_last_frame;
6625         }
6626 
6627         other_conv = find_conversation(pinfo->num, &pinfo->dst, &pinfo->src, ENDPOINT_TCP, pinfo->destport, pinfo->srcport, 0);
6628         if (other_conv != NULL)
6629         {
6630             conv = other_conv;
6631             tcpd=get_tcp_conversation_data(conv,pinfo);
6632 
6633             /* the retrieved conversation might have a different base_seq (issue 16944) */
6634             tcpd->fwd->base_seq = tcph->th_seq;
6635         }
6636 
6637         if(!tcpd->ta)
6638             tcp_analyze_get_acked_struct(pinfo->num, tcph->th_seq, tcph->th_ack, TRUE, tcpd);
6639         tcpd->ta->flags|=TCP_A_REUSED_PORTS;
6640     }
6641 
6642     if (tcpd) {
6643         item = proto_tree_add_uint(tcp_tree, hf_tcp_stream, tvb, offset, 0, tcpd->stream);
6644         proto_item_set_generated(item);
6645 
6646         /* Display the completeness of this TCP conversation */
6647         item = proto_tree_add_uint(tcp_tree, hf_tcp_completeness, NULL, 0, 0, tcpd->conversation_completeness);
6648         proto_item_set_generated(item);
6649 
6650         /* Copy the stream index into the header as well to make it available
6651          * to tap listeners.
6652          */
6653         tcph->th_stream = tcpd->stream;
6654 
6655         /* initialize the SACK blocks seen to 0 */
6656         if(tcp_analyze_seq && tcpd->fwd->tcp_analyze_seq_info) {
6657             tcpd->fwd->tcp_analyze_seq_info->num_sack_ranges = 0;
6658         }
6659     }
6660 
6661     /* Do we need to calculate timestamps relative to the tcp-stream? */
6662     if (tcp_calculate_ts) {
6663         tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num);
6664 
6665         /*
6666          * Calculate the timestamps relative to this conversation (but only on the
6667          * first run when frames are accessed sequentially)
6668          */
6669         if (!(pinfo->fd->visited))
6670             tcp_calculate_timestamps(pinfo, tcpd, tcppd);
6671     }
6672 
6673     /*
6674      * If we've been handed an IP fragment, we don't know how big the TCP
6675      * segment is, so don't do anything that requires that we know that.
6676      *
6677      * The same applies if we're part of an error packet.  (XXX - if the
6678      * ICMP and ICMPv6 dissectors could set a "this is how big the IP
6679      * header says it is" length in the tvbuff, we could use that; such
6680      * a length might also be useful for handling packets where the IP
6681      * length is bigger than the actual data available in the frame; the
6682      * dissectors should trust that length, and then throw a
6683      * ReportedBoundsError exception when they go past the end of the frame.)
6684      *
6685      * We also can't determine the segment length if the reported length
6686      * of the TCP packet is less than the TCP header length.
6687      */
6688     reported_len = tvb_reported_length(tvb);
6689 
6690     if (!pinfo->fragmented && !pinfo->flags.in_error_pkt) {
6691         if (reported_len < tcph->th_hlen) {
6692             proto_tree_add_expert_format(tcp_tree, pinfo, &ei_tcp_short_segment, tvb, offset, 0,
6693                                      "Short segment. Segment/fragment does not contain a full TCP header"
6694                                      " (might be NMAP or someone else deliberately sending unusual packets)");
6695             tcph->th_have_seglen = FALSE;
6696         } else {
6697             proto_item *pi;
6698 
6699             /* Compute the length of data in this segment. */
6700             tcph->th_seglen = reported_len - tcph->th_hlen;
6701             tcph->th_have_seglen = TRUE;
6702 
6703             pi = proto_tree_add_uint(ti, hf_tcp_len, tvb, offset+12, 1, tcph->th_seglen);
6704             proto_item_set_generated(pi);
6705 
6706             /* handle TCP seq# analysis parse all new segments we see */
6707             if(tcp_analyze_seq) {
6708                 if(!(pinfo->fd->visited)) {
6709                     tcp_analyze_sequence_number(pinfo, tcph->th_seq, tcph->th_ack, tcph->th_seglen, tcph->th_flags, tcph->th_win, tcpd);
6710                 }
6711                 if(tcpd && tcp_relative_seq) {
6712                     (tcph->th_seq) -= tcpd->fwd->base_seq;
6713                     if (tcph->th_flags & TH_ACK) {
6714                         (tcph->th_ack) -= tcpd->rev->base_seq;
6715                     }
6716                 }
6717             }
6718 
6719             /* re-calculate window size, based on scaling factor */
6720             if (!(tcph->th_flags&TH_SYN)) {   /* SYNs are never scaled */
6721                 if (tcpd && (tcpd->fwd->win_scale>=0)) {
6722                     (tcph->th_win)<<=tcpd->fwd->win_scale;
6723                 }
6724                 else if (tcpd && (tcpd->fwd->win_scale == -1)) {
6725                     /* i.e. Unknown, but wasn't signalled with no scaling, so use preference setting instead! */
6726                     if (tcp_default_window_scaling>=0) {
6727                         (tcph->th_win)<<=tcp_default_window_scaling;
6728                     }
6729                 }
6730             }
6731 
6732             /* Compute the sequence number of next octet after this segment. */
6733             nxtseq = tcph->th_seq + tcph->th_seglen;
6734         }
6735     } else
6736         tcph->th_have_seglen = FALSE;
6737 
6738     flags_str = tcp_flags_to_str(pinfo->pool, tcph);
6739     flags_str_first_letter = tcp_flags_to_str_first_letter(pinfo->pool, tcph);
6740 
6741     col_append_lstr(pinfo->cinfo, COL_INFO,
6742         " [", flags_str, "]",
6743         COL_ADD_LSTR_TERMINATOR);
6744     tcp_info_append_uint(pinfo, "Seq", tcph->th_seq);
6745     if (tcph->th_flags&TH_ACK)
6746         tcp_info_append_uint(pinfo, "Ack", tcph->th_ack);
6747 
6748     tcp_info_append_uint(pinfo, "Win", tcph->th_win);
6749 
6750     if (tcp_summary_in_tree) {
6751         proto_item_append_text(ti, ", Seq: %u", tcph->th_seq);
6752     }
6753 
6754     if (!icmp_ip) {
6755         if(tcp_relative_seq && tcp_analyze_seq) {
6756             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);
6757             proto_tree_add_uint(tcp_tree, hf_tcp_seq_abs, tvb, offset + 4, 4, tcph->th_rawseq);
6758         } else {
6759             proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, tcph->th_seq);
6760             hide_seqack_abs_item = proto_tree_add_uint(tcp_tree, hf_tcp_seq_abs, tvb, offset + 4, 4, tcph->th_rawseq);
6761             proto_item_set_hidden(hide_seqack_abs_item);
6762         }
6763     }
6764 
6765     if (tcph->th_hlen < TCPH_MIN_LEN) {
6766         /* Give up at this point; we put the source and destination port in
6767            the tree, before fetching the header length, so that they'll
6768            show up if this is in the failing packet in an ICMP error packet,
6769            but it's now time to give up if the header length is bogus. */
6770         col_append_fstr(pinfo->cinfo, COL_INFO, ", bogus TCP header length (%u, must be at least %u)",
6771                         tcph->th_hlen, TCPH_MIN_LEN);
6772         if (tree) {
6773             tf = proto_tree_add_uint_bits_format_value(tcp_tree, hf_tcp_hdr_len, tvb, (offset + 12) << 3, 4, tcph->th_hlen,
6774                                                        ENC_BIG_ENDIAN, "%u bytes (%u)", tcph->th_hlen, tcph->th_hlen >> 2);
6775             expert_add_info_format(pinfo, tf, &ei_tcp_bogus_header_length,
6776                                    "Bogus TCP header length (%u, must be at least %u)", tcph->th_hlen, TCPH_MIN_LEN);
6777         }
6778         return offset+12;
6779     }
6780 
6781     /* initialize or move forward the conversation completeness */
6782     if(tcpd) {
6783       if(conversation_is_new) { /* pure SYN must be sought in new conversations only */
6784         if((tcph->th_flags&(TH_SYN|TH_ACK))==TH_SYN) {
6785           conversation_completeness |= TCP_COMPLETENESS_SYNSENT;
6786           if(tcph->th_seglen > 0) { /* TCP Fast Open */
6787             conversation_completeness |= TCP_COMPLETENESS_DATA;
6788           }
6789         }
6790       }
6791       else {
6792           conversation_completeness  = tcpd->conversation_completeness ;
6793 
6794           /* SYN-ACK */
6795           if((tcph->th_flags&(TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
6796               conversation_completeness |= TCP_COMPLETENESS_SYNACK;
6797           }
6798 
6799           /* ACKs */
6800           if((tcph->th_flags&(TH_SYN|TH_ACK))==(TH_ACK)) {
6801               if(tcph->th_seglen>0) { /* transporting some data */
6802                   conversation_completeness |= TCP_COMPLETENESS_DATA;
6803               }
6804               else { /* pure ACK */
6805                   conversation_completeness |= TCP_COMPLETENESS_ACK;
6806               }
6807           }
6808 
6809           /* FIN-ACK */
6810           if((tcph->th_flags&(TH_FIN|TH_ACK))==(TH_FIN|TH_ACK)) {
6811               conversation_completeness |= TCP_COMPLETENESS_FIN;
6812           }
6813 
6814           /* RST */
6815           if(tcph->th_flags&(TH_RST)) {
6816               conversation_completeness |= TCP_COMPLETENESS_RST;
6817           }
6818       }
6819     }
6820     tcpd->conversation_completeness = conversation_completeness;
6821 
6822     if (tcp_summary_in_tree) {
6823         if(tcph->th_flags&TH_ACK) {
6824             proto_item_append_text(ti, ", Ack: %u", tcph->th_ack);
6825         }
6826         if (tcph->th_have_seglen)
6827             proto_item_append_text(ti, ", Len: %u", tcph->th_seglen);
6828     }
6829     proto_item_set_len(ti, tcph->th_hlen);
6830     if (tcph->th_have_seglen) {
6831         if(tcp_relative_seq && tcp_analyze_seq) {
6832             if (tcph->th_flags&(TH_SYN|TH_FIN))  {
6833                 tf=proto_tree_add_uint_format_value(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq + 1, "%u    (relative sequence number)", nxtseq + 1);
6834             } else  {
6835                 tf=proto_tree_add_uint_format_value(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq, "%u    (relative sequence number)", nxtseq);
6836             }
6837         } else {
6838             if (tcph->th_flags&(TH_SYN|TH_FIN))  {
6839                 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq + 1);
6840             } else  {
6841                 tf=proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
6842             }
6843         }
6844         proto_item_set_generated(tf);
6845     }
6846 
6847     tf = proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, tcph->th_ack);
6848     hide_seqack_abs_item = proto_tree_add_uint(tcp_tree, hf_tcp_ack_abs, tvb, offset + 8, 4, tcph->th_rawack);
6849     if (tcph->th_flags & TH_ACK) {
6850         if (tcp_relative_seq && tcp_analyze_seq) {
6851             proto_item_append_text(tf, "    (relative ack number)");
6852         } else {
6853             proto_item_set_hidden(hide_seqack_abs_item);
6854         }
6855         if ((tcph->th_flags & TH_SYN) && tcp_analyze_seq) {
6856             if ((tcp_relative_seq && tcph->th_ack > 1) ||
6857                (!tcp_relative_seq && tcpd && (tcph->th_ack - tcpd->rev->base_seq) > 1)) {
6858                 expert_add_info(pinfo, tf, &ei_tcp_analysis_tfo_ack);
6859             } else if (tcpd && tcpd->tfo_syn_data) {
6860                 expert_add_info(pinfo, tf, &ei_tcp_analysis_tfo_ignored);
6861             }
6862         }
6863     } else {
6864         /* Note if the ACK field is non-zero */
6865         if (tvb_get_ntohl(tvb, offset+8) != 0) {
6866             expert_add_info(pinfo, tf, &ei_tcp_ack_nonzero);
6867         }
6868     }
6869 
6870     if (tree) {
6871         // This should be consistent with ip.hdr_len.
6872         proto_tree_add_uint_bits_format_value(tcp_tree, hf_tcp_hdr_len, tvb, (offset + 12) << 3, 4, tcph->th_hlen,
6873             ENC_BIG_ENDIAN, "%u bytes (%u)", tcph->th_hlen, tcph->th_hlen>>2);
6874         tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 12, 2,
6875                                         tcph->th_flags, "Flags: 0x%03x (%s)", tcph->th_flags, flags_str);
6876         field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
6877         proto_tree_add_boolean(field_tree, hf_tcp_flags_res, tvb, offset + 12, 1, tcph->th_flags);
6878         proto_tree_add_boolean(field_tree, hf_tcp_flags_ns, tvb, offset + 12, 1, tcph->th_flags);
6879         proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, tcph->th_flags);
6880         proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, tcph->th_flags);
6881         proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
6882         proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
6883         proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
6884         tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
6885         tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
6886         tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
6887 
6888         tf = proto_tree_add_string(field_tree, hf_tcp_flags_str, tvb, offset + 12, 2, flags_str_first_letter);
6889         proto_item_set_generated(tf);
6890         /* As discussed in bug 5541, it is better to use two separate
6891          * fields for the real and calculated window size.
6892          */
6893         proto_tree_add_uint(tcp_tree, hf_tcp_window_size_value, tvb, offset + 14, 2, real_window);
6894         scaled_pi = proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win);
6895         proto_item_set_generated(scaled_pi);
6896 
6897         if( !(tcph->th_flags&TH_SYN) && tcpd ) {
6898             switch (tcpd->fwd->win_scale) {
6899 
6900             case -1:
6901                 /* Unknown */
6902                 {
6903                     gint16 win_scale = tcpd->fwd->win_scale;
6904                     gboolean override_with_pref = FALSE;
6905 
6906                     /* Use preference setting (if set) */
6907                     if (tcp_default_window_scaling != WindowScaling_NotKnown) {
6908                         win_scale = (1 << tcp_default_window_scaling);
6909                         override_with_pref = TRUE;
6910                     }
6911 
6912                     scaled_pi = proto_tree_add_int_format_value(tcp_tree, hf_tcp_window_size_scalefactor, tvb, offset + 14, 2,
6913                                                           win_scale, "%d (%s)",
6914                                                           win_scale,
6915                                                           (override_with_pref) ? "missing - taken from preference" : "unknown");
6916                     proto_item_set_generated(scaled_pi);
6917                 }
6918                 break;
6919 
6920             case -2:
6921                 /* No window scaling used */
6922                 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);
6923                 proto_item_set_generated(scaled_pi);
6924                 break;
6925 
6926             default:
6927                 /* Scaling from signalled value */
6928                 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);
6929                 proto_item_set_generated(scaled_pi);
6930             }
6931         }
6932     }
6933 
6934     if(tcph->th_flags & TH_SYN) {
6935         if(tcph->th_flags & TH_ACK) {
6936            expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_synack,
6937                                   "Connection establish acknowledge (SYN+ACK): server port %u", tcph->th_sport);
6938            /* Save the server port to help determine dissector used */
6939            tcpd->server_port = tcph->th_sport;
6940         }
6941         else {
6942            expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_syn,
6943                                   "Connection establish request (SYN): server port %u", tcph->th_dport);
6944            /* Save the server port to help determine dissector used */
6945            tcpd->server_port = tcph->th_dport;
6946            tcpd->ts_mru_syn = pinfo->abs_ts;
6947         }
6948         /* Remember where the next segment will start. */
6949         if (tcp_desegment && tcp_reassemble_out_of_order && tcpd && !PINFO_FD_VISITED(pinfo)) {
6950             if (tcpd->fwd->maxnextseq == 0) {
6951                 tcpd->fwd->maxnextseq = tcph->th_seq + 1;
6952             }
6953         }
6954         /* Initiliaze the is_first_ack */
6955         tcpd->fwd->is_first_ack = TRUE;
6956     }
6957     if(tcph->th_flags & TH_FIN) {
6958         /* XXX - find a way to know the server port and output only that one */
6959         expert_add_info(pinfo, tf_fin, &ei_tcp_connection_fin);
6960 
6961         /* Track closing initiator.
6962            If it was not already closed by the reverse flow, it means we are the first */
6963         if(!tcpd->rev->closing_initiator) {
6964             tcpd->fwd->closing_initiator = TRUE;
6965             expert_add_info(pinfo, tf, &ei_tcp_connection_fin_active);
6966         } else {
6967             expert_add_info(pinfo, tf, &ei_tcp_connection_fin_passive);
6968         }
6969     }
6970     if(tcph->th_flags & TH_RST)
6971         /* XXX - find a way to know the server port and output only that one */
6972         expert_add_info(pinfo, tf_rst, &ei_tcp_connection_rst);
6973 
6974     if(tcp_analyze_seq
6975             && (tcph->th_flags & (TH_SYN|TH_ACK)) == TH_ACK
6976             && !nstime_is_zero(&tcpd->ts_mru_syn)
6977             &&  nstime_is_zero(&tcpd->ts_first_rtt)) {
6978         /* If all of the following:
6979          * - we care (the pref is set)
6980          * - this is a pure ACK
6981          * - we have a timestamp for the most-recently-transmitted SYN
6982          * - we haven't seen a pure ACK yet (no ts_first_rtt stored)
6983          * then assume it's the last part of the handshake and store the initial
6984          * RTT time
6985          */
6986         nstime_delta(&(tcpd->ts_first_rtt), &(pinfo->abs_ts), &(tcpd->ts_mru_syn));
6987     }
6988 
6989     /*
6990      * Remember if we have already seen at least one ACK,
6991      * then we can neutralize the Window Scale side-effect at the beginning (issue 14690)
6992      */
6993     if(tcp_analyze_seq
6994             && (tcph->th_flags & (TH_SYN|TH_ACK)) == TH_ACK) {
6995         if(tcpd->fwd->is_first_ack) {
6996             tcpd->fwd->is_first_ack = FALSE;
6997         }
6998     }
6999 
7000     /* Supply the sequence number of the first byte and of the first byte
7001        after the segment. */
7002     tcpinfo.seq = tcph->th_seq;
7003     tcpinfo.nxtseq = nxtseq;
7004     tcpinfo.lastackseq = tcph->th_ack;
7005 
7006     /* Assume we'll pass un-reassembled data to subdissectors. */
7007     tcpinfo.is_reassembled = FALSE;
7008 
7009     /*
7010      * Assume, initially, that we can't desegment.
7011      */
7012     pinfo->can_desegment = 0;
7013     th_sum = tvb_get_ntohs(tvb, offset + 16);
7014     if (!pinfo->fragmented && tvb_bytes_exist(tvb, 0, reported_len)) {
7015         /* The packet isn't part of an un-reassembled fragmented datagram
7016            and isn't truncated.  This means we have all the data, and thus
7017            can checksum it and, unless it's being returned in an error
7018            packet, are willing to allow subdissectors to request reassembly
7019            on it. */
7020 
7021         if (tcp_check_checksum) {
7022             /* We haven't turned checksum checking off; checksum it. */
7023 
7024             /* Set up the fields of the pseudo-header. */
7025             SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len);
7026             SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len);
7027             switch (pinfo->src.type) {
7028 
7029             case AT_IPv4:
7030                 phdr[0] = g_htonl((IP_PROTO_TCP<<16) + reported_len);
7031                 SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)phdr, 4);
7032                 break;
7033 
7034             case AT_IPv6:
7035                 phdr[0] = g_htonl(reported_len);
7036                 phdr[1] = g_htonl(IP_PROTO_TCP);
7037                 SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)phdr, 8);
7038                 break;
7039 
7040             default:
7041                 /* TCP runs only atop IPv4 and IPv6.... */
7042                 DISSECTOR_ASSERT_NOT_REACHED();
7043                 break;
7044             }
7045             SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, offset, reported_len);
7046             computed_cksum = in_cksum(cksum_vec, 4);
7047             if (computed_cksum == 0 && th_sum == 0xffff) {
7048                 item = proto_tree_add_uint_format_value(tcp_tree, hf_tcp_checksum, tvb,
7049                                                   offset + 16, 2, th_sum,
7050                                                   "0x%04x [should be 0x0000 (see RFC 1624)]", th_sum);
7051 
7052                 checksum_tree = proto_item_add_subtree(item, ett_tcp_checksum);
7053                 item = proto_tree_add_uint(checksum_tree, hf_tcp_checksum_calculated, tvb,
7054                                               offset + 16, 2, 0x0000);
7055                 proto_item_set_generated(item);
7056                 /* XXX - What should this special status be? */
7057                 item = proto_tree_add_uint(checksum_tree, hf_tcp_checksum_status, tvb,
7058                                               offset + 16, 0, PROTO_CHECKSUM_E_BAD);
7059                 proto_item_set_generated(item);
7060                 expert_add_info(pinfo, item, &ei_tcp_checksum_ffff);
7061 
7062                 col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM 0xFFFF]");
7063 
7064                 /* Checksum is treated as valid on most systems, so we're willing to desegment it. */
7065                 desegment_ok = TRUE;
7066             } else {
7067                 proto_item* calc_item;
7068                 item = proto_tree_add_checksum(tcp_tree, tvb, offset+16, hf_tcp_checksum, hf_tcp_checksum_status, &ei_tcp_checksum_bad, pinfo, computed_cksum,
7069                                                ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM);
7070 
7071                 calc_item = proto_tree_add_uint(tcp_tree, hf_tcp_checksum_calculated, tvb,
7072                                               offset + 16, 2, in_cksum_shouldbe(th_sum, computed_cksum));
7073                 proto_item_set_generated(calc_item);
7074 
7075                 /* Checksum is valid, so we're willing to desegment it. */
7076                 if (computed_cksum == 0) {
7077                     desegment_ok = TRUE;
7078                 } else {
7079                     proto_item_append_text(item, "(maybe caused by \"TCP checksum offload\"?)");
7080 
7081                     /* Checksum is invalid, so we're not willing to desegment it. */
7082                     desegment_ok = FALSE;
7083                     pinfo->noreassembly_reason = " [incorrect TCP checksum]";
7084                     col_append_str(pinfo->cinfo, COL_INFO, " [TCP CHECKSUM INCORRECT]");
7085                 }
7086             }
7087         } else {
7088             proto_tree_add_checksum(tcp_tree, tvb, offset+16, hf_tcp_checksum, hf_tcp_checksum_status, &ei_tcp_checksum_bad, pinfo, 0,
7089                                     ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
7090 
7091             /* We didn't check the checksum, and don't care if it's valid,
7092                so we're willing to desegment it. */
7093             desegment_ok = TRUE;
7094         }
7095     } else {
7096         /* We don't have all the packet data, so we can't checksum it... */
7097         proto_tree_add_checksum(tcp_tree, tvb, offset+16, hf_tcp_checksum, hf_tcp_checksum_status, &ei_tcp_checksum_bad, pinfo, 0,
7098                                     ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
7099 
7100         /* ...and aren't willing to desegment it. */
7101         desegment_ok = FALSE;
7102     }
7103 
7104     if (desegment_ok) {
7105         /* We're willing to desegment this.  Is desegmentation enabled? */
7106         if (tcp_desegment) {
7107             /* Yes - is this segment being returned in an error packet? */
7108             if (!pinfo->flags.in_error_pkt) {
7109                 /* No - indicate that we will desegment.
7110                    We do NOT want to desegment segments returned in error
7111                    packets, as they're not part of a TCP connection. */
7112                 pinfo->can_desegment = 2;
7113             }
7114         }
7115     }
7116 
7117     item = proto_tree_add_item_ret_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, ENC_BIG_ENDIAN, &th_urp);
7118 
7119     if (IS_TH_URG(tcph->th_flags)) {
7120         /* Export the urgent pointer, for the benefit of protocols such as
7121            rlogin. */
7122         tcpinfo.urgent_pointer = (guint16)th_urp;
7123         tcp_info_append_uint(pinfo, "Urg", th_urp);
7124     } else {
7125          if (th_urp) {
7126             /* Note if the urgent pointer field is non-zero */
7127             expert_add_info(pinfo, item, &ei_tcp_urgent_pointer_non_zero);
7128          }
7129     }
7130 
7131     if (tcph->th_have_seglen)
7132         tcp_info_append_uint(pinfo, "Len", tcph->th_seglen);
7133 
7134     /* If there's more than just the fixed-length header (20 bytes), create
7135        a protocol tree item for the options.  (We already know there's
7136        not less than the fixed-length header - we checked that above.)
7137 
7138        We ensure that we don't throw an exception here, so that we can
7139        do some analysis before we dissect the options and possibly
7140        throw an exception.  (Trying to avoid throwing an exception when
7141        dissecting options is not something we should do.) */
7142     optlen = tcph->th_hlen - TCPH_MIN_LEN; /* length of options, in bytes */
7143     options_item = NULL;
7144     options_tree = NULL;
7145     if (optlen != 0) {
7146         guint bc = (guint)tvb_captured_length_remaining(tvb, offset + 20);
7147 
7148         if (tcp_tree != NULL) {
7149             options_item = proto_tree_add_item(tcp_tree, hf_tcp_options, tvb, offset + 20,
7150                                                bc < optlen ? bc : optlen, ENC_NA);
7151             proto_item_set_text(options_item, "Options: (%u bytes)", optlen);
7152             options_tree = proto_item_add_subtree(options_item, ett_tcp_options);
7153         }
7154     }
7155 
7156     tcph->num_sack_ranges = 0;
7157 
7158     /* handle conversation timestamps */
7159     if(tcp_calculate_ts) {
7160         tcp_print_timestamps(pinfo, tvb, tcp_tree, tcpd, tcppd);
7161     }
7162 
7163     /* Now dissect the options. */
7164     if (optlen) {
7165         rvbd_option_data* option_data;
7166 
7167         tcp_dissect_options(tvb, offset + 20, optlen,
7168                                TCPOPT_EOL, pinfo, options_tree,
7169                                options_item, tcph);
7170 
7171         /* Do some post evaluation of some Riverbed probe options in the list */
7172         option_data = (rvbd_option_data*)p_get_proto_data(pinfo->pool, pinfo, proto_tcp_option_rvbd_probe, pinfo->curr_layer_num);
7173         if (option_data != NULL)
7174         {
7175             if (option_data->valid)
7176             {
7177                 /* Distinguish S+ from S+* */
7178                 col_prepend_fstr(pinfo->cinfo, COL_INFO, "S%s, ",
7179                                      option_data->type == PROBE_TRACE ? "#" :
7180                                      (option_data->probe_flags & RVBD_FLAGS_PROBE_NCFE) ? "+*" : "+");
7181             }
7182         }
7183 
7184     }
7185 
7186     /* handle TCP seq# analysis, print any extra SEQ/ACK data for this segment*/
7187     if(tcp_analyze_seq) {
7188         guint32 use_seq = tcph->th_seq;
7189         guint32 use_ack = tcph->th_ack;
7190         /* May need to recover absolute values here... */
7191         if (tcp_relative_seq) {
7192             use_seq += tcpd->fwd->base_seq;
7193             if (tcph->th_flags & TH_ACK) {
7194                 use_ack += tcpd->rev->base_seq;
7195             }
7196         }
7197         tcp_print_sequence_number_analysis(pinfo, tvb, tcp_tree, tcpd, use_seq, use_ack);
7198     }
7199 
7200     if(!pinfo->fd->visited) {
7201         if((tcph->th_flags & TH_SYN)==TH_SYN) {
7202             /* Check the validity of the window scale value
7203              */
7204             verify_tcp_window_scaling((tcph->th_flags&TH_ACK)==TH_ACK,tcpd);
7205         }
7206 
7207         if((tcph->th_flags & (TH_SYN|TH_ACK))==(TH_SYN|TH_ACK)) {
7208             /* If the SYN or the SYN+ACK offered SCPS capabilities,
7209              * validate the flow's bidirectional scps capabilities.
7210              * The or protects against broken implementations offering
7211              * SCPS capabilities on SYN+ACK even if it wasn't offered with the SYN
7212              */
7213             if(tcpd && ((tcpd->rev->scps_capable) || (tcpd->fwd->scps_capable))) {
7214                 verify_scps(pinfo, tf_syn, tcpd);
7215             }
7216 
7217         }
7218     }
7219 
7220     if (tcph->th_mptcp) {
7221 
7222         if (tcp_analyze_mptcp) {
7223             mptcp_add_analysis_subtree(pinfo, tvb, tcp_tree, tcpd, tcpd->mptcp_analysis, tcph );
7224         }
7225     }
7226 
7227     /* Skip over header + options */
7228     offset += tcph->th_hlen;
7229 
7230     /* Check the packet length to see if there's more data
7231        (it could be an ACK-only packet) */
7232     captured_length_remaining = tvb_captured_length_remaining(tvb, offset);
7233 
7234     if (tcph->th_have_seglen) {
7235         if(have_tap_listener(tcp_follow_tap)) {
7236             tcp_follow_tap_data_t* follow_data = wmem_new0(pinfo->pool, tcp_follow_tap_data_t);
7237 
7238             follow_data->tvb = tvb_new_subset_remaining(tvb, offset);
7239             follow_data->tcph = tcph;
7240             follow_data->tcpd = tcpd;
7241 
7242             tap_queue_packet(tcp_follow_tap, pinfo, follow_data);
7243         }
7244     }
7245 
7246     tap_queue_packet(tcp_tap, pinfo, tcph);
7247 
7248     /* if it is an MPTCP packet */
7249     if(tcpd->mptcp_analysis) {
7250         tap_queue_packet(mptcp_tap, pinfo, tcpd);
7251     }
7252 
7253     /* If we're reassembling something whose length isn't known
7254      * beforehand, and that runs all the way to the end of
7255      * the data stream, a FIN indicates the end of the data
7256      * stream and thus the completion of reassembly, so we
7257      * need to explicitly check for that here.
7258      */
7259     if(tcph->th_have_seglen && tcpd && (tcph->th_flags & TH_FIN)
7260        && (tcpd->fwd->flags&TCP_FLOW_REASSEMBLE_UNTIL_FIN) ) {
7261         struct tcp_multisegment_pdu *msp;
7262 
7263         /* Is this the FIN that ended the data stream or is it a
7264          * retransmission of that FIN?
7265          */
7266         if (tcpd->fwd->fin == 0 || tcpd->fwd->fin == pinfo->num) {
7267             /* Either we haven't seen a FIN for this flow or we
7268              * have and it's this frame. Note that this is the FIN
7269              * for this flow, terminate reassembly and dissect the
7270              * results. */
7271             tcpd->fwd->fin = pinfo->num;
7272             msp=(struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(tcpd->fwd->multisegment_pdus, tcph->th_seq-1);
7273             if(msp) {
7274                 fragment_head *ipfd_head;
7275 
7276                 ipfd_head = fragment_add(&tcp_reassembly_table, tvb, offset,
7277                                          pinfo, msp->first_frame, NULL,
7278                                          tcph->th_seq - msp->seq,
7279                                          tcph->th_seglen,
7280                                          FALSE );
7281                 if(ipfd_head) {
7282                     tvbuff_t *next_tvb;
7283 
7284                     /* create a new TVB structure for desegmented data
7285                      * datalen-1 to strip the dummy FIN byte off
7286                      */
7287                     next_tvb = tvb_new_chain(tvb, ipfd_head->tvb_data);
7288 
7289                     /* add desegmented data to the data source list */
7290                     add_new_data_source(pinfo, next_tvb, "Reassembled TCP");
7291 
7292                     /* Show details of the reassembly */
7293                     print_tcp_fragment_tree(ipfd_head, tree, tcp_tree, pinfo, next_tvb);
7294 
7295                     /* call the payload dissector
7296                      * but make sure we don't offer desegmentation any more
7297                      */
7298                     pinfo->can_desegment = 0;
7299 
7300                     process_tcp_payload(next_tvb, 0, pinfo, tree, tcp_tree, tcph->th_sport, tcph->th_dport, tcph->th_seq,
7301                                         nxtseq, FALSE, tcpd, &tcpinfo);
7302 
7303                     return tvb_captured_length(tvb);
7304                 }
7305             }
7306         } else {
7307             /* Yes.  This is a retransmission of the final FIN (or it's
7308              * the final FIN transmitted via a different path).
7309              * XXX - we need to flag retransmissions a bit better.
7310              */
7311             proto_tree_add_uint(tcp_tree, hf_tcp_fin_retransmission, tvb, 0, 0, tcpd->fwd->fin);
7312         }
7313     }
7314 
7315     if (tcp_display_process_info && tcpd && ((tcpd->fwd && tcpd->fwd->process_info && tcpd->fwd->process_info->command) ||
7316                  (tcpd->rev && tcpd->rev->process_info && tcpd->rev->process_info->command))) {
7317         field_tree = proto_tree_add_subtree(tcp_tree, tvb, offset, 0, ett_tcp_process_info, &ti, "Process Information");
7318         proto_item_set_generated(ti);
7319         if (tcpd->fwd && tcpd->fwd->process_info && tcpd->fwd->process_info->command) {
7320             proto_tree_add_uint(field_tree, hf_tcp_proc_dst_uid, tvb, 0, 0, tcpd->fwd->process_info->process_uid);
7321             proto_tree_add_uint(field_tree, hf_tcp_proc_dst_pid, tvb, 0, 0, tcpd->fwd->process_info->process_pid);
7322             proto_tree_add_string(field_tree, hf_tcp_proc_dst_uname, tvb, 0, 0, tcpd->fwd->process_info->username);
7323             proto_tree_add_string(field_tree, hf_tcp_proc_dst_cmd, tvb, 0, 0, tcpd->fwd->process_info->command);
7324         }
7325         if (tcpd->rev && tcpd->rev->process_info && tcpd->rev->process_info->command) {
7326             proto_tree_add_uint(field_tree, hf_tcp_proc_src_uid, tvb, 0, 0, tcpd->rev->process_info->process_uid);
7327             proto_tree_add_uint(field_tree, hf_tcp_proc_src_pid, tvb, 0, 0, tcpd->rev->process_info->process_pid);
7328             proto_tree_add_string(field_tree, hf_tcp_proc_src_uname, tvb, 0, 0, tcpd->rev->process_info->username);
7329             proto_tree_add_string(field_tree, hf_tcp_proc_src_cmd, tvb, 0, 0, tcpd->rev->process_info->command);
7330         }
7331     }
7332 
7333     /*
7334      * XXX - what, if any, of this should we do if this is included in an
7335      * error packet?  It might be nice to see the details of the packet
7336      * that caused the ICMP error, but it might not be nice to have the
7337      * dissector update state based on it.
7338      * Also, we probably don't want to run TCP taps on those packets.
7339      */
7340     if (captured_length_remaining != 0) {
7341         if (tcph->th_flags & TH_RST) {
7342             /*
7343              * RFC1122 says:
7344              *
7345              *  4.2.2.12  RST Segment: RFC-793 Section 3.4
7346              *
7347              *    A TCP SHOULD allow a received RST segment to include data.
7348              *
7349              *    DISCUSSION
7350              *         It has been suggested that a RST segment could contain
7351              *         ASCII text that encoded and explained the cause of the
7352              *         RST.  No standard has yet been established for such
7353              *         data.
7354              *
7355              * so for segments with RST we just display the data as text.
7356              */
7357             proto_tree_add_item(tcp_tree, hf_tcp_reset_cause, tvb, offset, captured_length_remaining, ENC_NA|ENC_ASCII);
7358         } else {
7359         /* When we have a frame with TCP SYN bit set and segmented TCP payload we need
7360          * to increment seq and nxtseq to detect the overlapping byte(s). This is to fix Bug 9882.
7361          */
7362             if(tcph->th_flags & TH_SYN) {
7363                 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq + 1, nxtseq + 1,
7364                                     tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd, &tcpinfo);
7365             } else {
7366                 dissect_tcp_payload(tvb, pinfo, offset, tcph->th_seq, nxtseq,
7367                                     tcph->th_sport, tcph->th_dport, tree, tcp_tree, tcpd, &tcpinfo);
7368             }
7369         }
7370     }
7371     return tvb_captured_length(tvb);
7372 }
7373 
7374 static void
tcp_init(void)7375 tcp_init(void)
7376 {
7377     tcp_stream_count = 0;
7378 
7379     /* MPTCP init */
7380     mptcp_stream_count = 0;
7381     mptcp_tokens = wmem_tree_new(wmem_file_scope());
7382 }
7383 
7384 void
proto_register_tcp(void)7385 proto_register_tcp(void)
7386 {
7387     static hf_register_info hf[] = {
7388 
7389         { &hf_tcp_srcport,
7390         { "Source Port",        "tcp.srcport", FT_UINT16, BASE_PT_TCP, NULL, 0x0,
7391             NULL, HFILL }},
7392 
7393         { &hf_tcp_dstport,
7394         { "Destination Port",       "tcp.dstport", FT_UINT16, BASE_PT_TCP, NULL, 0x0,
7395             NULL, HFILL }},
7396 
7397         { &hf_tcp_port,
7398         { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_PT_TCP, NULL, 0x0,
7399             NULL, HFILL }},
7400 
7401         { &hf_tcp_stream,
7402         { "Stream index",       "tcp.stream", FT_UINT32, BASE_DEC, NULL, 0x0,
7403             NULL, HFILL }},
7404 
7405         { &hf_tcp_completeness,
7406         { "Conversation completeness",       "tcp.completeness", FT_UINT8,
7407             BASE_CUSTOM, CF_FUNC(conversation_completeness_fill), 0x0,
7408             "The completeness of the conversation capture", HFILL }},
7409 
7410         { &hf_tcp_seq,
7411         { "Sequence Number",        "tcp.seq", FT_UINT32, BASE_DEC, NULL, 0x0,
7412             NULL, HFILL }},
7413 
7414         { &hf_tcp_seq_abs,
7415         { "Sequence Number (raw)",        "tcp.seq_raw", FT_UINT32, BASE_DEC, NULL, 0x0,
7416             "This shows the raw value of the sequence number", HFILL }},
7417 
7418         { &hf_tcp_nxtseq,
7419         { "Next Sequence Number",   "tcp.nxtseq", FT_UINT32, BASE_DEC, NULL, 0x0,
7420             NULL, HFILL }},
7421 
7422         { &hf_tcp_ack,
7423         { "Acknowledgment Number", "tcp.ack", FT_UINT32, BASE_DEC, NULL, 0x0,
7424             NULL, HFILL }},
7425 
7426         { &hf_tcp_ack_abs,
7427         { "Acknowledgment number (raw)", "tcp.ack_raw", FT_UINT32, BASE_DEC, NULL, 0x0,
7428             "This shows the raw value of the acknowledgment number", HFILL } },
7429 
7430         // "Data Offset" in https://tools.ietf.org/html/rfc793#section-3.1 and
7431         // "Data offset" in https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure
7432         { &hf_tcp_hdr_len,
7433         { "Header Length",    "tcp.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0,
7434             "Data offset in 32-bit words", HFILL }},
7435 
7436         { &hf_tcp_flags,
7437         { "Flags",          "tcp.flags", FT_UINT16, BASE_HEX, NULL, TH_MASK,
7438             "Flags (12 bits)", HFILL }},
7439 
7440         { &hf_tcp_flags_res,
7441         { "Reserved",            "tcp.flags.res", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_RES,
7442             "Three reserved bits (must be zero)", HFILL }},
7443 
7444         { &hf_tcp_flags_ns,
7445         { "Nonce", "tcp.flags.ns", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_NS,
7446             "ECN concealment protection (RFC 3540)", HFILL }},
7447 
7448         { &hf_tcp_flags_cwr,
7449         { "Congestion Window Reduced (CWR)",            "tcp.flags.cwr", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_CWR,
7450             NULL, HFILL }},
7451 
7452         { &hf_tcp_flags_ecn,
7453         { "ECN-Echo",           "tcp.flags.ecn", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_ECN,
7454             NULL, HFILL }},
7455 
7456         { &hf_tcp_flags_urg,
7457         { "Urgent",         "tcp.flags.urg", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_URG,
7458             NULL, HFILL }},
7459 
7460         { &hf_tcp_flags_ack,
7461         { "Acknowledgment",        "tcp.flags.ack", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_ACK,
7462             NULL, HFILL }},
7463 
7464         { &hf_tcp_flags_push,
7465         { "Push",           "tcp.flags.push", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_PUSH,
7466             NULL, HFILL }},
7467 
7468         { &hf_tcp_flags_reset,
7469         { "Reset",          "tcp.flags.reset", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_RST,
7470             NULL, HFILL }},
7471 
7472         { &hf_tcp_flags_syn,
7473         { "Syn",            "tcp.flags.syn", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_SYN,
7474             NULL, HFILL }},
7475 
7476         { &hf_tcp_flags_fin,
7477         { "Fin",            "tcp.flags.fin", FT_BOOLEAN, 12, TFS(&tfs_set_notset), TH_FIN,
7478             NULL, HFILL }},
7479 
7480         { &hf_tcp_flags_str,
7481         { "TCP Flags",          "tcp.flags.str", FT_STRING, STR_UNICODE, NULL, 0x0,
7482             NULL, HFILL }},
7483 
7484         { &hf_tcp_window_size_value,
7485         { "Window",        "tcp.window_size_value", FT_UINT16, BASE_DEC, NULL, 0x0,
7486             "The window size value from the TCP header", HFILL }},
7487 
7488         /* 32 bits so we can present some values adjusted to window scaling */
7489         { &hf_tcp_window_size,
7490         { "Calculated window size",        "tcp.window_size", FT_UINT32, BASE_DEC, NULL, 0x0,
7491             "The scaled window size (if scaling has been used)", HFILL }},
7492 
7493         { &hf_tcp_window_size_scalefactor,
7494         { "Window size scaling factor", "tcp.window_size_scalefactor", FT_INT32, BASE_DEC, NULL, 0x0,
7495             "The window size scaling factor (-1 when unknown, -2 when no scaling is used)", HFILL }},
7496 
7497         { &hf_tcp_checksum,
7498         { "Checksum",           "tcp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
7499             "Details at: https://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
7500 
7501         { &hf_tcp_checksum_status,
7502         { "Checksum Status",      "tcp.checksum.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
7503             NULL, HFILL }},
7504 
7505         { &hf_tcp_checksum_calculated,
7506         { "Calculated Checksum", "tcp.checksum_calculated", FT_UINT16, BASE_HEX, NULL, 0x0,
7507             "The expected TCP checksum field as calculated from the TCP segment", HFILL }},
7508 
7509         { &hf_tcp_analysis,
7510         { "SEQ/ACK analysis",   "tcp.analysis", FT_NONE, BASE_NONE, NULL, 0x0,
7511             "This frame has some of the TCP analysis shown", HFILL }},
7512 
7513         { &hf_tcp_analysis_flags,
7514         { "TCP Analysis Flags",     "tcp.analysis.flags", FT_NONE, BASE_NONE, NULL, 0x0,
7515             "This frame has some of the TCP analysis flags set", HFILL }},
7516 
7517         { &hf_tcp_analysis_duplicate_ack,
7518         { "Duplicate ACK",      "tcp.analysis.duplicate_ack", FT_NONE, BASE_NONE, NULL, 0x0,
7519             "This is a duplicate ACK", HFILL }},
7520 
7521         { &hf_tcp_analysis_duplicate_ack_num,
7522         { "Duplicate ACK #",        "tcp.analysis.duplicate_ack_num", FT_UINT32, BASE_DEC, NULL, 0x0,
7523             "This is duplicate ACK number #", HFILL }},
7524 
7525         { &hf_tcp_analysis_duplicate_ack_frame,
7526         { "Duplicate to the ACK in frame",      "tcp.analysis.duplicate_ack_frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_DUP_ACK), 0x0,
7527             "This is a duplicate to the ACK in frame #", HFILL }},
7528 
7529         { &hf_tcp_continuation_to,
7530         { "This is a continuation to the PDU in frame",     "tcp.continuation_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7531             "This is a continuation to the PDU in frame #", HFILL }},
7532 
7533         { &hf_tcp_len,
7534           { "TCP Segment Len",            "tcp.len", FT_UINT32, BASE_DEC, NULL, 0x0,
7535             NULL, HFILL}},
7536 
7537         { &hf_tcp_analysis_acks_frame,
7538           { "This is an ACK to the segment in frame",            "tcp.analysis.acks_frame", FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_ACK), 0x0,
7539             "Which previous segment is this an ACK for", HFILL}},
7540 
7541         { &hf_tcp_analysis_bytes_in_flight,
7542           { "Bytes in flight",            "tcp.analysis.bytes_in_flight", FT_UINT32, BASE_DEC, NULL, 0x0,
7543             "How many bytes are now in flight for this connection", HFILL}},
7544 
7545         { &hf_tcp_analysis_push_bytes_sent,
7546           { "Bytes sent since last PSH flag",            "tcp.analysis.push_bytes_sent", FT_UINT32, BASE_DEC, NULL, 0x0,
7547             "How many bytes have been sent since the last PSH flag", HFILL}},
7548 
7549         { &hf_tcp_analysis_ack_rtt,
7550           { "The RTT to ACK the segment was",            "tcp.analysis.ack_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
7551             "How long time it took to ACK the segment (RTT)", HFILL}},
7552 
7553         { &hf_tcp_analysis_first_rtt,
7554           { "iRTT",            "tcp.analysis.initial_rtt", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
7555             "How long it took for the SYN to ACK handshake (iRTT)", HFILL}},
7556 
7557         { &hf_tcp_analysis_rto,
7558           { "The RTO for this segment was",            "tcp.analysis.rto", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
7559             "How long transmission was delayed before this segment was retransmitted (RTO)", HFILL}},
7560 
7561         { &hf_tcp_analysis_rto_frame,
7562           { "RTO based on delta from frame", "tcp.analysis.rto_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7563             "This is the frame we measure the RTO from", HFILL }},
7564 
7565         { &hf_tcp_urgent_pointer,
7566         { "Urgent Pointer",     "tcp.urgent_pointer", FT_UINT16, BASE_DEC, NULL, 0x0,
7567             NULL, HFILL }},
7568 
7569         { &hf_tcp_segment_overlap,
7570         { "Segment overlap",    "tcp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
7571             "Segment overlaps with other segments", HFILL }},
7572 
7573         { &hf_tcp_segment_overlap_conflict,
7574         { "Conflicting data in segment overlap",    "tcp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
7575             "Overlapping segments contained conflicting data", HFILL }},
7576 
7577         { &hf_tcp_segment_multiple_tails,
7578         { "Multiple tail segments found",   "tcp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
7579             "Several tails were found when reassembling the pdu", HFILL }},
7580 
7581         { &hf_tcp_segment_too_long_fragment,
7582         { "Segment too long",   "tcp.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
7583             "Segment contained data past end of the pdu", HFILL }},
7584 
7585         { &hf_tcp_segment_error,
7586         { "Reassembling error", "tcp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7587             "Reassembling error due to illegal segments", HFILL }},
7588 
7589         { &hf_tcp_segment_count,
7590         { "Segment count", "tcp.segment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
7591             NULL, HFILL }},
7592 
7593         { &hf_tcp_segment,
7594         { "TCP Segment", "tcp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7595             NULL, HFILL }},
7596 
7597         { &hf_tcp_segments,
7598         { "Reassembled TCP Segments", "tcp.segments", FT_NONE, BASE_NONE, NULL, 0x0,
7599             "TCP Segments", HFILL }},
7600 
7601         { &hf_tcp_reassembled_in,
7602         { "Reassembled PDU in frame", "tcp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
7603             "The PDU that doesn't end in this segment is reassembled in this frame", HFILL }},
7604 
7605         { &hf_tcp_reassembled_length,
7606         { "Reassembled TCP length", "tcp.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
7607             "The total length of the reassembled payload", HFILL }},
7608 
7609         { &hf_tcp_reassembled_data,
7610         { "Reassembled TCP Data", "tcp.reassembled.data", FT_BYTES, BASE_NONE, NULL, 0x0,
7611             "The reassembled payload", HFILL }},
7612 
7613         { &hf_tcp_option_kind,
7614           { "Kind", "tcp.option_kind", FT_UINT8,
7615             BASE_DEC|BASE_EXT_STRING, &tcp_option_kind_vs_ext, 0x0, "This TCP option's kind", HFILL }},
7616 
7617         { &hf_tcp_option_len,
7618           { "Length", "tcp.option_len", FT_UINT8,
7619             BASE_DEC, NULL, 0x0, "Length of this TCP option in bytes (including kind and length fields)", HFILL }},
7620 
7621         { &hf_tcp_options,
7622           { "TCP Options", "tcp.options", FT_BYTES,
7623             BASE_NONE, NULL, 0x0, NULL, HFILL }},
7624 
7625         { &hf_tcp_option_mss_val,
7626           { "MSS Value", "tcp.options.mss_val", FT_UINT16,
7627             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7628 
7629         { &hf_tcp_option_wscale_shift,
7630           { "Shift count", "tcp.options.wscale.shift", FT_UINT8,
7631             BASE_DEC, NULL, 0x0, "Logarithmically encoded power of 2 scale factor", HFILL}},
7632 
7633         { &hf_tcp_option_wscale_multiplier,
7634           { "Multiplier", "tcp.options.wscale.multiplier",  FT_UINT16,
7635             BASE_DEC, NULL, 0x0, "Multiply segment window size by this for scaled window size", HFILL}},
7636 
7637         { &hf_tcp_option_exp_data,
7638           { "Data", "tcp.options.experimental.data", FT_BYTES,
7639             BASE_NONE, NULL, 0x0, NULL, HFILL}},
7640 
7641         { &hf_tcp_option_exp_magic_number,
7642           { "Magic Number", "tcp.options.experimental.magic_number", FT_UINT16,
7643             BASE_HEX, NULL, 0x0, NULL, HFILL}},
7644 
7645         { &hf_tcp_option_unknown_payload,
7646           { "Payload", "tcp.options.unknown.payload", FT_BYTES,
7647             BASE_NONE, NULL, 0x0, NULL, HFILL}},
7648 
7649         { &hf_tcp_option_sack_sle,
7650           {"TCP SACK Left Edge", "tcp.options.sack_le", FT_UINT32,
7651            BASE_DEC, NULL, 0x0, NULL, HFILL}},
7652 
7653         { &hf_tcp_option_sack_sre,
7654           {"TCP SACK Right Edge", "tcp.options.sack_re", FT_UINT32,
7655            BASE_DEC, NULL, 0x0, NULL, HFILL}},
7656 
7657         { &hf_tcp_option_sack_range_count,
7658           { "TCP SACK Count", "tcp.options.sack.count", FT_UINT8,
7659             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7660 
7661         { &hf_tcp_option_sack_dsack_le,
7662           {"TCP D-SACK Left Edge", "tcp.options.sack.dsack_le", FT_UINT32,
7663            BASE_DEC, NULL, 0x0, "Duplicate SACK Left Edge", HFILL}},
7664 
7665         { &hf_tcp_option_sack_dsack_re,
7666           {"TCP D-SACK Right Edge", "tcp.options.sack.dsack_re", FT_UINT32,
7667            BASE_DEC, NULL, 0x0, "Duplicate SACK Right Edge", HFILL}},
7668 
7669         { &hf_tcp_option_echo,
7670           { "TCP Echo Option", "tcp.options.echo_value", FT_UINT32,
7671             BASE_DEC, NULL, 0x0, "TCP Sack Echo", HFILL}},
7672 
7673         { &hf_tcp_option_timestamp_tsval,
7674           { "Timestamp value", "tcp.options.timestamp.tsval", FT_UINT32,
7675             BASE_DEC, NULL, 0x0, "Value of sending machine's timestamp clock", HFILL}},
7676 
7677         { &hf_tcp_option_timestamp_tsecr,
7678           { "Timestamp echo reply", "tcp.options.timestamp.tsecr", FT_UINT32,
7679             BASE_DEC, NULL, 0x0, "Echoed timestamp from remote machine", HFILL}},
7680 
7681         { &hf_tcp_option_mptcp_subtype,
7682           { "Multipath TCP subtype", "tcp.options.mptcp.subtype", FT_UINT8,
7683             BASE_DEC, VALS(mptcp_subtype_vs), 0xF0, NULL, HFILL}},
7684 
7685         { &hf_tcp_option_mptcp_version,
7686           { "Multipath TCP version", "tcp.options.mptcp.version", FT_UINT8,
7687             BASE_DEC, NULL, 0x0F, NULL, HFILL}},
7688 
7689         { &hf_tcp_option_mptcp_reserved,
7690           { "Reserved", "tcp.options.mptcp.reserved", FT_UINT16,
7691             BASE_HEX, NULL, 0x0FFF, NULL, HFILL}},
7692 
7693         { &hf_tcp_option_mptcp_flags,
7694           { "Multipath TCP flags", "tcp.options.mptcp.flags", FT_UINT8,
7695             BASE_HEX, NULL, 0x0, NULL, HFILL}},
7696 
7697         { &hf_tcp_option_mptcp_backup_flag,
7698           { "Backup flag", "tcp.options.mptcp.backup.flag", FT_UINT8,
7699             BASE_DEC, NULL, 0x01, NULL, HFILL}},
7700 
7701         { &hf_tcp_option_mptcp_checksum_flag,
7702           { "Checksum required", "tcp.options.mptcp.checksumreq.flags", FT_UINT8,
7703             BASE_DEC, NULL, MPTCP_CHECKSUM_MASK, NULL, HFILL}},
7704 
7705         { &hf_tcp_option_mptcp_B_flag,
7706           { "Extensibility", "tcp.options.mptcp.extensibility.flag", FT_UINT8,
7707             BASE_DEC, NULL, 0x40, NULL, HFILL}},
7708 
7709         { &hf_tcp_option_mptcp_C_flag,
7710           { "Do not attempt to establish new subflows to this address and port", "tcp.options.mptcp.nomoresubflows.flag", FT_UINT8,
7711             BASE_DEC, NULL, 0x20, NULL, HFILL}},
7712 
7713         { &hf_tcp_option_mptcp_H_v0_flag,
7714           { "Use HMAC-SHA1", "tcp.options.mptcp.sha1.flag", FT_UINT8,
7715             BASE_DEC, NULL, 0x01, NULL, HFILL}},
7716 
7717         { &hf_tcp_option_mptcp_H_v1_flag,
7718           { "Use HMAC-SHA256", "tcp.options.mptcp.sha256.flag", FT_UINT8,
7719             BASE_DEC, NULL, 0x01, NULL, HFILL}},
7720 
7721         { &hf_tcp_option_mptcp_F_flag,
7722           { "DATA_FIN", "tcp.options.mptcp.datafin.flag", FT_UINT8,
7723             BASE_DEC, NULL, MPTCP_DSS_FLAG_DATA_FIN_PRESENT, NULL, HFILL}},
7724 
7725         { &hf_tcp_option_mptcp_m_flag,
7726           { "Data Sequence Number is 8 octets", "tcp.options.mptcp.dseqn8.flag", FT_UINT8,
7727             BASE_DEC, NULL, MPTCP_DSS_FLAG_DSN_8BYTES, NULL, HFILL}},
7728 
7729         { &hf_tcp_option_mptcp_M_flag,
7730           { "Data Sequence Number, Subflow Sequence Number, Data-level Length, Checksum present", "tcp.options.mptcp.dseqnpresent.flag", FT_UINT8,
7731             BASE_DEC, NULL, MPTCP_DSS_FLAG_MAPPING_PRESENT, NULL, HFILL}},
7732 
7733         { &hf_tcp_option_mptcp_a_flag,
7734           { "Data ACK is 8 octets", "tcp.options.mptcp.dataack8.flag", FT_UINT8,
7735             BASE_DEC, NULL, MPTCP_DSS_FLAG_DATA_ACK_8BYTES, NULL, HFILL}},
7736 
7737         { &hf_tcp_option_mptcp_A_flag,
7738           { "Data ACK is present", "tcp.options.mptcp.dataackpresent.flag", FT_UINT8,
7739             BASE_DEC, NULL, MPTCP_DSS_FLAG_DATA_ACK_PRESENT, NULL, HFILL}},
7740 
7741         { &hf_tcp_option_mptcp_reserved_v0_flag,
7742           { "Reserved", "tcp.options.mptcp.reserved.flag", FT_UINT8,
7743             BASE_HEX, NULL, 0x3E, NULL, HFILL}},
7744 
7745         { &hf_tcp_option_mptcp_reserved_v1_flag,
7746           { "Reserved", "tcp.options.mptcp.reserved.flag", FT_UINT8,
7747             BASE_HEX, NULL, 0x1E, NULL, HFILL}},
7748 
7749         { &hf_tcp_option_mptcp_U_flag,
7750           { "Flag U", "tcp.options.mptcp.flag_U.flag", FT_BOOLEAN,
7751             4, TFS(&tfs_set_notset), MPTCP_TCPRST_FLAG_U_PRESENT, NULL, HFILL}},
7752 
7753         { &hf_tcp_option_mptcp_V_flag,
7754           { "Flag V", "tcp.options.mptcp.flag_V.flag", FT_BOOLEAN,
7755             4, TFS(&tfs_set_notset), MPTCP_TCPRST_FLAG_V_PRESENT, NULL, HFILL}},
7756 
7757         { &hf_tcp_option_mptcp_W_flag,
7758           { "Flag W", "tcp.options.mptcp.flag_W.flag", FT_BOOLEAN,
7759             4, TFS(&tfs_set_notset), MPTCP_TCPRST_FLAG_W_PRESENT, NULL, HFILL}},
7760 
7761         { &hf_tcp_option_mptcp_T_flag,
7762           { "Transient", "tcp.options.mptcp.flag_T.flag", FT_BOOLEAN,
7763             4, TFS(&tfs_set_notset), MPTCP_TCPRST_FLAG_T_PRESENT, NULL, HFILL}},
7764 
7765         { &hf_tcp_option_mptcp_tcprst_reason,
7766           { "TCPRST Reason", "tcp.options.mptcp.rst_reason", FT_UINT8,
7767             BASE_HEX, VALS(mp_tcprst_reasons), 0x0, "Multipath TCPRST Reason Code", HFILL}},
7768 
7769         { &hf_tcp_option_mptcp_address_id,
7770           { "Address ID", "tcp.options.mptcp.addrid", FT_UINT8,
7771             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7772 
7773         { &hf_tcp_option_mptcp_sender_key,
7774           { "Sender's Key", "tcp.options.mptcp.sendkey", FT_UINT64,
7775             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7776 
7777         { &hf_tcp_option_mptcp_recv_key,
7778           { "Receiver's Key", "tcp.options.mptcp.recvkey", FT_UINT64,
7779             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7780 
7781         { &hf_tcp_option_mptcp_recv_token,
7782           { "Receiver's Token", "tcp.options.mptcp.recvtok", FT_UINT32,
7783             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7784 
7785         { &hf_tcp_option_mptcp_sender_rand,
7786           { "Sender's Random Number", "tcp.options.mptcp.sendrand", FT_UINT32,
7787             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7788 
7789         { &hf_tcp_option_mptcp_sender_trunc_hmac,
7790           { "Sender's Truncated HMAC", "tcp.options.mptcp.sendtrunchmac", FT_UINT64,
7791             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7792 
7793         { &hf_tcp_option_mptcp_sender_hmac,
7794           { "Sender's HMAC", "tcp.options.mptcp.sendhmac", FT_BYTES,
7795             BASE_NONE, NULL, 0x0, NULL, HFILL}},
7796 
7797         { &hf_tcp_option_mptcp_addaddr_trunc_hmac,
7798           { "Truncated HMAC", "tcp.options.mptcp.addaddrtrunchmac", FT_UINT64,
7799             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7800 
7801         { &hf_tcp_option_mptcp_data_ack_raw,
7802           { "Original MPTCP Data ACK", "tcp.options.mptcp.rawdataack", FT_UINT64,
7803             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7804 
7805         { &hf_tcp_option_mptcp_data_seq_no_raw,
7806           { "Data Sequence Number", "tcp.options.mptcp.rawdataseqno", FT_UINT64,
7807             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7808 
7809         { &hf_tcp_option_mptcp_subflow_seq_no,
7810           { "Subflow Sequence Number", "tcp.options.mptcp.subflowseqno", FT_UINT32,
7811             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7812 
7813         { &hf_tcp_option_mptcp_data_lvl_len,
7814           { "Data-level Length", "tcp.options.mptcp.datalvllen", FT_UINT16,
7815             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7816 
7817         { &hf_tcp_option_mptcp_checksum,
7818           { "Checksum", "tcp.options.mptcp.checksum", FT_UINT16,
7819             BASE_HEX, NULL, 0x0, NULL, HFILL}},
7820 
7821         { &hf_tcp_option_mptcp_ipver,
7822           { "IP version", "tcp.options.mptcp.ipver", FT_UINT8,
7823             BASE_DEC, NULL, 0x0F, NULL, HFILL}},
7824 
7825         { &hf_tcp_option_mptcp_echo,
7826           { "Echo", "tcp.options.mptcp.echo", FT_UINT8,
7827             BASE_DEC, NULL, 0x01, NULL, HFILL}},
7828 
7829         { &hf_tcp_option_mptcp_ipv4,
7830           { "Advertised IPv4 Address", "tcp.options.mptcp.ipv4", FT_IPv4,
7831             BASE_NONE, NULL, 0x0, NULL, HFILL}},
7832 
7833         { &hf_tcp_option_mptcp_ipv6,
7834           { "Advertised IPv6 Address", "tcp.options.mptcp.ipv6", FT_IPv6,
7835             BASE_NONE, NULL, 0x0, NULL, HFILL}},
7836 
7837         { &hf_tcp_option_mptcp_port,
7838           { "Advertised port", "tcp.options.mptcp.port", FT_UINT16,
7839             BASE_DEC, NULL, 0x0, NULL, HFILL}},
7840 
7841         { &hf_tcp_option_cc,
7842           { "TCP CC Option", "tcp.options.cc_value", FT_UINT32, BASE_DEC,
7843             NULL, 0x0, NULL, HFILL}},
7844 
7845         { &hf_tcp_option_md5_digest,
7846           { "MD5 digest", "tcp.options.md5.digest", FT_BYTES, BASE_NONE,
7847             NULL, 0x0, NULL, HFILL}},
7848 
7849         { &hf_tcp_option_ao_keyid,
7850           { "AO KeyID", "tcp.options.ao.keyid", FT_UINT8, BASE_DEC,
7851             NULL, 0x0, NULL, HFILL}},
7852 
7853         { &hf_tcp_option_ao_rnextkeyid,
7854           { "AO RNextKeyID", "tcp.options.ao.rnextkeyid", FT_UINT8, BASE_DEC,
7855             NULL, 0x0, NULL, HFILL}},
7856 
7857         { &hf_tcp_option_ao_mac,
7858           { "AO MAC", "tcp.options.ao.mac", FT_BYTES, BASE_NONE,
7859             NULL, 0x0, NULL, HFILL}},
7860 
7861         { &hf_tcp_option_qs_rate,
7862           { "QS Rate", "tcp.options.qs.rate", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
7863             &qs_rate_vals_ext, 0x0F, NULL, HFILL}},
7864 
7865         { &hf_tcp_option_qs_ttl_diff,
7866           { "QS Rate", "tcp.options.qs.ttl_diff", FT_UINT8, BASE_DEC,
7867             NULL, 0x0, NULL, HFILL}},
7868 
7869         { &hf_tcp_option_scps_vector,
7870           { "TCP SCPS Capabilities Vector", "tcp.options.scps.vector",
7871             FT_UINT8, BASE_HEX, NULL, 0x0,
7872             NULL, HFILL}},
7873 
7874         { &hf_tcp_option_scps_binding,
7875           { "Binding Space (Community) ID",
7876             "tcp.options.scps.binding.id",
7877             FT_UINT8, BASE_DEC, NULL, 0x0,
7878             "TCP SCPS Extended Binding Space (Community) ID", HFILL}},
7879 
7880         { &hf_tcp_option_scps_binding_len,
7881           { "Extended Capability Length",
7882             "tcp.options.scps.binding.len",
7883             FT_UINT8, BASE_DEC, NULL, 0x0,
7884             "TCP SCPS Extended Capability Length in bytes", HFILL}},
7885 
7886         { &hf_tcp_option_snack_offset,
7887           { "TCP SNACK Offset", "tcp.options.snack.offset",
7888             FT_UINT16, BASE_DEC, NULL, 0x0,
7889             NULL, HFILL}},
7890 
7891         { &hf_tcp_option_snack_size,
7892           { "TCP SNACK Size", "tcp.options.snack.size",
7893             FT_UINT16, BASE_DEC, NULL, 0x0,
7894             NULL, HFILL}},
7895 
7896         { &hf_tcp_option_snack_le,
7897           { "TCP SNACK Left Edge", "tcp.options.snack.le",
7898             FT_UINT16, BASE_DEC, NULL, 0x0,
7899             NULL, HFILL}},
7900 
7901         { &hf_tcp_option_snack_re,
7902           { "TCP SNACK Right Edge", "tcp.options.snack.re",
7903             FT_UINT16, BASE_DEC, NULL, 0x0,
7904             NULL, HFILL}},
7905 
7906         { &hf_tcp_scpsoption_flags_bets,
7907           { "Partial Reliability Capable (BETS)",
7908             "tcp.options.scpsflags.bets", FT_BOOLEAN, 8,
7909             TFS(&tfs_set_notset), 0x80, NULL, HFILL }},
7910 
7911         { &hf_tcp_scpsoption_flags_snack1,
7912           { "Short Form SNACK Capable (SNACK1)",
7913             "tcp.options.scpsflags.snack1", FT_BOOLEAN, 8,
7914             TFS(&tfs_set_notset), 0x40, NULL, HFILL }},
7915 
7916         { &hf_tcp_scpsoption_flags_snack2,
7917           { "Long Form SNACK Capable (SNACK2)",
7918             "tcp.options.scpsflags.snack2", FT_BOOLEAN, 8,
7919             TFS(&tfs_set_notset), 0x20, NULL, HFILL }},
7920 
7921         { &hf_tcp_scpsoption_flags_compress,
7922           { "Lossless Header Compression (COMP)",
7923             "tcp.options.scpsflags.compress", FT_BOOLEAN, 8,
7924             TFS(&tfs_set_notset), 0x10, NULL, HFILL }},
7925 
7926         { &hf_tcp_scpsoption_flags_nlts,
7927           { "Network Layer Timestamp (NLTS)",
7928             "tcp.options.scpsflags.nlts", FT_BOOLEAN, 8,
7929             TFS(&tfs_set_notset), 0x8, NULL, HFILL }},
7930 
7931         { &hf_tcp_scpsoption_flags_reserved,
7932           { "Reserved",
7933             "tcp.options.scpsflags.reserved", FT_UINT8, BASE_DEC,
7934             NULL, 0x7, NULL, HFILL }},
7935 
7936         { &hf_tcp_scpsoption_connection_id,
7937           { "Connection ID",
7938             "tcp.options.scps.binding",
7939             FT_UINT8, BASE_DEC, NULL, 0x0,
7940             "TCP SCPS Connection ID", HFILL}},
7941 
7942         { &hf_tcp_option_user_to_granularity,
7943           { "Granularity", "tcp.options.user_to_granularity", FT_BOOLEAN,
7944             16, TFS(&tcp_option_user_to_granularity), 0x8000, "TCP User Timeout Granularity", HFILL}},
7945 
7946         { &hf_tcp_option_user_to_val,
7947           { "User Timeout", "tcp.options.user_to_val", FT_UINT16,
7948             BASE_DEC, NULL, 0x7FFF, "TCP User Timeout Value", HFILL}},
7949 
7950         { &hf_tcp_option_rvbd_probe_type1,
7951           { "Type", "tcp.options.rvbd.probe.type1",
7952             FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
7953 
7954         { &hf_tcp_option_rvbd_probe_type2,
7955           { "Type", "tcp.options.rvbd.probe.type2",
7956             FT_UINT8, BASE_DEC, NULL, 0xFE, NULL, HFILL }},
7957 
7958         { &hf_tcp_option_rvbd_probe_version1,
7959           { "Version", "tcp.options.rvbd.probe.version",
7960             FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }},
7961 
7962         { &hf_tcp_option_rvbd_probe_version2,
7963           { "Version", "tcp.options.rvbd.probe.version_raw",
7964             FT_UINT8, BASE_DEC, NULL, 0x01, "Version 2 Raw Value", HFILL }},
7965 
7966         { &hf_tcp_option_rvbd_probe_prober,
7967           { "CSH IP", "tcp.options.rvbd.probe.prober",
7968             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7969 
7970         { &hf_tcp_option_rvbd_probe_proxy,
7971           { "SSH IP", "tcp.options.rvbd.probe.proxy.ip",
7972             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7973 
7974         { &hf_tcp_option_rvbd_probe_proxy_port,
7975           { "SSH Port", "tcp.options.rvbd.probe.proxy.port",
7976             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7977 
7978         { &hf_tcp_option_rvbd_probe_appli_ver,
7979           { "Application Version", "tcp.options.rvbd.probe.appli_ver",
7980             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7981 
7982         { &hf_tcp_option_rvbd_probe_client,
7983           { "Client IP", "tcp.options.rvbd.probe.client.ip",
7984             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7985 
7986         { &hf_tcp_option_rvbd_probe_storeid,
7987           { "CFE Store ID", "tcp.options.rvbd.probe.storeid",
7988             FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7989 
7990         { &hf_tcp_option_rvbd_probe_flags,
7991           { "Probe Flags", "tcp.options.rvbd.probe.flags",
7992             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
7993 
7994         { &hf_tcp_option_rvbd_probe_flag_not_cfe,
7995           { "Not CFE", "tcp.options.rvbd.probe.flags.notcfe",
7996             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_NCFE,
7997             NULL, HFILL }},
7998 
7999         { &hf_tcp_option_rvbd_probe_flag_last_notify,
8000           { "Last Notify", "tcp.options.rvbd.probe.flags.last",
8001             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_LAST,
8002             NULL, HFILL }},
8003 
8004         { &hf_tcp_option_rvbd_probe_flag_probe_cache,
8005           { "Disable Probe Cache on CSH", "tcp.options.rvbd.probe.flags.probe",
8006             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE,
8007             NULL, HFILL }},
8008 
8009         { &hf_tcp_option_rvbd_probe_flag_sslcert,
8010           { "SSL Enabled", "tcp.options.rvbd.probe.flags.ssl",
8011             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_SSLCERT,
8012             NULL, HFILL }},
8013 
8014         { &hf_tcp_option_rvbd_probe_flag_server_connected,
8015           { "SSH outer to server established", "tcp.options.rvbd.probe.flags.server",
8016             FT_BOOLEAN, 8, TFS(&tfs_set_notset), RVBD_FLAGS_PROBE_SERVER,
8017             NULL, HFILL }},
8018 
8019         { &hf_tcp_option_rvbd_trpy_flags,
8020           { "Transparency Options", "tcp.options.rvbd.trpy.flags",
8021             FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
8022 
8023         { &hf_tcp_option_rvbd_trpy_flag_fw_rst_probe,
8024           { "Enable FW traversal feature", "tcp.options.rvbd.trpy.flags.fw_rst_probe",
8025             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
8026             RVBD_FLAGS_TRPY_FW_RST_PROBE,
8027             "Reset state created by probe on the nexthop firewall",
8028             HFILL }},
8029 
8030         { &hf_tcp_option_rvbd_trpy_flag_fw_rst_inner,
8031           { "Enable Inner FW feature on All FWs", "tcp.options.rvbd.trpy.flags.fw_rst_inner",
8032             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
8033             RVBD_FLAGS_TRPY_FW_RST_INNER,
8034             "Reset state created by transparent inner on all firewalls"
8035             " before passing connection through",
8036             HFILL }},
8037 
8038         { &hf_tcp_option_rvbd_trpy_flag_fw_rst,
8039           { "Enable Transparency FW feature on All FWs", "tcp.options.rvbd.trpy.flags.fw_rst",
8040             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
8041             RVBD_FLAGS_TRPY_FW_RST,
8042             "Reset state created by probe on all firewalls before "
8043             "establishing transparent inner connection", HFILL }},
8044 
8045         { &hf_tcp_option_rvbd_trpy_flag_chksum,
8046           { "Reserved", "tcp.options.rvbd.trpy.flags.chksum",
8047             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
8048             RVBD_FLAGS_TRPY_CHKSUM, NULL, HFILL }},
8049 
8050         { &hf_tcp_option_rvbd_trpy_flag_oob,
8051           { "Out of band connection", "tcp.options.rvbd.trpy.flags.oob",
8052             FT_BOOLEAN, 16, TFS(&tfs_set_notset),
8053             RVBD_FLAGS_TRPY_OOB, NULL, HFILL }},
8054 
8055         { &hf_tcp_option_rvbd_trpy_flag_mode,
8056           { "Transparency Mode", "tcp.options.rvbd.trpy.flags.mode",
8057             FT_BOOLEAN, 16, TFS(&trpy_mode_str),
8058             RVBD_FLAGS_TRPY_MODE, NULL, HFILL }},
8059 
8060         { &hf_tcp_option_rvbd_trpy_src,
8061           { "Src SH IP Addr", "tcp.options.rvbd.trpy.src.ip",
8062             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
8063 
8064         { &hf_tcp_option_rvbd_trpy_dst,
8065           { "Dst SH IP Addr", "tcp.options.rvbd.trpy.dst.ip",
8066             FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
8067 
8068         { &hf_tcp_option_rvbd_trpy_src_port,
8069           { "Src SH Inner Port", "tcp.options.rvbd.trpy.src.port",
8070             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
8071 
8072         { &hf_tcp_option_rvbd_trpy_dst_port,
8073           { "Dst SH Inner Port", "tcp.options.rvbd.trpy.dst.port",
8074             FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
8075 
8076         { &hf_tcp_option_rvbd_trpy_client_port,
8077           { "Out of band connection Client Port", "tcp.options.rvbd.trpy.client.port",
8078             FT_UINT16, BASE_DEC, NULL , 0x0, NULL, HFILL }},
8079 
8080         { &hf_tcp_option_fast_open_cookie_request,
8081           { "Fast Open Cookie Request", "tcp.options.tfo.request", FT_NONE,
8082             BASE_NONE, NULL, 0x0, NULL, HFILL }},
8083 
8084         { &hf_tcp_option_fast_open_cookie,
8085           { "Fast Open Cookie", "tcp.options.tfo.cookie", FT_BYTES,
8086             BASE_NONE, NULL, 0x0, NULL, HFILL}},
8087 
8088         { &hf_tcp_pdu_time,
8089           { "Time until the last segment of this PDU", "tcp.pdu.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
8090             "How long time has passed until the last frame of this PDU", HFILL}},
8091 
8092         { &hf_tcp_pdu_size,
8093           { "PDU Size", "tcp.pdu.size", FT_UINT32, BASE_DEC, NULL, 0x0,
8094             "The size of this PDU", HFILL}},
8095 
8096         { &hf_tcp_pdu_last_frame,
8097           { "Last frame of this PDU", "tcp.pdu.last_frame", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
8098             "This is the last frame of the PDU starting in this segment", HFILL }},
8099 
8100         { &hf_tcp_ts_relative,
8101           { "Time since first frame in this TCP stream", "tcp.time_relative", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
8102             "Time relative to first frame in this TCP stream", HFILL}},
8103 
8104         { &hf_tcp_ts_delta,
8105           { "Time since previous frame in this TCP stream", "tcp.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
8106             "Time delta from previous frame in this TCP stream", HFILL}},
8107 
8108         { &hf_tcp_proc_src_uid,
8109           { "Source process user ID", "tcp.proc.srcuid", FT_UINT32, BASE_DEC, NULL, 0x0,
8110             NULL, HFILL}},
8111 
8112         { &hf_tcp_proc_src_pid,
8113           { "Source process ID", "tcp.proc.srcpid", FT_UINT32, BASE_DEC, NULL, 0x0,
8114             NULL, HFILL}},
8115 
8116         { &hf_tcp_proc_src_uname,
8117           { "Source process user name", "tcp.proc.srcuname", FT_STRING, BASE_NONE, NULL, 0x0,
8118             NULL, HFILL}},
8119 
8120         { &hf_tcp_proc_src_cmd,
8121           { "Source process name", "tcp.proc.srccmd", FT_STRING, BASE_NONE, NULL, 0x0,
8122             "Source process command name", HFILL}},
8123 
8124         { &hf_tcp_proc_dst_uid,
8125           { "Destination process user ID", "tcp.proc.dstuid", FT_UINT32, BASE_DEC, NULL, 0x0,
8126             NULL, HFILL}},
8127 
8128         { &hf_tcp_proc_dst_pid,
8129           { "Destination process ID", "tcp.proc.dstpid", FT_UINT32, BASE_DEC, NULL, 0x0,
8130             NULL, HFILL}},
8131 
8132         { &hf_tcp_proc_dst_uname,
8133           { "Destination process user name", "tcp.proc.dstuname", FT_STRING, BASE_NONE, NULL, 0x0,
8134             NULL, HFILL}},
8135 
8136         { &hf_tcp_proc_dst_cmd,
8137           { "Destination process name", "tcp.proc.dstcmd", FT_STRING, BASE_NONE, NULL, 0x0,
8138             "Destination process command name", HFILL}},
8139 
8140         { &hf_tcp_segment_data,
8141           { "TCP segment data", "tcp.segment_data", FT_BYTES, BASE_NONE, NULL, 0x0,
8142             "A data segment used in reassembly of a lower-level protocol", HFILL}},
8143 
8144         { &hf_tcp_payload,
8145           { "TCP payload", "tcp.payload", FT_BYTES, BASE_NONE, NULL, 0x0,
8146             "The TCP payload of this packet", HFILL}},
8147 
8148         { &hf_tcp_option_scps_binding_data,
8149           { "Binding Space Data", "tcp.options.scps.binding.data", FT_BYTES, BASE_NONE, NULL, 0x0,
8150             NULL, HFILL }},
8151 
8152         { &hf_tcp_option_rvbd_probe_reserved,
8153           { "Reserved", "tcp.options.rvbd.probe.reserved", FT_UINT8, BASE_HEX, NULL, 0x0,
8154             NULL, HFILL }},
8155 
8156         { &hf_tcp_fin_retransmission,
8157           { "Retransmission of FIN from frame", "tcp.fin_retransmission", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
8158             NULL, HFILL }},
8159 
8160         { &hf_tcp_reset_cause,
8161           { "Reset cause", "tcp.reset_cause", FT_STRING, BASE_NONE, NULL, 0x0,
8162             NULL, HFILL }},
8163     };
8164 
8165     static gint *ett[] = {
8166         &ett_tcp,
8167         &ett_tcp_flags,
8168         &ett_tcp_options,
8169         &ett_tcp_option_timestamp,
8170         &ett_tcp_option_mptcp,
8171         &ett_tcp_option_wscale,
8172         &ett_tcp_option_sack,
8173         &ett_tcp_option_snack,
8174         &ett_tcp_option_scps,
8175         &ett_tcp_scpsoption_flags,
8176         &ett_tcp_option_scps_extended,
8177         &ett_tcp_option_user_to,
8178         &ett_tcp_option_exp,
8179         &ett_tcp_option_sack_perm,
8180         &ett_tcp_option_mss,
8181         &ett_tcp_opt_rvbd_probe,
8182         &ett_tcp_opt_rvbd_probe_flags,
8183         &ett_tcp_opt_rvbd_trpy,
8184         &ett_tcp_opt_rvbd_trpy_flags,
8185         &ett_tcp_opt_echo,
8186         &ett_tcp_opt_cc,
8187         &ett_tcp_opt_md5,
8188         &ett_tcp_opt_ao,
8189         &ett_tcp_opt_qs,
8190         &ett_tcp_analysis_faults,
8191         &ett_tcp_analysis,
8192         &ett_tcp_timestamps,
8193         &ett_tcp_segments,
8194         &ett_tcp_segment,
8195         &ett_tcp_checksum,
8196         &ett_tcp_process_info,
8197         &ett_tcp_unknown_opt,
8198         &ett_tcp_opt_recbound,
8199         &ett_tcp_opt_scpscor,
8200         &ett_tcp_option_other
8201     };
8202 
8203     static gint *mptcp_ett[] = {
8204         &ett_mptcp_analysis,
8205         &ett_mptcp_analysis_subflows
8206     };
8207 
8208     static const enum_val_t window_scaling_vals[] = {
8209         {"not-known",  "Not known",                  WindowScaling_NotKnown},
8210         {"0",          "0 (no scaling)",             WindowScaling_0},
8211         {"1",          "1 (multiply by 2)",          WindowScaling_1},
8212         {"2",          "2 (multiply by 4)",          WindowScaling_2},
8213         {"3",          "3 (multiply by 8)",          WindowScaling_3},
8214         {"4",          "4 (multiply by 16)",         WindowScaling_4},
8215         {"5",          "5 (multiply by 32)",         WindowScaling_5},
8216         {"6",          "6 (multiply by 64)",         WindowScaling_6},
8217         {"7",          "7 (multiply by 128)",        WindowScaling_7},
8218         {"8",          "8 (multiply by 256)",        WindowScaling_8},
8219         {"9",          "9 (multiply by 512)",        WindowScaling_9},
8220         {"10",         "10 (multiply by 1024)",      WindowScaling_10},
8221         {"11",         "11 (multiply by 2048)",      WindowScaling_11},
8222         {"12",         "12 (multiply by 4096)",      WindowScaling_12},
8223         {"13",         "13 (multiply by 8192)",      WindowScaling_13},
8224         {"14",         "14 (multiply by 16384)",     WindowScaling_14},
8225         {NULL, NULL, -1}
8226     };
8227 
8228     static ei_register_info ei[] = {
8229         { &ei_tcp_opt_len_invalid, { "tcp.option.len.invalid", PI_SEQUENCE, PI_NOTE, "Invalid length for option", EXPFILL }},
8230         { &ei_tcp_analysis_retransmission, { "tcp.analysis.retransmission", PI_SEQUENCE, PI_NOTE, "This frame is a (suspected) retransmission", EXPFILL }},
8231         { &ei_tcp_analysis_fast_retransmission, { "tcp.analysis.fast_retransmission", PI_SEQUENCE, PI_NOTE, "This frame is a (suspected) fast retransmission", EXPFILL }},
8232         { &ei_tcp_analysis_spurious_retransmission, { "tcp.analysis.spurious_retransmission", PI_SEQUENCE, PI_NOTE, "This frame is a (suspected) spurious retransmission", EXPFILL }},
8233         { &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 }},
8234         { &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 }},
8235         { &ei_tcp_analysis_lost_packet, { "tcp.analysis.lost_segment", PI_SEQUENCE, PI_WARN, "Previous segment(s) not captured (common at capture start)", EXPFILL }},
8236         { &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 }},
8237         { &ei_tcp_analysis_window_update, { "tcp.analysis.window_update", PI_SEQUENCE, PI_CHAT, "TCP window update", EXPFILL }},
8238         { &ei_tcp_analysis_window_full, { "tcp.analysis.window_full", PI_SEQUENCE, PI_WARN, "TCP window specified by the receiver is now completely full", EXPFILL }},
8239         { &ei_tcp_analysis_keep_alive, { "tcp.analysis.keep_alive", PI_SEQUENCE, PI_NOTE, "TCP keep-alive segment", EXPFILL }},
8240         { &ei_tcp_analysis_keep_alive_ack, { "tcp.analysis.keep_alive_ack", PI_SEQUENCE, PI_NOTE, "ACK to a TCP keep-alive segment", EXPFILL }},
8241         { &ei_tcp_analysis_duplicate_ack, { "tcp.analysis.duplicate_ack", PI_SEQUENCE, PI_NOTE, "Duplicate ACK", EXPFILL }},
8242         { &ei_tcp_analysis_zero_window_probe, { "tcp.analysis.zero_window_probe", PI_SEQUENCE, PI_NOTE, "TCP Zero Window Probe", EXPFILL }},
8243         { &ei_tcp_analysis_zero_window, { "tcp.analysis.zero_window", PI_SEQUENCE, PI_WARN, "TCP Zero Window segment", EXPFILL }},
8244         { &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 }},
8245         { &ei_tcp_analysis_tfo_syn, { "tcp.analysis.tfo_syn", PI_SEQUENCE, PI_NOTE, "TCP SYN with TFO Cookie", EXPFILL }},
8246         { &ei_tcp_analysis_tfo_ack, { "tcp.analysis.tfo_ack", PI_SEQUENCE, PI_NOTE, "TCP SYN-ACK accepting TFO data", EXPFILL }},
8247         { &ei_tcp_analysis_tfo_ignored, { "tcp.analysis.tfo_ignored", PI_SEQUENCE, PI_NOTE, "TCP SYN-ACK ignoring TFO data", EXPFILL }},
8248         { &ei_tcp_connection_fin_active, { "tcp.connection.fin_active", PI_SEQUENCE, PI_NOTE, "This frame initiates the connection closing", EXPFILL }},
8249         { &ei_tcp_connection_fin_passive, { "tcp.connection.fin_passive", PI_SEQUENCE, PI_NOTE, "This frame undergoes the connection closing", EXPFILL }},
8250         { &ei_tcp_scps_capable, { "tcp.analysis.zero_window_probe_ack", PI_SEQUENCE, PI_NOTE, "Connection establish request (SYN-ACK): SCPS Capabilities Negotiated", EXPFILL }},
8251         { &ei_tcp_option_sack_dsack, { "tcp.options.sack.dsack", PI_SEQUENCE, PI_WARN, "D-SACK Sequence", EXPFILL }},
8252         { &ei_tcp_option_snack_sequence, { "tcp.options.snack.sequence", PI_SEQUENCE, PI_NOTE, "SNACK Sequence", EXPFILL }},
8253         { &ei_tcp_option_wscale_shift_invalid, { "tcp.options.wscale.shift.invalid", PI_PROTOCOL, PI_WARN, "Window scale shift exceeds 14", EXPFILL }},
8254         { &ei_tcp_option_mss_absent, { "tcp.options.mss.absent", PI_PROTOCOL, PI_NOTE, "The SYN packet does not contain a MSS option", EXPFILL }},
8255         { &ei_tcp_option_mss_present, { "tcp.options.mss.present", PI_PROTOCOL, PI_WARN, "The non-SYN packet does contain a MSS option", EXPFILL }},
8256         { &ei_tcp_short_segment, { "tcp.short_segment", PI_MALFORMED, PI_WARN, "Short segment", EXPFILL }},
8257         { &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 }},
8258         { &ei_tcp_connection_synack, { "tcp.connection.synack", PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK)", EXPFILL }},
8259         { &ei_tcp_connection_syn, { "tcp.connection.syn", PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN)", EXPFILL }},
8260         { &ei_tcp_connection_fin, { "tcp.connection.fin", PI_SEQUENCE, PI_CHAT, "Connection finish (FIN)", EXPFILL }},
8261         /* According to RFCs, RST is an indication of an error. Some applications use it
8262          * to terminate a connection as well, which is a misbehavior (see e.g. rfc3360)
8263          */
8264         { &ei_tcp_connection_rst, { "tcp.connection.rst", PI_SEQUENCE, PI_WARN, "Connection reset (RST)", EXPFILL }},
8265         { &ei_tcp_checksum_ffff, { "tcp.checksum.ffff", PI_CHECKSUM, PI_WARN, "TCP Checksum 0xffff instead of 0x0000 (see RFC 1624)", EXPFILL }},
8266         { &ei_tcp_checksum_bad, { "tcp.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
8267         { &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 }},
8268         { &ei_tcp_suboption_malformed, { "tcp.suboption_malformed", PI_MALFORMED, PI_ERROR, "suboption would go past end of option", EXPFILL }},
8269         { &ei_tcp_nop, { "tcp.nop", PI_PROTOCOL, PI_WARN, "4 NOP in a row - a router may have removed some options", EXPFILL }},
8270         { &ei_tcp_bogus_header_length, { "tcp.bogus_header_length", PI_PROTOCOL, PI_ERROR, "Bogus TCP Header length", EXPFILL }},
8271     };
8272 
8273     static ei_register_info mptcp_ei[] = {
8274 #if 0
8275         { &ei_mptcp_analysis_unexpected_idsn, { "mptcp.connection.unexpected_idsn", PI_PROTOCOL, PI_NOTE, "Unexpected initial sequence number", EXPFILL }},
8276 #endif
8277         { &ei_mptcp_analysis_echoed_key_mismatch, { "mptcp.connection.echoed_key_mismatch", PI_PROTOCOL, PI_WARN, "The echoed key in the ACK of the MPTCP handshake does not match the key of the SYN/ACK", EXPFILL }},
8278         { &ei_mptcp_analysis_missing_algorithm, { "mptcp.connection.missing_algorithm", PI_PROTOCOL, PI_WARN, "No crypto algorithm specified", EXPFILL }},
8279         { &ei_mptcp_analysis_unsupported_algorithm, { "mptcp.connection.unsupported_algorithm", PI_PROTOCOL, PI_WARN, "Unsupported algorithm", EXPFILL }},
8280         { &ei_mptcp_infinite_mapping, { "mptcp.dss.infinite_mapping", PI_PROTOCOL, PI_WARN, "Fallback to infinite mapping", EXPFILL }},
8281         { &ei_mptcp_mapping_missing, { "mptcp.dss.missing_mapping", PI_PROTOCOL, PI_WARN, "No mapping available", EXPFILL }},
8282 #if 0
8283         { &ei_mptcp_stream_incomplete, { "mptcp.incomplete", PI_PROTOCOL, PI_WARN, "Everything was not captured", EXPFILL }},
8284         { &ei_mptcp_analysis_dsn_out_of_order, { "mptcp.analysis.dsn.out_of_order", PI_PROTOCOL, PI_WARN, "Out of order dsn", EXPFILL }},
8285 #endif
8286     };
8287 
8288     static hf_register_info mptcp_hf[] = {
8289         { &hf_mptcp_ack,
8290           { "Multipath TCP Data ACK", "mptcp.ack", FT_UINT64,
8291             BASE_DEC, NULL, 0x0, NULL, HFILL}},
8292 
8293         { &hf_mptcp_dsn,
8294           { "Data Sequence Number", "mptcp.dsn", FT_UINT64, BASE_DEC, NULL, 0x0,
8295             "Data Sequence Number mapped to this TCP sequence number", HFILL}},
8296 
8297         { &hf_mptcp_rawdsn64,
8298           { "Raw Data Sequence Number", "mptcp.rawdsn64", FT_UINT64, BASE_DEC, NULL, 0x0,
8299             "Data Sequence Number mapped to this TCP sequence number", HFILL}},
8300 
8301         { &hf_mptcp_dss_dsn,
8302           { "DSS Data Sequence Number", "mptcp.dss.dsn", FT_UINT64,
8303             BASE_DEC, NULL, 0x0, NULL, HFILL}},
8304 
8305         { &hf_mptcp_expected_idsn,
8306           { "Subflow expected IDSN", "mptcp.expected_idsn", FT_UINT64,
8307             BASE_DEC|BASE_UNIT_STRING, &units_64bit_version, 0x0, NULL, HFILL}},
8308 
8309         { &hf_mptcp_analysis,
8310           { "MPTCP analysis",   "mptcp.analysis", FT_NONE, BASE_NONE, NULL, 0x0,
8311             "This frame has some of the MPTCP analysis shown", HFILL }},
8312 
8313         { &hf_mptcp_related_mapping,
8314           { "Related mapping", "mptcp.related_mapping", FT_FRAMENUM , BASE_NONE, NULL, 0x0,
8315             "Packet in which current packet DSS mapping was sent", HFILL }},
8316 
8317         { &hf_mptcp_reinjection_of,
8318           { "Reinjection of", "mptcp.reinjection_of", FT_FRAMENUM , BASE_NONE, NULL, 0x0,
8319             "This is a retransmission of data sent on another subflow", HFILL }},
8320 
8321         { &hf_mptcp_reinjected_in,
8322           { "Data reinjected in", "mptcp.reinjected_in", FT_FRAMENUM , BASE_NONE, NULL, 0x0,
8323             "This was retransmitted on another subflow", HFILL }},
8324 
8325         { &hf_mptcp_analysis_subflows,
8326           { "TCP subflow stream id(s)", "mptcp.analysis.subflows", FT_STRING, BASE_NONE, NULL, 0x0,
8327             "List all TCP connections mapped to this MPTCP connection", HFILL }},
8328 
8329         { &hf_mptcp_stream,
8330           { "Stream index", "mptcp.stream", FT_UINT32, BASE_DEC, NULL, 0x0,
8331             NULL, HFILL }},
8332 
8333         { &hf_mptcp_number_of_removed_addresses,
8334           { "Number of removed addresses", "mptcp.rm_addr.count", FT_UINT8,
8335             BASE_DEC, NULL, 0x0, NULL, HFILL}},
8336 
8337         { &hf_mptcp_expected_token,
8338           { "Subflow token generated from key", "mptcp.expected_token", FT_UINT32,
8339             BASE_DEC, NULL, 0x0, NULL, HFILL}},
8340 
8341         { &hf_mptcp_analysis_master,
8342           { "Master flow", "mptcp.master", FT_BOOLEAN, BASE_NONE,
8343             NULL, 0x0, NULL, HFILL}}
8344 
8345     };
8346 
8347     static build_valid_func tcp_da_src_values[1] = {tcp_src_value};
8348     static build_valid_func tcp_da_dst_values[1] = {tcp_dst_value};
8349     static build_valid_func tcp_da_both_values[2] = {tcp_src_value, tcp_dst_value};
8350     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}};
8351     static decode_as_t tcp_da = {"tcp", "tcp.port", 3, 2, tcp_da_values, "TCP", "port(s) as",
8352                                  decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
8353 
8354     module_t *tcp_module;
8355     module_t *mptcp_module;
8356     expert_module_t* expert_tcp;
8357     expert_module_t* expert_mptcp;
8358 
8359     proto_tcp = proto_register_protocol("Transmission Control Protocol", "TCP", "tcp");
8360     tcp_handle = register_dissector("tcp", dissect_tcp, proto_tcp);
8361     proto_register_field_array(proto_tcp, hf, array_length(hf));
8362     proto_register_subtree_array(ett, array_length(ett));
8363     expert_tcp = expert_register_protocol(proto_tcp);
8364     expert_register_field_array(expert_tcp, ei, array_length(ei));
8365 
8366     /* subdissector code */
8367     subdissector_table = register_dissector_table("tcp.port",
8368         "TCP port", proto_tcp, FT_UINT16, BASE_DEC);
8369     heur_subdissector_list = register_heur_dissector_list("tcp", proto_tcp);
8370     tcp_option_table = register_dissector_table("tcp.option",
8371         "TCP Options", proto_tcp, FT_UINT8, BASE_DEC);
8372 
8373     /* Register TCP options as their own protocols so we can get the name of the option */
8374     proto_tcp_option_nop = proto_register_protocol_in_name_only("TCP Option - No-Operation (NOP)", "No-Operation (NOP)", "tcp.options.nop", proto_tcp, FT_BYTES);
8375     proto_tcp_option_eol = proto_register_protocol_in_name_only("TCP Option - End of Option List (EOL)", "End of Option List (EOL)", "tcp.options.eol", proto_tcp, FT_BYTES);
8376     proto_tcp_option_timestamp = proto_register_protocol_in_name_only("TCP Option - Timestamps", "Timestamps", "tcp.options.timestamp", proto_tcp, FT_BYTES);
8377     proto_tcp_option_mss = proto_register_protocol_in_name_only("TCP Option - Maximum segment size", "Maximum segment size", "tcp.options.mss", proto_tcp, FT_BYTES);
8378     proto_tcp_option_wscale = proto_register_protocol_in_name_only("TCP Option - Window scale", "Window scale", "tcp.options.wscale", proto_tcp, FT_BYTES);
8379     proto_tcp_option_sack_perm = proto_register_protocol_in_name_only("TCP Option - SACK permitted", "SACK permitted", "tcp.options.sack_perm", proto_tcp, FT_BYTES);
8380     proto_tcp_option_sack = proto_register_protocol_in_name_only("TCP Option - SACK", "SACK", "tcp.options.sack", proto_tcp, FT_BYTES);
8381     proto_tcp_option_echo = proto_register_protocol_in_name_only("TCP Option - Echo", "Echo", "tcp.options.echo", proto_tcp, FT_BYTES);
8382     proto_tcp_option_echoreply = proto_register_protocol_in_name_only("TCP Option - Echo reply", "Echo reply", "tcp.options.echoreply", proto_tcp, FT_BYTES);
8383     proto_tcp_option_cc = proto_register_protocol_in_name_only("TCP Option - CC", "CC", "tcp.options.cc", proto_tcp, FT_BYTES);
8384     proto_tcp_option_cc_new = proto_register_protocol_in_name_only("TCP Option - CC.NEW", "CC.NEW", "tcp.options.ccnew", proto_tcp, FT_BYTES);
8385     proto_tcp_option_cc_echo = proto_register_protocol_in_name_only("TCP Option - CC.ECHO", "CC.ECHO", "tcp.options.ccecho", proto_tcp, FT_BYTES);
8386     proto_tcp_option_ao = proto_register_protocol_in_name_only("TCP Option - TCP AO", "TCP AO", "tcp.options.ao", proto_tcp, FT_BYTES);
8387     proto_tcp_option_md5 = proto_register_protocol_in_name_only("TCP Option - TCP MD5 signature", "TCP MD5 signature", "tcp.options.md5", proto_tcp, FT_BYTES);
8388     proto_tcp_option_scps = proto_register_protocol_in_name_only("TCP Option - SCPS capabilities", "SCPS capabilities", "tcp.options.scps", proto_tcp, FT_BYTES);
8389     proto_tcp_option_snack = proto_register_protocol_in_name_only("TCP Option - Selective Negative Acknowledgment", "Selective Negative Acknowledgment", "tcp.options.snack", proto_tcp, FT_BYTES);
8390     proto_tcp_option_scpsrec = proto_register_protocol_in_name_only("TCP Option - SCPS record boundary", "SCPS record boundary", "tcp.options.scpsrec", proto_tcp, FT_BYTES);
8391     proto_tcp_option_scpscor = proto_register_protocol_in_name_only("TCP Option - SCPS corruption experienced", "SCPS corruption experienced", "tcp.options.scpscor", proto_tcp, FT_BYTES);
8392     proto_tcp_option_qs = proto_register_protocol_in_name_only("TCP Option - Quick-Start", "Quick-Start", "tcp.options.qs", proto_tcp, FT_BYTES);
8393     proto_tcp_option_user_to = proto_register_protocol_in_name_only("TCP Option - User Timeout", "User Timeout", "tcp.options.user_to", proto_tcp, FT_BYTES);
8394     proto_tcp_option_tfo = proto_register_protocol_in_name_only("TCP Option - TCP Fast Open", "TCP Fast Open", "tcp.options.tfo", proto_tcp, FT_BYTES);
8395     proto_tcp_option_rvbd_probe = proto_register_protocol_in_name_only("TCP Option - Riverbed Probe", "Riverbed Probe", "tcp.options.rvbd.probe", proto_tcp, FT_BYTES);
8396     proto_tcp_option_rvbd_trpy = proto_register_protocol_in_name_only("TCP Option - Riverbed Transparency", "Riverbed Transparency", "tcp.options.rvbd.trpy", proto_tcp, FT_BYTES);
8397     proto_tcp_option_exp = proto_register_protocol_in_name_only("TCP Option - Experimental", "Experimental", "tcp.options.experimental", proto_tcp, FT_BYTES);
8398     proto_tcp_option_unknown = proto_register_protocol_in_name_only("TCP Option - Unknown", "Unknown", "tcp.options.unknown", proto_tcp, FT_BYTES);
8399 
8400     register_capture_dissector_table("tcp.port", "TCP");
8401 
8402     /* Register configuration preferences */
8403     tcp_module = prefs_register_protocol(proto_tcp, NULL);
8404     prefs_register_bool_preference(tcp_module, "summary_in_tree",
8405         "Show TCP summary in protocol tree",
8406         "Whether the TCP summary line should be shown in the protocol tree",
8407         &tcp_summary_in_tree);
8408     prefs_register_bool_preference(tcp_module, "check_checksum",
8409         "Validate the TCP checksum if possible",
8410         "Whether to validate the TCP checksum or not.  "
8411         "(Invalid checksums will cause reassembly, if enabled, to fail.)",
8412         &tcp_check_checksum);
8413     prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
8414         "Allow subdissector to reassemble TCP streams",
8415         "Whether subdissector can request TCP streams to be reassembled",
8416         &tcp_desegment);
8417     prefs_register_bool_preference(tcp_module, "reassemble_out_of_order",
8418         "Reassemble out-of-order segments",
8419         "Whether out-of-order segments should be buffered and reordered before passing it to a subdissector. "
8420         "To use this option you must also enable \"Allow subdissector to reassemble TCP streams\".",
8421         &tcp_reassemble_out_of_order);
8422     prefs_register_bool_preference(tcp_module, "analyze_sequence_numbers",
8423         "Analyze TCP sequence numbers",
8424         "Make the TCP dissector analyze TCP sequence numbers to find and flag segment retransmissions, missing segments and RTT",
8425         &tcp_analyze_seq);
8426     prefs_register_bool_preference(tcp_module, "relative_sequence_numbers",
8427         "Relative sequence numbers (Requires \"Analyze TCP sequence numbers\")",
8428         "Make the TCP dissector use relative sequence numbers instead of absolute ones. "
8429         "To use this option you must also enable \"Analyze TCP sequence numbers\". ",
8430         &tcp_relative_seq);
8431     prefs_register_enum_preference(tcp_module, "default_window_scaling",
8432         "Scaling factor to use when not available from capture",
8433         "Make the TCP dissector use this scaling factor for streams where the signalled scaling factor "
8434         "is not visible in the capture",
8435         &tcp_default_window_scaling, window_scaling_vals, FALSE);
8436 
8437     /* Presumably a retired, unconditional version of what has been added back with the preference above... */
8438     prefs_register_obsolete_preference(tcp_module, "window_scaling");
8439 
8440     prefs_register_bool_preference(tcp_module, "track_bytes_in_flight",
8441         "Track number of bytes in flight",
8442         "Make the TCP dissector track the number on un-ACKed bytes of data are in flight per packet. "
8443         "To use this option you must also enable \"Analyze TCP sequence numbers\". "
8444         "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",
8445         &tcp_track_bytes_in_flight);
8446     prefs_register_bool_preference(tcp_module, "bif_seq_based",
8447         "Evaluate bytes in flight based on sequence numbers",
8448         "Evaluate BiF on actual sequence numbers or use the historical method based on payloads (default). "
8449         "This option has no effect if not used with \"Track number of bytes in flight\". ",
8450         &tcp_bif_seq_based);
8451     prefs_register_bool_preference(tcp_module, "calculate_timestamps",
8452         "Calculate conversation timestamps",
8453         "Calculate timestamps relative to the first frame and the previous frame in the tcp conversation",
8454         &tcp_calculate_ts);
8455     prefs_register_bool_preference(tcp_module, "try_heuristic_first",
8456         "Try heuristic sub-dissectors first",
8457         "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
8458         &try_heuristic_first);
8459     prefs_register_bool_preference(tcp_module, "ignore_tcp_timestamps",
8460         "Ignore TCP Timestamps in summary",
8461         "Do not place the TCP Timestamps in the summary line",
8462         &tcp_ignore_timestamps);
8463     prefs_register_bool_preference(tcp_module, "fastrt_supersedes_ooo",
8464         "Fast Retransmission supersedes Out-of-Order interpretation",
8465         "When interpreting ambiguous packets, give precedence to Fast Retransmission or OOO ",
8466         &tcp_fastrt_precedence);
8467 
8468     prefs_register_bool_preference(tcp_module, "no_subdissector_on_error",
8469         "Do not call subdissectors for error packets",
8470         "Do not call any subdissectors for Retransmitted or OutOfOrder segments",
8471         &tcp_no_subdissector_on_error);
8472 
8473     prefs_register_bool_preference(tcp_module, "dissect_experimental_options_with_magic",
8474         "TCP Experimental Options with a Magic Number",
8475         "Assume TCP Experimental Options (253, 254) have a Magic Number and use it for dissection",
8476         &tcp_exp_options_with_magic);
8477 
8478     prefs_register_bool_preference(tcp_module, "display_process_info_from_ipfix",
8479         "Display process information via IPFIX",
8480         "Collect and store process information retrieved from IPFIX dissector",
8481         &tcp_display_process_info);
8482 
8483     register_init_routine(tcp_init);
8484     reassembly_table_register(&tcp_reassembly_table,
8485                           &addresses_ports_reassembly_table_functions);
8486 
8487     register_decode_as(&tcp_da);
8488 
8489     register_conversation_table(proto_tcp, FALSE, tcpip_conversation_packet, tcpip_hostlist_packet);
8490     register_conversation_filter("tcp", "TCP", tcp_filter_valid, tcp_build_filter);
8491 
8492     register_seq_analysis("tcp", "TCP Flows", proto_tcp, NULL, 0, tcp_seq_analysis_packet);
8493 
8494     /* considers MPTCP as a distinct protocol (even if it's a TCP option) */
8495     proto_mptcp = proto_register_protocol("Multipath Transmission Control Protocol", "MPTCP", "mptcp");
8496 
8497     proto_register_field_array(proto_mptcp, mptcp_hf, array_length(mptcp_hf));
8498     proto_register_subtree_array(mptcp_ett, array_length(mptcp_ett));
8499 
8500     /* Register configuration preferences */
8501     mptcp_module = prefs_register_protocol(proto_mptcp, NULL);
8502     expert_mptcp = expert_register_protocol(proto_tcp);
8503     expert_register_field_array(expert_mptcp, mptcp_ei, array_length(mptcp_ei));
8504 
8505     prefs_register_bool_preference(mptcp_module, "analyze_mptcp",
8506         "Map TCP subflows to their respective MPTCP connections",
8507         "To use this option you must also enable \"Analyze TCP sequence numbers\". ",
8508         &tcp_analyze_mptcp);
8509 
8510     prefs_register_bool_preference(mptcp_module, "relative_sequence_numbers",
8511         "Display relative MPTCP sequence numbers.",
8512         "In case you don't capture the key, it will use the first DSN seen",
8513         &mptcp_relative_seq);
8514 
8515     prefs_register_bool_preference(mptcp_module, "analyze_mappings",
8516         "Deeper analysis of Data Sequence Signal (DSS)",
8517         "Scales logarithmically with the number of packets"
8518         "You need to capture the handshake for this to work."
8519         "\"Map TCP subflows to their respective MPTCP connections\"",
8520         &mptcp_analyze_mappings);
8521 
8522     prefs_register_bool_preference(mptcp_module, "intersubflows_retransmission",
8523         "Check for data duplication across subflows",
8524         "(Greedy algorithm: Scales linearly with number of subflows and"
8525         " logarithmic scaling with number of packets)"
8526         "You need to enable DSS mapping analysis for this option to work",
8527         &mptcp_intersubflows_retransmission);
8528 
8529     register_conversation_table(proto_mptcp, FALSE, mptcpip_conversation_packet, tcpip_hostlist_packet);
8530     register_follow_stream(proto_tcp, "tcp_follow", tcp_follow_conv_filter, tcp_follow_index_filter, tcp_follow_address_filter,
8531                             tcp_port_to_display, follow_tcp_tap_listener);
8532 }
8533 
8534 void
proto_reg_handoff_tcp(void)8535 proto_reg_handoff_tcp(void)
8536 {
8537     capture_dissector_handle_t tcp_cap_handle;
8538 
8539     dissector_add_uint("ip.proto", IP_PROTO_TCP, tcp_handle);
8540     dissector_add_for_decode_as_with_preference("udp.port", tcp_handle);
8541     data_handle = find_dissector("data");
8542     sport_handle = find_dissector("sport");
8543     tcp_tap = register_tap("tcp");
8544     tcp_follow_tap = register_tap("tcp_follow");
8545 
8546     tcp_cap_handle = create_capture_dissector_handle(capture_tcp, proto_tcp);
8547     capture_dissector_add_uint("ip.proto", IP_PROTO_TCP, tcp_cap_handle);
8548 
8549     /* Create dissection function handles for all TCP options */
8550     dissector_add_uint("tcp.option", TCPOPT_TIMESTAMP, create_dissector_handle( dissect_tcpopt_timestamp, proto_tcp_option_timestamp ));
8551     dissector_add_uint("tcp.option", TCPOPT_MSS, create_dissector_handle( dissect_tcpopt_mss, proto_tcp_option_mss ));
8552     dissector_add_uint("tcp.option", TCPOPT_WINDOW, create_dissector_handle( dissect_tcpopt_wscale, proto_tcp_option_wscale ));
8553     dissector_add_uint("tcp.option", TCPOPT_SACK_PERM, create_dissector_handle( dissect_tcpopt_sack_perm, proto_tcp_option_sack_perm ));
8554     dissector_add_uint("tcp.option", TCPOPT_SACK, create_dissector_handle( dissect_tcpopt_sack, proto_tcp_option_sack ));
8555     dissector_add_uint("tcp.option", TCPOPT_ECHO, create_dissector_handle( dissect_tcpopt_echo, proto_tcp_option_echo ));
8556     dissector_add_uint("tcp.option", TCPOPT_ECHOREPLY, create_dissector_handle( dissect_tcpopt_echo, proto_tcp_option_echoreply ));
8557     dissector_add_uint("tcp.option", TCPOPT_CC, create_dissector_handle( dissect_tcpopt_cc, proto_tcp_option_cc ));
8558     dissector_add_uint("tcp.option", TCPOPT_CCNEW, create_dissector_handle( dissect_tcpopt_cc, proto_tcp_option_cc_new ));
8559     dissector_add_uint("tcp.option", TCPOPT_CCECHO, create_dissector_handle( dissect_tcpopt_cc, proto_tcp_option_cc_echo ));
8560     dissector_add_uint("tcp.option", TCPOPT_MD5, create_dissector_handle( dissect_tcpopt_md5, proto_tcp_option_md5 ));
8561     dissector_add_uint("tcp.option", TCPOPT_AO, create_dissector_handle( dissect_tcpopt_ao, proto_tcp_option_ao ));
8562     dissector_add_uint("tcp.option", TCPOPT_SCPS, create_dissector_handle( dissect_tcpopt_scps, proto_tcp_option_scps ));
8563     dissector_add_uint("tcp.option", TCPOPT_SNACK, create_dissector_handle( dissect_tcpopt_snack, proto_tcp_option_snack ));
8564     dissector_add_uint("tcp.option", TCPOPT_RECBOUND, create_dissector_handle( dissect_tcpopt_recbound, proto_tcp_option_scpsrec ));
8565     dissector_add_uint("tcp.option", TCPOPT_CORREXP, create_dissector_handle( dissect_tcpopt_correxp, proto_tcp_option_scpscor ));
8566     dissector_add_uint("tcp.option", TCPOPT_QS, create_dissector_handle( dissect_tcpopt_qs, proto_tcp_option_qs ));
8567     dissector_add_uint("tcp.option", TCPOPT_USER_TO, create_dissector_handle( dissect_tcpopt_user_to, proto_tcp_option_user_to ));
8568     dissector_add_uint("tcp.option", TCPOPT_TFO, create_dissector_handle( dissect_tcpopt_tfo, proto_tcp_option_tfo ));
8569     dissector_add_uint("tcp.option", TCPOPT_RVBD_PROBE, create_dissector_handle( dissect_tcpopt_rvbd_probe, proto_tcp_option_rvbd_probe ));
8570     dissector_add_uint("tcp.option", TCPOPT_RVBD_TRPY, create_dissector_handle( dissect_tcpopt_rvbd_trpy, proto_tcp_option_rvbd_trpy ));
8571     dissector_add_uint("tcp.option", TCPOPT_EXP_FD, create_dissector_handle( dissect_tcpopt_exp, proto_tcp_option_exp ));
8572     dissector_add_uint("tcp.option", TCPOPT_EXP_FE, create_dissector_handle( dissect_tcpopt_exp, proto_tcp_option_exp ));
8573     dissector_add_uint("tcp.option", TCPOPT_MPTCP, create_dissector_handle( dissect_tcpopt_mptcp, proto_mptcp ));
8574     /* Common handle for all the unknown/unsupported TCP options */
8575     tcp_opt_unknown_handle = create_dissector_handle( dissect_tcpopt_unknown, proto_tcp_option_unknown );
8576 
8577     mptcp_tap = register_tap("mptcp");
8578     exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_4);
8579 
8580     proto_ip = proto_get_id_by_filter_name("ip");
8581     proto_icmp = proto_get_id_by_filter_name("icmp");
8582 }
8583 
8584 /*
8585  * Editor modelines
8586  *
8587  * Local Variables:
8588  * c-basic-offset: 4
8589  * tab-width: 8
8590  * indent-tabs-mode: nil
8591  * End:
8592  *
8593  * ex: set shiftwidth=4 tabstop=8 expandtab:
8594  * :indentSize=4:tabSize=8:noTabs=true:
8595  */
8596