Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-fortinet-fgcp.c
blob0187259eeeb2f1d5022d723d90301bfeac81a6c0
1 /* packet-fortinet-fgcp.c
2 * Routines for FortiGate Cluster Protocol dissection
3 * Copyright 2023, Alexis La Goutte <alexis.lagoutte at gmail dot com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
11 * No spec/doc is available based on reverse/analysis of protocol...
15 #include "config.h"
17 #include <wireshark.h>
19 #include <epan/packet.h>
20 #include <epan/expert.h>
21 #include <epan/prefs.h>
22 #include <epan/etypes.h>
24 void proto_reg_handoff_fortinet_fgcp(void);
25 void proto_register_fortinet_fgcp(void);
27 static int proto_fortinet_fgcp_hb;
28 static int hf_fortinet_fgcp_hb_magic;
29 static int hf_fortinet_fgcp_hb_flag;
30 static int hf_fortinet_fgcp_hb_flag_b74;
31 static int hf_fortinet_fgcp_hb_flag_b3;
32 static int hf_fortinet_fgcp_hb_flag_b2;
33 static int hf_fortinet_fgcp_hb_flag_authentication;
34 static int hf_fortinet_fgcp_hb_flag_encryption;
35 static int hf_fortinet_fgcp_hb_mode;
36 static int hf_fortinet_fgcp_hb_gn;
37 static int hf_fortinet_fgcp_hb_group_id;
38 static int hf_fortinet_fgcp_hb_port;
39 static int hf_fortinet_fgcp_hb_revision;
40 static int hf_fortinet_fgcp_hb_sn;
41 static int hf_fortinet_fgcp_hb_payload_encrypted;
42 static int hf_fortinet_fgcp_hb_authentication;
44 static int hf_fortinet_fgcp_hb_tlv;
45 static int hf_fortinet_fgcp_hb_tlv_type;
46 static int hf_fortinet_fgcp_hb_tlv_length;
47 static int hf_fortinet_fgcp_hb_tlv_value;
48 static int hf_fortinet_fgcp_hb_tlv_vcluster_id;
49 static int hf_fortinet_fgcp_hb_tlv_priority;
50 static int hf_fortinet_fgcp_hb_tlv_override;
52 //static int hf_fortinet_fgcp_hb_unknown;
53 static int hf_fortinet_fgcp_hb_unknown_uint16;
55 static dissector_handle_t fortinet_fgcp_hb_handle;
57 static int ett_fortinet_fgcp_hb;
58 static int ett_fortinet_fgcp_hb_flag;
59 static int ett_fortinet_fgcp_hb_tlv;
61 static int proto_fortinet_fgcp_session;
62 static int hf_fortinet_fgcp_session_magic;
63 static int hf_fortinet_fgcp_session_type;
65 static dissector_handle_t fortinet_fgcp_session_handle;
66 static dissector_handle_t ip_handle;
68 static int ett_fortinet_fgcp_session;
70 static const value_string fortinet_fgcp_hb_mode_vals[] = {
71 { 0x1, "A/A (Active/Active)"},
72 { 0x2, "A/P (Active/Passive)"},
73 {0, NULL }
76 #define HB_TLV_END_OF_TLV 0x00
77 #define HB_TLV_VCLUSTER_ID 0x0B
78 #define HB_TLV_PRIORITY 0x0C
79 #define HB_TLV_OVERRIDE 0x0D
81 static const value_string fortinet_fgcp_hb_tlv_vals[] = {
82 { HB_TLV_END_OF_TLV, "End of TLV" },
83 { HB_TLV_PRIORITY, "Port Priority" },
84 { HB_TLV_OVERRIDE, "Override" },
85 { 0, NULL }
89 static int
90 dissect_fortinet_fgcp_hb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
91 void *data _U_)
93 proto_item *ti;
94 proto_tree *fortinet_hb_tree;
95 unsigned offset = 0, length, auth_len=0;
96 uint8_t flags;
98 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FGCP-HB");
100 col_add_fstr(pinfo->cinfo, COL_INFO, "Cluster: %s(%u) - monitor: %s - SN: %s",
101 tvb_get_string_enc(pinfo->pool, tvb, offset+4, 32, ENC_ASCII), /* Group Name*/
102 tvb_get_uint16(tvb, (offset+4+32+2), ENC_LITTLE_ENDIAN), /* Group ID*/
103 tvb_get_string_enc(pinfo->pool, tvb, offset+4+32+2+14, 16, ENC_ASCII), /* Port */
104 tvb_get_string_enc(pinfo->pool, tvb, offset+4+32+2+14+16+2+2, 16, ENC_ASCII) /* Serial Number */);
106 ti = proto_tree_add_item(tree, proto_fortinet_fgcp_hb, tvb, 0, -1, ENC_NA);
108 fortinet_hb_tree = proto_item_add_subtree(ti, ett_fortinet_fgcp_hb);
110 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_magic, tvb, offset, 2, ENC_LITTLE_ENDIAN);
111 offset += 2;
113 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_mode, tvb, offset, 1, ENC_NA);
114 offset += 1;
116 static int * const fortinet_fgcp_hb_flag[] = {
117 &hf_fortinet_fgcp_hb_flag_b74,
118 &hf_fortinet_fgcp_hb_flag_b3,
119 &hf_fortinet_fgcp_hb_flag_b2,
120 &hf_fortinet_fgcp_hb_flag_authentication,
121 &hf_fortinet_fgcp_hb_flag_encryption,
122 NULL
125 proto_tree_add_bitmask(fortinet_hb_tree, tvb, offset, hf_fortinet_fgcp_hb_flag, ett_fortinet_fgcp_hb_flag,
126 fortinet_fgcp_hb_flag, ENC_NA);
127 flags = tvb_get_uint8(tvb, offset);
128 offset += 1;
130 /* Group Name */
131 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_gn, tvb, offset, 32, ENC_ASCII);
132 offset += 32;
134 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
135 offset += 2;
137 /* Group Id */
138 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_group_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
139 offset += 2;
141 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
142 offset += 2;
144 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
145 offset += 2;
147 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
148 offset += 2;
150 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
151 offset += 2;
153 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
154 offset += 2;
156 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
157 offset += 2;
159 /* Heartbeat Port */
160 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_port, tvb, offset, 16, ENC_ASCII);
161 offset += 16;
163 /* Revision ? */
164 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_revision, tvb, offset, 2, ENC_LITTLE_ENDIAN);
165 offset += 2;
167 /* Hash/crc ? change after each revision*/
168 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_unknown_uint16, tvb, offset, 2, ENC_NA);
169 offset += 2;
171 /* Serial Number */
172 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_sn, tvb, offset, 16, ENC_ASCII);
173 offset += 16;
175 if (flags & 0x02) { /* Authentication ? */
176 /* the payload finish with 32bits of authentication (hash ?) */
177 auth_len = 32;
180 if (flags & 0x01) { /* Encrypted Payload ?*/
181 length = tvb_reported_length_remaining(tvb, offset) - auth_len;
182 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_payload_encrypted, tvb, offset, length, ENC_NA);
183 offset += length;
184 } else {
185 unsigned next_offset;
187 length = tvb_reported_length_remaining(tvb, offset) - auth_len;
188 next_offset = offset + length;
190 while (offset < next_offset) {
191 uint32_t type, len;
192 proto_item *ti_tlv;
193 proto_tree *tlv_tree;
195 ti_tlv = proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_tlv, tvb, offset, 3, ENC_NA);
196 tlv_tree = proto_item_add_subtree(ti_tlv, ett_fortinet_fgcp_hb_tlv);
197 proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, &type);
198 offset += 2;
199 proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &len);
200 offset += 2;
202 proto_item_append_text(ti_tlv, ": (t=%u,l=%d) %s", type, len, val_to_str_const(type, fortinet_fgcp_hb_tlv_vals ,"Unknown type") );
203 proto_item_set_len(ti_tlv, 2 + 2 + len);
205 proto_tree_add_item(tlv_tree, hf_fortinet_fgcp_hb_tlv_value, tvb, offset, len, ENC_NA);
206 switch (type) {
207 case HB_TLV_VCLUSTER_ID:{
208 uint32_t vcluster_id;
209 proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_vcluster_id, tvb, offset, 1, ENC_NA, &vcluster_id);
210 proto_item_append_text(ti_tlv, ": %u", vcluster_id);
211 offset += 1;
213 break;
214 case HB_TLV_PRIORITY:{
215 uint32_t priority;
216 proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_priority, tvb, offset, 1, ENC_NA, &priority);
217 proto_item_append_text(ti_tlv, ": %u", priority);
218 offset += 1;
220 break;
221 case HB_TLV_OVERRIDE:{
222 uint32_t override;
223 proto_tree_add_item_ret_uint(tlv_tree, hf_fortinet_fgcp_hb_tlv_override, tvb, offset, 1, ENC_NA, &override);
224 if (override){
225 proto_item_append_text(ti_tlv, ": True");
226 } else {
227 proto_item_append_text(ti_tlv, ": False");
229 offset += 1;
231 break;
232 default:
233 offset += len;
234 break;
239 if (auth_len) { /* Authentication ? */
240 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_hb_authentication, tvb, offset, 32, ENC_NA);
241 offset += 32;
244 return offset;
247 static int
248 dissect_fortinet_fgcp_session(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
249 void *data _U_)
251 proto_item *ti;
252 proto_tree *fortinet_hb_tree;
253 unsigned offset = 0;
254 tvbuff_t *data_tvb;
256 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FGCP-SESSION");
258 ti = proto_tree_add_item(tree, proto_fortinet_fgcp_session, tvb, 0, -1, ENC_NA);
260 fortinet_hb_tree = proto_item_add_subtree(ti, ett_fortinet_fgcp_session);
262 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_session_magic, tvb, offset, 2, ENC_LITTLE_ENDIAN);
263 offset += 2;
265 proto_tree_add_item(fortinet_hb_tree, hf_fortinet_fgcp_session_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
266 offset += 2;
268 data_tvb = tvb_new_subset_remaining(tvb, offset);
269 call_dissector(ip_handle, data_tvb, pinfo, tree);
271 return offset;
274 void
275 proto_register_fortinet_fgcp(void)
278 static hf_register_info hf[] = {
279 /* HeartBeat */
280 { &hf_fortinet_fgcp_hb_magic,
281 { "Magic Number", "fortinet_fgcp.hb.magic",
282 FT_UINT16, BASE_HEX_DEC, NULL, 0x0,
283 "Magic Number ?", HFILL }
285 { &hf_fortinet_fgcp_hb_flag,
286 { "Flag", "fortinet_fgcp.hb.flag",
287 FT_UINT8, BASE_HEX, NULL, 0x0,
288 NULL, HFILL }
290 { &hf_fortinet_fgcp_hb_flag_b74,
291 { "Bit 7 to 4", "fortinet_fgcp.hb.flag.b74",
292 FT_UINT8, BASE_HEX, NULL, 0xF0,
293 "Unknown", HFILL }
295 { &hf_fortinet_fgcp_hb_flag_b3,
296 { "Bit b3", "fortinet_fgcp.hb.flag.b3",
297 FT_UINT8, BASE_HEX, NULL, 0x08,
298 "Unknown", HFILL }
300 { &hf_fortinet_fgcp_hb_flag_b2,
301 { "Bit b2", "fortinet_fgcp.hb.flag.b2",
302 FT_UINT8, BASE_HEX, NULL, 0x04,
303 "Unknown", HFILL }
305 { &hf_fortinet_fgcp_hb_flag_authentication,
306 { "Authentication", "fortinet_fgcp.hb.flag.authentication",
307 FT_BOOLEAN, 8, NULL, 0x02,
308 NULL, HFILL }
310 { &hf_fortinet_fgcp_hb_flag_encryption,
311 { "Encryption", "fortinet_fgcp.hb.flag.encryption",
312 FT_BOOLEAN, 8, NULL, 0x01,
313 NULL, HFILL }
315 { &hf_fortinet_fgcp_hb_mode,
316 { "Mode", "fortinet_fgcp.hb.mode",
317 FT_UINT8, BASE_DEC, VALS(fortinet_fgcp_hb_mode_vals), 0x0,
318 NULL, HFILL }
320 { &hf_fortinet_fgcp_hb_gn,
321 { "Group Name", "fortinet_fgcp.hb.gn",
322 FT_STRING, BASE_NONE, NULL, 0x0,
323 NULL, HFILL }
325 { &hf_fortinet_fgcp_hb_group_id,
326 { "Group Id", "fortinet_fgcp.hb.group_id",
327 FT_UINT16, BASE_DEC, NULL, 0x0,
328 NULL, HFILL }
330 { &hf_fortinet_fgcp_hb_port,
331 { "Port", "fortinet_fgcp.hb.port",
332 FT_STRING, BASE_NONE, NULL, 0x0,
333 NULL, HFILL }
335 { &hf_fortinet_fgcp_hb_revision,
336 { "Revision", "fortinet_fgcp.hb.revision",
337 FT_UINT16, BASE_DEC, NULL, 0x0,
338 "Number of revision config for HA", HFILL }
340 { &hf_fortinet_fgcp_hb_sn,
341 { "Serial Number", "fortinet_fgcp.hb.sn",
342 FT_STRING, BASE_NONE, NULL, 0x0,
343 NULL, HFILL }
345 { &hf_fortinet_fgcp_hb_payload_encrypted,
346 { "Payload (encrypted)", "fortinet_fgcp.hb.payload_encrypted",
347 FT_BYTES, BASE_NONE, NULL, 0x0,
348 NULL, HFILL }
350 { &hf_fortinet_fgcp_hb_authentication,
351 { "Authentication", "fortinet_fgcp.hb.authentication",
352 FT_BYTES, BASE_NONE, NULL, 0x0,
353 NULL, HFILL }
356 { &hf_fortinet_fgcp_hb_tlv,
357 { "TLV", "fortinet_fgcp.hb.tlv",
358 FT_NONE, BASE_NONE, NULL, 0x0,
359 NULL, HFILL }
361 { &hf_fortinet_fgcp_hb_tlv_type,
362 { "Type", "fortinet_fgcp.hb.tlv.type",
363 FT_UINT16, BASE_HEX, VALS(fortinet_fgcp_hb_tlv_vals), 0x0,
364 NULL, HFILL }
366 { &hf_fortinet_fgcp_hb_tlv_length,
367 { "Length", "fortinet_fgcp.hb.tlv.length",
368 FT_UINT16, BASE_DEC, NULL, 0x0,
369 NULL, HFILL }
371 { &hf_fortinet_fgcp_hb_tlv_value,
372 { "Value", "fortinet_fgcp.hb.tlv.value",
373 FT_BYTES, BASE_NONE, NULL, 0x0,
374 NULL, HFILL }
377 { &hf_fortinet_fgcp_hb_tlv_vcluster_id,
378 { "Vcluster ID", "fortinet_fgcp.hb.tlv.vcluster_id",
379 FT_UINT8, BASE_DEC, NULL, 0x0,
380 NULL, HFILL }
382 { &hf_fortinet_fgcp_hb_tlv_priority,
383 { "Port Priority", "fortinet_fgcp.hb.tlv.priority",
384 FT_UINT8, BASE_DEC, NULL, 0x0,
385 NULL, HFILL }
387 { &hf_fortinet_fgcp_hb_tlv_override,
388 { "Override", "fortinet_fgcp.hb.tlv.override",
389 FT_UINT8, BASE_DEC, NULL, 0x0,
390 NULL, HFILL }
393 { &hf_fortinet_fgcp_hb_unknown,
394 { "Unknown", "fortinet_fgcp.hb.unknown",
395 FT_BYTES, BASE_NONE, NULL, 0x0,
396 "Always NULL ?", HFILL }
399 { &hf_fortinet_fgcp_hb_unknown_uint16,
400 { "Unknown", "fortinet_fgcp.hb.unknown.uint16",
401 FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
402 NULL, HFILL }
405 /* Session */
406 { &hf_fortinet_fgcp_session_magic,
407 { "Magic Number", "fortinet_fgcp.session.magic",
408 FT_UINT16, BASE_HEX_DEC, NULL, 0x0,
409 "Magic Number ?", HFILL }
411 { &hf_fortinet_fgcp_session_type,
412 { "Type", "fortinet_fgcp.session.type",
413 FT_UINT16, BASE_HEX, NULL, 0x0,
414 NULL, HFILL }
418 /* Setup protocol subtree array */
419 static int *ett[] = {
420 &ett_fortinet_fgcp_hb,
421 &ett_fortinet_fgcp_hb_flag,
422 &ett_fortinet_fgcp_hb_tlv,
423 &ett_fortinet_fgcp_session,
426 /* Register the protocol name and description */
427 proto_fortinet_fgcp_hb = proto_register_protocol("FortiGate Cluster Protocol - HeartBeat",
428 "fortinet_fgcp_hb", "fortinet_fgcp_hb");
430 proto_fortinet_fgcp_session = proto_register_protocol("FortiGate Cluster Protocol - Session",
431 "fortinet_fgcp_session", "fortinet_fgcp_session");
433 /* Required function calls to register the header fields and subtrees */
434 proto_register_field_array(proto_fortinet_fgcp_hb, hf, array_length(hf));
435 proto_register_subtree_array(ett, array_length(ett));
437 fortinet_fgcp_hb_handle = register_dissector("fortinet_fgcp_hb", dissect_fortinet_fgcp_hb,
438 proto_fortinet_fgcp_hb);
440 fortinet_fgcp_session_handle = register_dissector("fortinet_fgcp_session", dissect_fortinet_fgcp_session,
441 proto_fortinet_fgcp_session);
446 void
447 proto_reg_handoff_fortinet_fgcp(void)
449 dissector_add_uint("ethertype", ETHERTYPE_FORTINET_FGCP_HB, fortinet_fgcp_hb_handle);
450 dissector_add_uint("ethertype", ETHERTYPE_FORTINET_FGCP_SESSION, fortinet_fgcp_session_handle);
452 ip_handle = find_dissector_add_dependency("ip", proto_fortinet_fgcp_session);
456 * Editor modelines - https://www.wireshark.org/tools/modelines.html
458 * Local variables:
459 * c-basic-offset: 4
460 * tab-width: 8
461 * indent-tabs-mode: nil
462 * End:
464 * vi: set shiftwidth=4 tabstop=8 expandtab:
465 * :indentSize=4:tabSize=8:noTabs=true: