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
15 #include <epan/packet.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
[] = {
57 dissect_interlink(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
62 proto_tree
*ilh_tree
= NULL
;
63 proto_tree
*ilb_tree
= NULL
;
66 uint16_t type_version
= 0;
67 dissector_handle_t handle
;
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
,
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");
80 proto_tree_add_item(ilh_tree
, hf_interlink_id
, tvb
, offset
, 4, ENC_ASCII
);
82 proto_tree_add_item(ilh_tree
, hf_interlink_version
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
84 proto_tree_add_item(ilh_tree
, hf_interlink_cmd
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
86 proto_tree_add_item(ilh_tree
, hf_interlink_seq
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
93 static int * const flags
[] = {
94 &hf_interlink_flags_req_ack
,
95 &hf_interlink_flags_inc_ack_port
,
99 proto_tree_add_bitmask(ilh_tree
, tvb
, offset
, hf_interlink_flags
, ett_interlink_flags
, flags
, ENC_LITTLE_ENDIAN
);
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
);
113 proto_tree_add_item(ilb_tree
, hf_interlink_block_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
115 proto_tree_add_item(ilb_tree
, hf_interlink_block_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
117 proto_tree_add_item(ilb_tree
, hf_interlink_block_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
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
);
140 dissect_interlink_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
142 if (!tvb_bytes_exist(tvb
, 0, 4)) {
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'
153 dissect_interlink(tvb
, pinfo
, tree
, data
);
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
[] = {
196 &ett_interlink_header
,
197 &ett_interlink_flags
,
198 &ett_interlink_block
,
201 proto_interlink
= proto_register_protocol("Interlink Protocol",
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
);
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
232 * indent-tabs-mode: t
235 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
236 * :indentSize=8:tabSize=8:noTabs=false: