3 * Routines for Stateless Transport Tunneling (STT) packet dissection
4 * Remi Vichery <remi.vichery@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 * https://tools.ietf.org/html/draft-davie-stt-07
18 #include <epan/packet.h>
19 #include <epan/expert.h>
20 #include <epan/in_cksum.h>
21 #include <epan/ipproto.h>
22 #include <epan/prefs.h>
23 #include <epan/reassemble.h>
25 #include <epan/unit_strings.h>
27 #include <wsutil/array.h>
29 #include "packet-ip.h"
31 static bool pref_reassemble
= true;
32 static bool pref_check_checksum
;
35 * https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
37 #define TCP_PORT_STT 7471
39 /* Length of entire overloaded TCP header. */
40 #define STT_TCP_HDR_LEN 20
42 /* Sum of STT header field sizes plus trailing padding. */
43 #define STT_HEADER_SIZE 18
45 #define STT_TCP_OFF_DPORT 2
46 #define STT_TCP_OFF_PKT_LEN 4
47 #define STT_TCP_OFF_SEG_OFF 6
48 #define STT_TCP_OFF_PKT_ID 8
50 #define STT_PCP_MASK 0xE000
51 #define STT_V_MASK 0x1000
52 #define STT_VLANID_MASK 0x0FFF
54 #define FLAG_OFFLOAD_MASK 0x02
56 void proto_register_stt(void);
57 void proto_reg_handoff_stt(void);
61 static int hf_stt_stream_id
;
62 static int hf_stt_dport
;
63 static int hf_stt_pkt_len
;
64 static int hf_stt_seg_off
;
65 static int hf_stt_pkt_id
;
66 static int hf_stt_checksum
;
67 static int hf_stt_checksum_status
;
68 static int hf_stt_tcp_data
;
69 static int hf_stt_tcp_data_offset
;
70 static int hf_stt_tcp_flags
;
71 static int hf_stt_tcp_rsvd
;
72 static int hf_stt_tcp_ns
;
73 static int hf_stt_tcp_cwr
;
74 static int hf_stt_tcp_ece
;
75 static int hf_stt_tcp_urg
;
76 static int hf_stt_tcp_ack
;
77 static int hf_stt_tcp_psh
;
78 static int hf_stt_tcp_rst
;
79 static int hf_stt_tcp_syn
;
80 static int hf_stt_tcp_fin
;
81 static int hf_stt_tcp_window
;
82 static int hf_stt_tcp_urg_ptr
;
84 static int hf_stt_version
;
85 static int hf_stt_flags
;
86 static int hf_stt_flag_rsvd
;
87 static int hf_stt_flag_tcp
;
88 static int hf_stt_flag_ipv4
;
89 static int hf_stt_flag_partial
;
90 static int hf_stt_flag_verified
;
91 static int hf_stt_l4_offset
;
92 static int hf_stt_reserved_8
;
93 static int hf_stt_mss
;
94 static int hf_stt_vlan
;
95 static int hf_stt_pcp
;
97 static int hf_stt_vlan_id
;
98 static int hf_stt_context_id
;
99 static int hf_stt_padding
;
101 static int hf_segments
;
102 static int hf_segment
;
103 static int hf_segment_overlap
;
104 static int hf_segment_overlap_conflict
;
105 static int hf_segment_multiple_tails
;
106 static int hf_segment_too_long_fragment
;
107 static int hf_segment_error
;
108 static int hf_segment_count
;
109 static int hf_reassembled_in
;
110 static int hf_reassembled_length
;
113 static int ett_stt_tcp_data
;
114 static int ett_stt_tcp_flags
;
115 static int ett_stt_flgs
;
116 static int ett_stt_vlan
;
117 static int ett_segment
;
118 static int ett_segments
;
120 static reassembly_table stt_reassembly_table
;
122 static expert_field ei_stt_ver_unknown
;
123 static expert_field ei_stt_checksum_bad
;
124 static expert_field ei_stt_data_offset_bad
;
125 static expert_field ei_stt_l4_offset
;
126 static expert_field ei_stt_mss
;
128 static dissector_handle_t eth_handle
;
130 /* From Table G-2 of IEEE standard 802.1Q-2005 */
131 static const value_string pri_vals
[] = {
133 { 0, "Best Effort (default)" },
134 { 2, "Excellent Effort" },
135 { 3, "Critical Applications" },
136 { 4, "Video, < 100ms latency and jitter" },
137 { 5, "Voice, < 10ms latency and jitter" },
138 { 6, "Internetwork Control" },
139 { 7, "Network Control" },
143 static const fragment_items frag_items
= {
149 &hf_segment_overlap_conflict
,
150 &hf_segment_multiple_tails
,
151 &hf_segment_too_long_fragment
,
155 &hf_reassembled_length
,
156 NULL
, /* Reassembled data */
161 handle_segment(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
162 uint32_t pkt_id
, uint16_t pkt_len
, uint16_t seg_off
)
164 fragment_head
*frags
;
166 uint32_t frag_data_len
;
169 /* Skip fake TCP header after the first segment. */
173 offset
= STT_TCP_HDR_LEN
;
174 /* We saved the TCP header on the first packet (only), which skews the
176 seg_off
+= STT_TCP_HDR_LEN
;
179 frag_data_len
= tvb_reported_length_remaining(tvb
, offset
);
180 more_frags
= seg_off
+ frag_data_len
< pkt_len
;
182 frags
= fragment_add_check(&stt_reassembly_table
, tvb
, offset
, pinfo
,
183 pkt_id
, NULL
, seg_off
, frag_data_len
,
186 /* Update reassembly fields in UI if reassembly is complete. */
188 return process_reassembled_data(tvb
, offset
, pinfo
, "Reassembled STT",
189 frags
, &frag_items
, NULL
, tree
);
196 dissect_stt_checksum(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*stt_tree
)
198 bool can_checksum
= !pinfo
->fragmented
&&
199 tvb_bytes_exist(tvb
, 0, tvb_reported_length(tvb
));
201 if (can_checksum
&& pref_check_checksum
) {
205 /* Set up the fields of the pseudo-header. */
206 SET_CKSUM_VEC_PTR(cksum_vec
[0], (const uint8_t *)pinfo
->src
.data
,
208 SET_CKSUM_VEC_PTR(cksum_vec
[1], (const uint8_t *)pinfo
->dst
.data
,
210 switch (pinfo
->src
.type
) {
212 phdr
[0] = g_htonl((IP_PROTO_TCP
<<16) + tvb_reported_length(tvb
));
213 SET_CKSUM_VEC_PTR(cksum_vec
[2], (const uint8_t *)phdr
, 4);
217 phdr
[0] = g_htonl(tvb_reported_length(tvb
));
218 phdr
[1] = g_htonl(IP_PROTO_TCP
);
219 SET_CKSUM_VEC_PTR(cksum_vec
[2], (const uint8_t *)phdr
, 8);
223 /* STT runs only atop IPv4 and IPv6.... */
224 DISSECTOR_ASSERT_NOT_REACHED();
227 SET_CKSUM_VEC_TVB(cksum_vec
[3], tvb
, 0, tvb_reported_length(tvb
));
229 proto_tree_add_checksum(stt_tree
, tvb
, 16, hf_stt_checksum
, hf_stt_checksum_status
, &ei_stt_checksum_bad
, pinfo
,
230 in_cksum(cksum_vec
, 4), ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
232 proto_tree_add_checksum(stt_tree
, tvb
, 16, hf_stt_checksum
, hf_stt_checksum_status
, &ei_stt_checksum_bad
, pinfo
,
233 0, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
238 dissect_tcp_flags(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
240 static int * const flags
[] = {
254 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_stt_tcp_flags
,
255 ett_stt_tcp_flags
, flags
, ENC_BIG_ENDIAN
);
262 dissect_tcp_tree(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*stt_tree
)
265 proto_tree
*tcp_tree
;
266 proto_item
*tcp_item
, *data_offset_item
;
269 proto_tree_add_item(stt_tree
, hf_stt_stream_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
272 proto_tree_add_item(stt_tree
, hf_stt_dport
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
275 proto_tree_add_item(stt_tree
, hf_stt_pkt_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
278 proto_tree_add_item(stt_tree
, hf_stt_seg_off
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
281 proto_tree_add_item(stt_tree
, hf_stt_pkt_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
284 tcp_item
= proto_tree_add_item(stt_tree
, hf_stt_tcp_data
, tvb
, offset
,
286 tcp_tree
= proto_item_add_subtree(tcp_item
, ett_stt_tcp_data
);
287 proto_item_set_text(tcp_item
, "TCP Data");
289 data_offset
= hi_nibble(tvb_get_uint8(tvb
, offset
)) * 4;
290 data_offset_item
= proto_tree_add_uint(tcp_tree
,
291 hf_stt_tcp_data_offset
,
294 if (data_offset
!= STT_TCP_HDR_LEN
) {
295 expert_add_info(pinfo
, data_offset_item
, &ei_stt_data_offset_bad
);
298 offset
= dissect_tcp_flags(tcp_tree
, tvb
, offset
);
300 proto_tree_add_item(tcp_tree
, hf_stt_tcp_window
, tvb
, offset
, 2,
304 dissect_stt_checksum(tvb
, pinfo
, stt_tree
);
307 proto_tree_add_item(tcp_tree
, hf_stt_tcp_urg_ptr
, tvb
, offset
, 2,
312 dissect_stt_flags(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
314 static int * const flags
[] = {
318 &hf_stt_flag_partial
,
319 &hf_stt_flag_verified
,
323 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_stt_flags
,
324 ett_stt_flgs
, flags
, ENC_BIG_ENDIAN
);
331 dissect_stt_tree(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*stt_tree
,
332 proto_item
*stt_item
)
334 proto_tree
*vlan_tree
;
335 proto_item
*ver_item
, *l4_offset_item
, *vlan_item
, *mss_item
;
337 uint32_t version
, l4_offset
, mss
, attributes
;
339 int offset
= STT_TCP_HDR_LEN
;
343 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
344 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
345 | Version | Flags | L4 Offset | Reserved |
346 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347 | Max. Segment Size | PCP |V| VLAN ID |
348 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
350 + Context ID (64 bits) +
352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
358 /* Protocol version */
359 ver_item
= proto_tree_add_item_ret_uint(stt_tree
, hf_stt_version
, tvb
,
360 offset
, 1, ENC_BIG_ENDIAN
, &version
);
362 expert_add_info_format(pinfo
, ver_item
, &ei_stt_ver_unknown
,
363 "Unknown version %u", version
);
364 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown STT version %u", version
);
369 flags
= tvb_get_uint8(tvb
, offset
);
370 offset
= dissect_stt_flags(stt_tree
, tvb
, offset
);
373 l4_offset_item
= proto_tree_add_item_ret_uint(stt_tree
, hf_stt_l4_offset
,
375 ENC_BIG_ENDIAN
, &l4_offset
);
376 /* Display an error if offset is != 0 when offloading is not in use */
377 if ( !(flags
& FLAG_OFFLOAD_MASK
) && (l4_offset
!= 0) ) {
378 expert_add_info_format(pinfo
, l4_offset_item
, &ei_stt_l4_offset
, "Incorrect offset, should be equal to zero");
380 /* Display an error if offset equals 0 when there is offloading */
381 if ( (flags
& FLAG_OFFLOAD_MASK
) && (l4_offset
== 0) ) {
382 expert_add_info_format(pinfo
, l4_offset_item
, &ei_stt_l4_offset
, "Incorrect offset, should be greater than zero");
386 /* Reserved field (1 byte). MUST be 0 on transmission,
387 ignored on receipt. */
388 proto_tree_add_item(stt_tree
, hf_stt_reserved_8
, tvb
, offset
, 1,
392 /* Maximum Segment Size. MUST be 0 if segmentation offload
394 mss_item
= proto_tree_add_item_ret_uint(stt_tree
, hf_stt_mss
, tvb
,
395 offset
, 2, ENC_BIG_ENDIAN
, &mss
);
396 /* Display an error if MSS is != 0 when offloading is not in use */
397 if ( !(flags
& FLAG_OFFLOAD_MASK
) && (mss
!= 0) ) {
398 expert_add_info_format(pinfo
, mss_item
, &ei_stt_mss
, "Incorrect max segment size, should be equal to zero");
402 /* Tag Control Information like header. If V flag is set, it
403 indicates the presence of a valid VLAN ID in the following field
404 and valid PCP in the preceding field. */
405 vlan_item
= proto_tree_add_item_ret_uint(stt_tree
, hf_stt_vlan
, tvb
, offset
,
406 2, ENC_BIG_ENDIAN
, &attributes
);
407 vlan_tree
= proto_item_add_subtree(vlan_item
, ett_stt_vlan
);
408 proto_item_set_text(vlan_item
, "VLAN Priority %u, ID %u",
409 (attributes
>> 13), (attributes
& STT_VLANID_MASK
));
411 proto_tree_add_item(vlan_tree
, hf_stt_pcp
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
412 proto_tree_add_item(vlan_tree
, hf_stt_v
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
413 proto_tree_add_item(vlan_tree
, hf_stt_vlan_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
414 if (attributes
& STT_V_MASK
) {
415 /* Display priority code point and VLAN ID when V flag is set */
416 proto_item_append_text(stt_item
, ", Priority: %u, VLAN ID: %u",
418 attributes
& STT_VLANID_MASK
);
420 /* Show if any part of this is set to aid debugging bad implementations. */
421 if (attributes
== 0) {
422 proto_item_set_hidden(vlan_item
);
427 context_id
= tvb_get_ntoh64(tvb
, offset
);
428 proto_tree_add_item(stt_tree
, hf_stt_context_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
429 proto_item_append_text(stt_item
, ", Context ID: 0x%" PRIx64
,
434 proto_tree_add_item(stt_tree
, hf_stt_padding
, tvb
, offset
,
439 dissect_stt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
441 proto_item
*stt_item
;
442 proto_tree
*stt_tree
;
444 uint16_t seg_off
, pkt_len
, rx_bytes
;
446 bool frag_save
, is_seg
;
448 /* Make entry in Protocol column on summary display. */
449 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "STT");
450 col_clear(pinfo
->cinfo
, COL_INFO
);
452 stt_item
= proto_tree_add_item(tree
, proto_stt
, tvb
, 0,
453 STT_TCP_HDR_LEN
, ENC_NA
);
454 stt_tree
= proto_item_add_subtree(stt_item
, ett_stt
);
456 dissect_tcp_tree(tvb
, pinfo
, stt_tree
);
458 frag_save
= pinfo
->fragmented
;
460 seg_off
= tvb_get_ntohs(tvb
, STT_TCP_OFF_SEG_OFF
);
461 pkt_len
= tvb_get_ntohs(tvb
, STT_TCP_OFF_PKT_LEN
);
462 rx_bytes
= tvb_reported_length_remaining(tvb
, STT_TCP_HDR_LEN
);
463 is_seg
= pkt_len
> rx_bytes
;
466 uint32_t pkt_id
= tvb_get_ntohl(tvb
, STT_TCP_OFF_PKT_ID
);
468 pinfo
->fragmented
= true;
469 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
470 "STT Segment (ID: 0x%x Len: %hu, Off: %hu)",
471 pkt_id
, pkt_len
, seg_off
);
473 /* Reassemble segments unless the user has disabled reassembly. */
474 if (pref_reassemble
&& tvb_bytes_exist(tvb
, 0, rx_bytes
)) {
477 reasm_tvb
= handle_segment(tvb
, pinfo
, stt_tree
, pkt_id
,
481 pinfo
->fragmented
= frag_save
;
484 } else if (seg_off
== 0) {
485 /* If we're not reassembling, move ahead as if we have the
491 /* Only full packets have a STT header (following the fake TCP header). */
493 sub_off
= STT_TCP_HDR_LEN
+ STT_HEADER_SIZE
;
494 dissect_stt_tree(tvb
, pinfo
, stt_tree
, stt_item
);
496 sub_off
= STT_TCP_HDR_LEN
;
500 proto_item_set_len(stt_item
, sub_off
);
502 next_tvb
= tvb_new_subset_remaining(tvb
, sub_off
);
504 /* Only dissect inner frame if not segmented or if we aren't
507 call_dissector(eth_handle
, next_tvb
, pinfo
, tree
);
509 call_data_dissector(next_tvb
, pinfo
, tree
);
512 pinfo
->fragmented
= frag_save
;
516 dissect_stt_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
519 /* Make sure we at least have a TCP header */
520 if (ws_ip_protocol(iph
) != IP_PROTO_TCP
||
521 tvb_captured_length(tvb
) < STT_TCP_HDR_LEN
) {
525 /* Check the TCP destination port */
526 if (tvb_get_ntohs(tvb
, STT_TCP_OFF_DPORT
) != TCP_PORT_STT
) {
530 dissect_stt(tvb
, pinfo
, tree
);
534 /* Register STT with Wireshark */
536 proto_register_stt(void)
538 expert_module_t
* expert_stt
;
541 static hf_register_info hf
[] = {
542 /* Overloaded fake TCP header fields. */
544 { "Stream ID", "stt.stream_id",
545 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
550 { "Destination Port", "stt.dport",
551 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
556 { "Packet Length", "stt.pkt_len",
557 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
562 { "Segment Offset", "stt.seg_off",
563 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
568 { "Packet ID", "stt.pkt_id",
569 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
574 { "TCP Data", "stt.tcp",
575 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
579 { &hf_stt_tcp_data_offset
,
580 { "Data Offset", "stt.tcp.data_offset",
581 FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0x0,
586 { "Flags", "stt.tcp.flags",
587 FT_UINT16
, BASE_HEX
, NULL
, 0x0FFF,
592 { "Reserved", "stt.tcp.flags.rsvd",
593 FT_BOOLEAN
, 12, NULL
, 0xE00,
598 { "Nonce", "stt.tcp.flags.ns",
599 FT_BOOLEAN
, 12, NULL
, 0x100,
604 { "Congestion Window Reduced (CWR)", "stt.tcp.flags.cwr",
605 FT_BOOLEAN
, 12, NULL
, 0x080,
610 { "ECN-Echo", "stt.tcp.flags.ece",
611 FT_BOOLEAN
, 12, NULL
, 0x040,
616 { "Urgent", "stt.tcp.flags.urg",
617 FT_BOOLEAN
, 12, NULL
, 0x020,
622 { "Acknowledgement", "stt.tcp.flags.ack",
623 FT_BOOLEAN
, 12, NULL
, 0x010,
628 { "Push", "stt.tcp.flags.psh",
629 FT_BOOLEAN
, 12, NULL
, 0x008,
634 { "Reset", "stt.tcp.flags.rst",
635 FT_BOOLEAN
, 12, NULL
, 0x004,
640 { "Syn", "stt.tcp.flags.syn",
641 FT_BOOLEAN
, 12, NULL
, 0x002,
646 { "Fin", "stt.tcp.flags.fin",
647 FT_BOOLEAN
, 12, NULL
, 0x001,
651 { &hf_stt_tcp_window
,
652 { "Window", "stt.tcp.window",
653 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
657 { &hf_stt_tcp_urg_ptr
,
658 { "Urgent Pointer", "stt.tcp.urg_ptr",
659 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
664 /* STT header fields. */
666 { "Version", "stt.version",
667 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
672 { "Flags", "stt.flags",
673 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
678 { "Reserved", "stt.flags.rsvd",
679 FT_BOOLEAN
, 8, NULL
, 0xF0,
684 { "TCP payload", "stt.flags.tcp",
685 FT_BOOLEAN
, 8, NULL
, 0x08,
690 { "IPv4 packet", "stt.flags.ipv4",
691 FT_BOOLEAN
, 8, NULL
, 0x04,
695 { &hf_stt_flag_partial
,
696 { "Checksum partial", "stt.flags.csum_partial",
697 FT_BOOLEAN
, 8, NULL
, 0x02,
701 { &hf_stt_flag_verified
,
702 { "Checksum verified", "stt.flags.csum_verified",
703 FT_BOOLEAN
, 8, NULL
, 0x01,
708 { "L4 Offset", "stt.l4offset",
709 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
713 { &hf_stt_reserved_8
,
714 { "Reserved", "stt.reserved",
715 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
720 { "Max Segment Size", "stt.mss",
721 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
726 { "VLAN", "stt.vlan",
727 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
732 { "PCP", "stt.vlan.pcp",
733 FT_UINT16
, BASE_DEC
, VALS(pri_vals
), STT_PCP_MASK
,
738 { "V flag", "stt.vlan.v",
739 FT_UINT16
, BASE_DEC
, NULL
, STT_V_MASK
,
744 { "VLAN ID", "stt.vlan.id",
745 FT_UINT16
, BASE_DEC
, NULL
, STT_VLANID_MASK
,
749 { &hf_stt_context_id
,
750 { "Context ID", "stt.context_id",
751 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
756 { "Padding", "stt.padding",
757 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
762 /* Checksum validation fields */
764 { "Checksum", "stt.checksum",
765 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
766 "Details at: https://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL
769 { &hf_stt_checksum_status
,
770 { "Checksum Status", "stt.checksum.status",
771 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
776 /* Segment reassembly information. */
777 { &hf_segment_overlap
,
778 { "Segment overlap", "stt.segment.overlap",
779 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
780 "Segment overlaps with other segments", HFILL
783 { &hf_segment_overlap_conflict
,
784 { "Conflicting data in segment overlap", "stt.segment.overlap.conflict",
785 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
786 "Overlapping segments contained conflicting data", HFILL
789 { &hf_segment_multiple_tails
,
790 { "Multiple tail segments found", "stt.segment.multipletails",
791 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
792 "Several tails were found when reassembling the packet", HFILL
795 { &hf_segment_too_long_fragment
,
796 { "Segment too long", "stt.segment.toolongfragment",
797 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
798 "Segment contained data past end of the packet", HFILL
802 { "Reassembling error", "stt.segment.error",
803 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
804 "Reassembling error due to illegal segments", HFILL
808 { "Segment count", "stt.segment.count",
809 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
814 { "STT Segment", "stt.segment",
815 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
820 { "Reassembled STT Segments", "stt.segments",
821 FT_NONE
, BASE_NONE
, NULL
, 0x0,
825 { &hf_reassembled_in
,
826 { "Reassembled PDU in frame", "stt.reassembled_in",
827 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
828 "The STT packet is reassembled in this frame", HFILL
831 { &hf_reassembled_length
,
832 { "Reassembled STT length", "stt.reassembled.length",
833 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
834 "The total length of the reassembled payload", HFILL
839 /* Setup protocol subtree array */
840 static int *ett
[] = {
850 static ei_register_info ei
[] = {
851 { &ei_stt_checksum_bad
,
852 { "stt.checksum_bad.expert", PI_CHECKSUM
,
853 PI_ERROR
, "Bad checksum", EXPFILL
856 { &ei_stt_data_offset_bad
,
857 { "stt.data_offset_bad.expert", PI_PROTOCOL
,
858 PI_WARN
, "TCP Data Offset should be 20 bytes", EXPFILL
861 { &ei_stt_ver_unknown
,
862 { "stt.version_unknown.expert", PI_PROTOCOL
,
863 PI_WARN
, "Unknown version", EXPFILL
867 { "stt.l4offset_bad.expert", PI_PROTOCOL
,
868 PI_WARN
, "Bad L4 Offset", EXPFILL
872 { "stt.mss_bad.expert", PI_PROTOCOL
,
873 PI_WARN
, "Bad MSS", EXPFILL
878 /* Register the protocol name and description */
879 proto_stt
= proto_register_protocol("Stateless Transport Tunneling",
882 expert_stt
= expert_register_protocol(proto_stt
);
883 expert_register_field_array(expert_stt
, ei
, array_length(ei
));
885 /* Required function calls to register the header fields and
887 proto_register_field_array(proto_stt
, hf
, array_length(hf
));
888 proto_register_subtree_array(ett
, array_length(ett
));
890 stt_prefs
= prefs_register_protocol(proto_stt
, NULL
);
891 prefs_register_bool_preference(stt_prefs
, "reassemble",
892 "Reassemble segmented STT packets",
893 "Reassembles greater than MTU sized STT packets broken into segments on transmit",
895 prefs_register_bool_preference(stt_prefs
, "check_checksum",
896 "Validate the STT checksum if possible",
897 "Whether to validate the STT checksum or not.",
898 &pref_check_checksum
);
900 reassembly_table_register(&stt_reassembly_table
,
901 &addresses_reassembly_table_functions
);
905 proto_reg_handoff_stt(void)
908 * The I-D doesn't explicity indicate that the FCS isn't present
909 * in the tunneled Ethernet frames, but it is missing from the
910 * captures attached to bug 10282.
912 eth_handle
= find_dissector_add_dependency("eth_withoutfcs", proto_stt
);
914 heur_dissector_add("ip", dissect_stt_heur
, "Stateless Transport Tunneling over IP", "stt_ip", proto_stt
, HEURISTIC_ENABLE
);
918 * Editor modelines - https://www.wireshark.org/tools/modelines.html
923 * indent-tabs-mode: nil
926 * vi: set shiftwidth=4 tabstop=8 expandtab:
927 * :indentSize=4:tabSize=8:noTabs=true: