Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-interlink.c
blob23f6c496830f49409c91fc82b6072e5fc2d8fd01
1 /* packet-interlink.c
2 * Routines for Interlink protocol packet disassembly
3 * By Uwe Girlich <uwe.girlich@philosys.de>
4 * Copyright 2010 Uwe Girlich
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 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/tfs.h>
17 #include <wsutil/array.h>
19 void proto_register_interlink(void);
20 void proto_reg_handoff_interlink(void);
23 * No public information available.
26 static int proto_interlink;
28 static int hf_interlink_id;
29 static int hf_interlink_version;
30 static int hf_interlink_cmd;
31 static int hf_interlink_seq;
32 static int hf_interlink_flags;
33 static int hf_interlink_flags_req_ack;
34 static int hf_interlink_flags_inc_ack_port;
35 static int hf_interlink_block_type;
36 static int hf_interlink_block_version;
37 static int hf_interlink_block_length;
39 static int ett_interlink;
40 static int ett_interlink_header;
41 static int ett_interlink_flags;
42 static int ett_interlink_block;
44 static dissector_handle_t data_handle;
45 static dissector_table_t subdissector_table;
46 static dissector_handle_t interlink_handle;
49 static const value_string names_cmd[] = {
50 { 1, "Data" },
51 { 2, "Ack" },
52 { 0, NULL }
56 static int
57 dissect_interlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
59 int offset = 0;
60 proto_tree *il_tree;
61 proto_item *il_item;
62 proto_tree *ilh_tree = NULL;
63 proto_tree *ilb_tree = NULL;
64 uint8_t ilb_type;
65 uint8_t ilb_version;
66 uint16_t type_version = 0;
67 dissector_handle_t handle;
68 tvbuff_t *next_tvb;
70 col_set_str(pinfo->cinfo, COL_PROTOCOL, "INTERLINK");
71 col_clear(pinfo->cinfo, COL_INFO);
73 il_item = proto_tree_add_item(tree, proto_interlink,
74 tvb, 0, 16, ENC_NA);
75 il_tree = proto_item_add_subtree(il_item, ett_interlink);
77 ilh_tree = proto_tree_add_subtree(il_tree, tvb, 0, 12, ett_interlink_header, NULL, "Interlink Header");
79 if (ilh_tree) {
80 proto_tree_add_item(ilh_tree, hf_interlink_id, tvb, offset, 4, ENC_ASCII);
81 offset += 4;
82 proto_tree_add_item(ilh_tree, hf_interlink_version, tvb, offset, 2, ENC_LITTLE_ENDIAN);
83 offset += 2;
84 proto_tree_add_item(ilh_tree, hf_interlink_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
85 offset += 2;
86 proto_tree_add_item(ilh_tree, hf_interlink_seq, tvb, offset, 2, ENC_LITTLE_ENDIAN);
87 offset += 2;
88 } else {
89 offset += 10;
92 if (ilh_tree) {
93 static int * const flags[] = {
94 &hf_interlink_flags_req_ack,
95 &hf_interlink_flags_inc_ack_port,
96 NULL
99 proto_tree_add_bitmask(ilh_tree, tvb, offset, hf_interlink_flags, ett_interlink_flags, flags, ENC_LITTLE_ENDIAN);
102 offset += 2;
104 ilb_tree = proto_tree_add_subtree(il_tree, tvb, offset, 4, ett_interlink_block, NULL, "Block Header");
106 ilb_type = tvb_get_uint8(tvb, offset);
107 ilb_version = tvb_get_uint8(tvb, offset + 1);
108 type_version = ilb_type << 8 | ilb_version;
109 col_append_fstr(pinfo->cinfo, COL_INFO, "Type: %d, Version: %d",
110 ilb_type, ilb_version);
112 if (ilb_tree) {
113 proto_tree_add_item(ilb_tree, hf_interlink_block_type, tvb, offset, 1, ENC_BIG_ENDIAN);
114 offset += 1;
115 proto_tree_add_item(ilb_tree, hf_interlink_block_version, tvb, offset, 1, ENC_BIG_ENDIAN);
116 offset += 1;
117 proto_tree_add_item(ilb_tree, hf_interlink_block_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
118 offset += 2;
119 } else {
120 offset += 4;
123 /* Generate a new tvb for the rest. */
124 next_tvb = tvb_new_subset_remaining(tvb, offset);
126 /* Probably a sub-dissector exists for this type/version combination. */
127 handle = dissector_get_uint_handle(subdissector_table, type_version);
129 /* Without a proper sub-dissector, we use "data". */
130 if (handle == NULL) handle = data_handle;
132 /* Call the sub-dissector. */
133 call_dissector(handle, next_tvb, pinfo, tree);
135 return tvb_captured_length(tvb);
139 static bool
140 dissect_interlink_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
142 if (!tvb_bytes_exist(tvb, 0, 4)) {
143 return false;
145 if (
146 tvb_get_uint8(tvb,0) != 'I' ||
147 tvb_get_uint8(tvb,1) != 'L' ||
148 tvb_get_uint8(tvb,2) != 'N' ||
149 tvb_get_uint8(tvb,3) != 'K'
151 return false;
153 dissect_interlink(tvb, pinfo, tree, data);
154 return true;
158 void
159 proto_register_interlink(void)
161 static hf_register_info hf[] = {
162 { &hf_interlink_id, {
163 "Magic ID", "interlink.id", FT_STRING,
164 BASE_NONE, NULL, 0, NULL, HFILL }},
165 { &hf_interlink_version, {
166 "Version", "interlink.version", FT_UINT16,
167 BASE_DEC, NULL, 0, NULL, HFILL }},
168 { &hf_interlink_cmd, {
169 "Command", "interlink.cmd", FT_UINT16,
170 BASE_DEC, VALS(names_cmd), 0, NULL, HFILL }},
171 { &hf_interlink_seq, {
172 "Sequence", "interlink.seq", FT_UINT16,
173 BASE_DEC, NULL, 0, NULL, HFILL }},
174 { &hf_interlink_flags, {
175 "Flags", "interlink.flags", FT_UINT16,
176 BASE_HEX, NULL, 0, NULL, HFILL }},
177 { &hf_interlink_flags_req_ack, {
178 "REQ_ACK", "interlink.flags.req_ack", FT_BOOLEAN,
179 16, TFS(&tfs_set_notset), 0x0001, NULL, HFILL }},
180 { &hf_interlink_flags_inc_ack_port, {
181 "INC_ACK_PORT", "interlink.flags.inc_ack_port", FT_BOOLEAN,
182 16, TFS(&tfs_set_notset), 0x0002, NULL, HFILL }},
183 { &hf_interlink_block_type, {
184 "Type", "interlink.type", FT_UINT8,
185 BASE_DEC, NULL, 0, NULL, HFILL }},
186 { &hf_interlink_block_version, {
187 "Version", "interlink.block_version", FT_UINT8,
188 BASE_DEC, NULL, 0, NULL, HFILL }},
189 { &hf_interlink_block_length, {
190 "Length", "interlink.length", FT_UINT16,
191 BASE_DEC, NULL, 0, NULL, HFILL }},
194 static int *ett[] = {
195 &ett_interlink,
196 &ett_interlink_header,
197 &ett_interlink_flags,
198 &ett_interlink_block,
201 proto_interlink = proto_register_protocol("Interlink Protocol",
202 "Interlink",
203 "interlink");
204 proto_register_field_array(proto_interlink, hf, array_length(hf));
205 proto_register_subtree_array(ett, array_length(ett));
206 interlink_handle = register_dissector("interlink", dissect_interlink, proto_interlink);
208 /* Probably someone will write sub-dissectors. You can never know. */
209 subdissector_table = register_dissector_table("interlink.type_version",
210 "Interlink type_version", proto_interlink, FT_UINT16, BASE_HEX);
214 void
215 proto_reg_handoff_interlink(void)
217 /* Allow "Decode As" with any UDP packet. */
218 dissector_add_for_decode_as_with_preference("udp.port", interlink_handle);
220 /* Add our heuristic packet finder. */
221 heur_dissector_add("udp", dissect_interlink_heur, "Interlink over UDP", "interlink_udp", proto_interlink, HEURISTIC_ENABLE);
223 data_handle = find_dissector("data");
227 * Editor modelines - https://www.wireshark.org/tools/modelines.html
229 * Local variables:
230 * c-basic-offset: 8
231 * tab-width: 8
232 * indent-tabs-mode: t
233 * End:
235 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
236 * :indentSize=8:tabSize=8:noTabs=false: