Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ipsec-tcp.c
bloba997587dd8749ba6f2b820a0be5d8ab9a0ea2307
1 /*
2 * Routines for the disassembly of the proprietary Cisco IPSEC in
3 * TCP encapsulation protocol
5 * Copyright 2007 Joerg Mayer (see AUTHORS file)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 /* TODO:
15 * - Find out the meaning of the (unknown) trailer
16 * - UDP checksum is wrong
17 * - Currently doesn't handle AH (lack of sample trace)
20 #include "config.h"
22 #include <epan/packet.h>
23 #include "packet-ndmp.h"
25 void proto_register_tcpencap(void);
26 void proto_reg_handoff_tcpencap(void);
28 static dissector_handle_t tcpencap_handle;
30 static int hf_tcpencap_unknown;
31 static int hf_tcpencap_zero;
32 static int hf_tcpencap_seq;
33 static int hf_tcpencap_ike_direction;
34 static int hf_tcpencap_esp_zero;
35 static int hf_tcpencap_magic;
36 static int hf_tcpencap_proto;
37 static int hf_tcpencap_magic2;
39 static int proto_tcpencap;
40 static int ett_tcpencap;
41 static int ett_tcpencap_unknown;
43 static const value_string tcpencap_ikedir_vals[] = {
44 { 0x0000, "Server to client" },
45 { 0x4000, "Client to server" },
47 { 0, NULL }
50 static const value_string tcpencap_proto_vals[] = {
51 { 0x11, "ISAKMP" },
52 { 0x32, "ESP" },
54 { 0, NULL }
57 #define TRAILERLENGTH 16
58 #define TCP_CISCO_IPSEC 10000
60 static dissector_handle_t esp_handle;
61 static dissector_handle_t udp_handle;
63 #define TCP_ENCAP_P_ESP 1
64 #define TCP_ENCAP_P_UDP 2
67 static int
68 packet_is_tcpencap(tvbuff_t *tvb, packet_info *pinfo, uint32_t offset)
70 if ( /* Must be zero */
71 tvb_get_ntohl(tvb, offset + 0) != 0 ||
72 /* Lower 12 bits must be zero */
73 (tvb_get_ntohs(tvb, offset + 6) & 0xfff) != 0 ||
74 /* Protocol must be UDP or ESP */
75 (tvb_get_uint8(tvb, offset + 13) != 17 &&
76 tvb_get_uint8(tvb, offset + 13) != 50)
77 ) {
78 return false;
81 if(check_if_ndmp(tvb, pinfo)){
82 return false;
85 return true;
89 * TCP Encapsulation of IPsec Packets
90 * as supported by the cisco vpn3000 concentrator series
92 static int
93 dissect_tcpencap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
95 proto_tree *tcpencap_tree = NULL;
96 proto_tree *tcpencap_unknown_tree = NULL;
98 proto_item *tree_item = NULL;
99 proto_item *unknown_item = NULL;
100 tvbuff_t *next_tvb;
101 uint32_t reported_length = tvb_reported_length(tvb);
102 uint32_t offset;
103 uint8_t protocol;
105 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPENCAP");
106 col_clear(pinfo->cinfo, COL_INFO);
108 /* If the first 4 bytes are 0x01f401f4 (udp src and dst port = 500)
109 we most likely have UDP (isakmp) traffic */
111 if (tvb_get_ntohl(tvb, 0) == 0x01f401f4) { /* UDP means ISAKMP */
112 protocol = TCP_ENCAP_P_UDP;
113 } else { /* Hopefully ESP */
114 protocol = TCP_ENCAP_P_ESP;
117 if (tree) {
118 tree_item = proto_tree_add_item(tree, proto_tcpencap, tvb, 0, -1, ENC_NA);
119 tcpencap_tree = proto_item_add_subtree(tree_item, ett_tcpencap);
121 /* Dissect the trailer following the encapsulated IPSEC/ISAKMP packet */
122 offset = reported_length - TRAILERLENGTH;
123 unknown_item = proto_tree_add_item(tcpencap_tree, hf_tcpencap_unknown, tvb,
124 offset, TRAILERLENGTH, ENC_NA);
125 /* Try to guess the contents of the trailer */
126 tcpencap_unknown_tree = proto_item_add_subtree(unknown_item, ett_tcpencap_unknown);
127 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_zero, tvb, offset + 0, 4, ENC_NA);
128 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_seq, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
129 if (protocol == TCP_ENCAP_P_UDP) {
130 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_ike_direction, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
131 } else {
132 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_esp_zero, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
134 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_magic, tvb, offset + 8, 5, ENC_NA);
135 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_proto, tvb, offset + 13, 1, ENC_BIG_ENDIAN);
136 proto_tree_add_item(tcpencap_unknown_tree, hf_tcpencap_magic2, tvb, offset + 14, 2, ENC_NA);
139 /* Create the tvbuffer for the next dissector */
140 next_tvb = tvb_new_subset_length_caplen(tvb, 0, reported_length - TRAILERLENGTH , -1);
141 if (protocol == TCP_ENCAP_P_UDP) {
142 call_dissector(udp_handle, next_tvb, pinfo, tree);
143 } else { /* Hopefully ESP */
144 call_dissector(esp_handle, next_tvb, pinfo, tree);
147 return tvb_captured_length(tvb);
150 static bool
151 dissect_tcpencap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
153 uint32_t reported_length = tvb_reported_length(tvb);
154 uint32_t captured_length = tvb_captured_length(tvb);
156 if (reported_length <= TRAILERLENGTH + 8 ||
157 /* Ensure we have enough bytes for packet_is_tcpencap analysis */
158 (reported_length - captured_length) > (TRAILERLENGTH - 13) ||
159 !packet_is_tcpencap(tvb, pinfo, reported_length - TRAILERLENGTH) ) {
160 return false;
163 dissect_tcpencap(tvb, pinfo, tree, data);
164 return true;
167 void
168 proto_register_tcpencap(void)
170 static hf_register_info hf[] = {
172 { &hf_tcpencap_unknown,
173 { "Unknown trailer", "tcpencap.unknown", FT_BYTES, BASE_NONE, NULL,
174 0x0, NULL, HFILL }},
176 { &hf_tcpencap_zero,
177 { "All zero", "tcpencap.zero", FT_BYTES, BASE_NONE, NULL,
178 0x0, NULL, HFILL }},
180 { &hf_tcpencap_seq,
181 { "Sequence number", "tcpencap.seq", FT_UINT16, BASE_HEX, NULL,
182 0x0, NULL, HFILL }},
184 { &hf_tcpencap_esp_zero,
185 { "ESP zero", "tcpencap.espzero", FT_UINT16, BASE_HEX, NULL,
186 0x0, NULL, HFILL }},
188 { &hf_tcpencap_ike_direction,
189 { "ISAKMP traffic direction", "tcpencap.ikedirection", FT_UINT16, BASE_HEX, VALS(tcpencap_ikedir_vals),
190 0x0, NULL, HFILL }},
192 { &hf_tcpencap_magic,
193 { "Magic number", "tcpencap.magic", FT_BYTES, BASE_NONE, NULL,
194 0x0, NULL, HFILL }},
196 { &hf_tcpencap_proto,
197 { "Protocol", "tcpencap.proto", FT_UINT8, BASE_HEX, VALS(tcpencap_proto_vals),
198 0x0, NULL, HFILL }},
200 { &hf_tcpencap_magic2,
201 { "Magic 2", "tcpencap.magic2", FT_BYTES, BASE_NONE, NULL,
202 0x0, NULL, HFILL }},
206 static int *ett[] = {
207 &ett_tcpencap,
208 &ett_tcpencap_unknown,
211 proto_tcpencap = proto_register_protocol("TCP Encapsulation of IPsec Packets", "TCPENCAP", "tcpencap");
213 proto_register_field_array(proto_tcpencap, hf, array_length(hf));
214 proto_register_subtree_array(ett, array_length(ett));
216 tcpencap_handle = register_dissector("tcpencap", dissect_tcpencap, proto_tcpencap);
219 void
220 proto_reg_handoff_tcpencap(void)
222 esp_handle = find_dissector_add_dependency("esp", proto_tcpencap);
223 udp_handle = find_dissector_add_dependency("udp", proto_tcpencap);
225 heur_dissector_add("tcp", dissect_tcpencap_heur, "TCP Encapsulation of IPsec Packets", "ipsec_tcp", proto_tcpencap, HEURISTIC_ENABLE);
227 /* Register TCP port for dissection */
228 dissector_add_for_decode_as_with_preference("tcp.port", tcpencap_handle);
232 * Editor modelines - https://www.wireshark.org/tools/modelines.html
234 * Local variables:
235 * c-basic-offset: 8
236 * tab-width: 8
237 * indent-tabs-mode: t
238 * End:
240 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
241 * :indentSize=8:tabSize=8:noTabs=false: