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