/src/wireshark/epan/dissectors/packet-omapi.c
Line | Count | Source |
1 | | /* packet-omapi.c |
2 | | * ISC OMAPI (Object Management API) dissector |
3 | | * Copyright 2006, Jaap Keuter <jaap.keuter@xs4all.nl> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* |
13 | | * From the description api+protocol. |
14 | | * All fields are 32 bit unless stated otherwise. |
15 | | * |
16 | | * On startup, each side sends a status message indicating what version |
17 | | * of the protocol they are speaking. The status message looks like this: |
18 | | * +---------+---------+ |
19 | | * | version | hlength | |
20 | | * +---------+---------+ |
21 | | * |
22 | | * The fixed-length header consists of: |
23 | | * +--------+----+--------+----+-----+---------+------------+------------+-----+ |
24 | | * | authid | op | handle | id | rid | authlen | msg values | obj values | sig | |
25 | | * +--------+----+--------+----+-----+---------+------v-----+-----v------+--v--+ |
26 | | * NOTE: real life capture shows order to be: authid, authlen, opcode, handle... |
27 | | * |
28 | | * The message and object values consists of: |
29 | | * +---------+------+----------+-------+ |
30 | | * | namelen | name | valuelen | value | |
31 | | * +---16b---+--v---+----------+---v---+ |
32 | | */ |
33 | | |
34 | | #include "config.h" |
35 | | |
36 | | #include <epan/packet.h> |
37 | | #include <epan/ptvcursor.h> |
38 | | |
39 | | void proto_register_omapi(void); |
40 | | void proto_reg_handoff_omapi(void); |
41 | | |
42 | | static dissector_handle_t omapi_handle; |
43 | | |
44 | | static int proto_omapi; |
45 | | static int hf_omapi_version; |
46 | | static int hf_omapi_hlength; |
47 | | static int hf_omapi_auth_id; |
48 | | static int hf_omapi_auth_len; |
49 | | static int hf_omapi_opcode; |
50 | | static int hf_omapi_handle; |
51 | | static int hf_omapi_id; |
52 | | static int hf_omapi_rid; |
53 | | static int hf_omapi_msg_name_len; /* 16bit */ |
54 | | static int hf_omapi_msg_name; |
55 | | static int hf_omapi_msg_value_len; |
56 | | static int hf_omapi_msg_value; |
57 | | static int hf_omapi_obj_name_len; /* 16bit */ |
58 | | static int hf_omapi_obj_name; |
59 | | static int hf_omapi_obj_value_len; |
60 | | static int hf_omapi_obj_value; |
61 | | static int hf_omapi_signature; |
62 | | |
63 | | /* Generated from convert_proto_tree_add_text.pl */ |
64 | | static int hf_omapi_empty_string; |
65 | | static int hf_omapi_object_end_tag; |
66 | | static int hf_omapi_message_end_tag; |
67 | | static int hf_omapi_no_value; |
68 | | |
69 | | static int ett_omapi; |
70 | | |
71 | 14 | #define OMAPI_PORT 7911 /* Not IANA registered */ |
72 | | |
73 | | #define OP_OPEN 1 |
74 | | #define OP_REFRESH 2 |
75 | | #define OP_UPDATE 3 |
76 | | #define OP_NOTIFY 4 |
77 | | #define OP_ERROR 5 |
78 | | #define OP_DELETE 6 |
79 | | #define OP_NOTIFY_CANCEL 7 |
80 | | #define OP_NOTIFY_CANCELLED 8 |
81 | | |
82 | | static const value_string omapi_opcode_vals[] = { |
83 | | { OP_OPEN, "Open" }, |
84 | | { OP_REFRESH, "Refresh" }, |
85 | | { OP_UPDATE, "Update" }, |
86 | | { OP_NOTIFY, "Notify" }, |
87 | | { OP_ERROR, "Error" }, |
88 | | { OP_DELETE, "Delete" }, |
89 | | { OP_NOTIFY_CANCEL, "Notify cancel" }, |
90 | | { OP_NOTIFY_CANCELLED, "Notify cancelled" }, |
91 | | { 0, NULL } |
92 | | }; |
93 | | |
94 | | static int |
95 | | dissect_omapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
96 | 13 | { |
97 | 13 | proto_item *ti; |
98 | 13 | proto_tree *omapi_tree; |
99 | 13 | ptvcursor_t *cursor; |
100 | | |
101 | 13 | uint32_t authlength; |
102 | 13 | uint32_t msglength; |
103 | 13 | uint32_t objlength; |
104 | 13 | char* str_opcode; |
105 | | |
106 | | /* Payload too small for OMAPI */ |
107 | 13 | if (tvb_reported_length_remaining(tvb, 0) < 8) |
108 | 1 | return 0; |
109 | | |
110 | 12 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "OMAPI"); |
111 | | |
112 | 12 | col_clear(pinfo->cinfo, COL_INFO); |
113 | | |
114 | 12 | ti = proto_tree_add_item(tree, proto_omapi, tvb, 0, -1, ENC_NA); |
115 | 12 | omapi_tree = proto_item_add_subtree(ti, ett_omapi); |
116 | 12 | cursor = ptvcursor_new(pinfo->pool, omapi_tree, tvb, 0); |
117 | | |
118 | 12 | if (tvb_reported_length_remaining(tvb, 0) < 24) |
119 | 1 | { |
120 | | /* This is a startup message */ |
121 | 1 | ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); |
122 | 1 | ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); |
123 | | |
124 | 1 | col_set_str(pinfo->cinfo, COL_INFO, "Status message"); |
125 | 1 | proto_item_append_text(ti, ", Status message"); |
126 | | |
127 | 1 | ptvcursor_free(cursor); |
128 | 1 | return 8; |
129 | 1 | } |
130 | 11 | else if ( !(tvb_get_ntohl(tvb, 8) || tvb_get_ntohl(tvb, 12)) ) |
131 | 2 | { |
132 | | /* This is a startup message, and more */ |
133 | 2 | ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); |
134 | 2 | ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); |
135 | | |
136 | 2 | col_append_str(pinfo->cinfo, COL_INFO, "Status message"); |
137 | | |
138 | 2 | proto_item_append_text(ti, ", Status message"); |
139 | 2 | } |
140 | | |
141 | 11 | ptvcursor_add(cursor, hf_omapi_auth_id, 4, ENC_BIG_ENDIAN); |
142 | 11 | authlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); |
143 | 11 | ptvcursor_add(cursor, hf_omapi_auth_len, 4, ENC_BIG_ENDIAN); |
144 | | |
145 | 11 | str_opcode = val_to_str(pinfo->pool, tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)"); |
146 | 11 | col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, str_opcode); |
147 | 11 | proto_item_append_text(ti, ", Opcode: %s", str_opcode); |
148 | | |
149 | 11 | ptvcursor_add(cursor, hf_omapi_opcode, 4, ENC_BIG_ENDIAN); |
150 | 11 | ptvcursor_add(cursor, hf_omapi_handle, 4, ENC_BIG_ENDIAN); |
151 | 11 | ptvcursor_add(cursor, hf_omapi_id, 4, ENC_BIG_ENDIAN); |
152 | 11 | ptvcursor_add(cursor, hf_omapi_rid, 4, ENC_BIG_ENDIAN); |
153 | | |
154 | 11 | msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); |
155 | 17 | while (msglength) |
156 | 6 | { |
157 | 6 | ptvcursor_add(cursor, hf_omapi_msg_name_len, 2, ENC_BIG_ENDIAN); |
158 | 6 | ptvcursor_add(cursor, hf_omapi_msg_name, msglength, ENC_ASCII); |
159 | 6 | msglength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); |
160 | 6 | ptvcursor_add(cursor, hf_omapi_msg_value_len, 4, ENC_BIG_ENDIAN); |
161 | | |
162 | 6 | if (msglength == 0) |
163 | 1 | { |
164 | 1 | proto_tree_add_item(omapi_tree, hf_omapi_empty_string, tvb, 0, 0, ENC_NA); |
165 | 1 | } |
166 | 5 | else if (msglength == (uint32_t)~0) |
167 | 1 | { |
168 | 1 | proto_tree_add_item(omapi_tree, hf_omapi_no_value, tvb, 0, 0, ENC_NA); |
169 | 1 | } |
170 | 4 | else |
171 | 4 | { |
172 | 4 | ptvcursor_add(cursor, hf_omapi_msg_value, msglength, ENC_ASCII); |
173 | 4 | } |
174 | | |
175 | 6 | msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); |
176 | 6 | } |
177 | | |
178 | 11 | ptvcursor_add(cursor, hf_omapi_message_end_tag, 2, ENC_NA); |
179 | | |
180 | 11 | objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); |
181 | 16 | while (objlength) |
182 | 5 | { |
183 | 5 | ptvcursor_add(cursor, hf_omapi_obj_name_len, 2, ENC_BIG_ENDIAN); |
184 | 5 | ptvcursor_add(cursor, hf_omapi_obj_name, objlength, ENC_ASCII); |
185 | 5 | objlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); |
186 | 5 | ptvcursor_add(cursor, hf_omapi_obj_value_len, 4, ENC_BIG_ENDIAN); |
187 | | |
188 | 5 | if (objlength == 0) |
189 | 1 | { |
190 | 1 | proto_tree_add_item(omapi_tree, hf_omapi_empty_string, tvb, 0, 0, ENC_NA); |
191 | 1 | } |
192 | 4 | else if (objlength == (uint32_t)~0) |
193 | 0 | { |
194 | 0 | proto_tree_add_item(omapi_tree, hf_omapi_no_value, tvb, 0, 0, ENC_NA); |
195 | 0 | } |
196 | 4 | else |
197 | 4 | { |
198 | 4 | ptvcursor_add(cursor, hf_omapi_obj_value, objlength, ENC_NA); |
199 | 4 | } |
200 | | |
201 | 5 | objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); |
202 | 5 | } |
203 | | |
204 | 11 | ptvcursor_add(cursor, hf_omapi_object_end_tag, 2, ENC_NA); |
205 | | |
206 | 11 | if (authlength > 0) { |
207 | 2 | ptvcursor_add(cursor, hf_omapi_signature, authlength, ENC_NA); |
208 | 2 | } |
209 | | |
210 | 11 | ptvcursor_free(cursor); |
211 | 11 | return tvb_captured_length(tvb); |
212 | 12 | } |
213 | | |
214 | | void |
215 | | proto_register_omapi(void) |
216 | 14 | { |
217 | 14 | static hf_register_info hf[] = { |
218 | 14 | { &hf_omapi_version, |
219 | 14 | { "Version", "omapi.version", |
220 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
221 | 14 | NULL, HFILL }}, |
222 | 14 | { &hf_omapi_hlength, |
223 | 14 | { "Header length", "omapi.hlength", |
224 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
225 | 14 | NULL, HFILL }}, |
226 | 14 | { &hf_omapi_auth_id, |
227 | 14 | { "Authentication ID", "omapi.authid", |
228 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
229 | 14 | NULL, HFILL }}, |
230 | 14 | { &hf_omapi_auth_len, |
231 | 14 | { "Authentication length", "omapi.authlength", |
232 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
233 | 14 | NULL, HFILL }}, |
234 | 14 | { &hf_omapi_opcode, |
235 | 14 | { "Opcode", "omapi.opcode", |
236 | 14 | FT_UINT32, BASE_DEC, VALS(omapi_opcode_vals), 0x0, |
237 | 14 | NULL, HFILL }}, |
238 | 14 | { &hf_omapi_handle, |
239 | 14 | { "Handle", "omapi.handle", |
240 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
241 | 14 | NULL, HFILL }}, |
242 | 14 | { &hf_omapi_id, |
243 | 14 | { "ID", "omapi.id", |
244 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
245 | 14 | NULL, HFILL }}, |
246 | 14 | { &hf_omapi_rid, |
247 | 14 | { "Response ID", "omapi.rid", |
248 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
249 | 14 | NULL, HFILL }}, |
250 | 14 | { &hf_omapi_msg_name_len, |
251 | 14 | { "Message name length", "omapi.msg_name_length", |
252 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
253 | 14 | NULL, HFILL }}, |
254 | 14 | { &hf_omapi_msg_name, |
255 | 14 | { "Message name", "omapi.msg_name", |
256 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
257 | 14 | NULL, HFILL }}, |
258 | 14 | { &hf_omapi_msg_value_len, |
259 | 14 | { "Message value length", "omapi.msg_value_length", |
260 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
261 | 14 | NULL, HFILL }}, |
262 | 14 | { &hf_omapi_msg_value, |
263 | 14 | { "Message value", "omapi.msg_value", |
264 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
265 | 14 | NULL, HFILL }}, |
266 | 14 | { &hf_omapi_obj_name_len, |
267 | 14 | { "Object name length", "omapi.obj_name_length", |
268 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
269 | 14 | NULL, HFILL }}, |
270 | 14 | { &hf_omapi_obj_name, |
271 | 14 | { "Object name", "omapi.obj_name", |
272 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
273 | 14 | NULL, HFILL }}, |
274 | 14 | { &hf_omapi_obj_value_len, |
275 | 14 | { "Object value length", "omapi.object_value_length", |
276 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
277 | 14 | NULL, HFILL }}, |
278 | 14 | { &hf_omapi_obj_value, |
279 | 14 | { "Object value", "omapi.obj_value", |
280 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
281 | 14 | NULL, HFILL }}, |
282 | 14 | { &hf_omapi_signature, |
283 | 14 | { "Signature", "omapi.signature", |
284 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
285 | 14 | NULL, HFILL }}, |
286 | | |
287 | | /* Generated from convert_proto_tree_add_text.pl */ |
288 | 14 | { &hf_omapi_empty_string, { "Empty string", "omapi.empty_string", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
289 | 14 | { &hf_omapi_no_value, { "No value", "omapi.no_value", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
290 | 14 | { &hf_omapi_message_end_tag, { "Message end tag", "omapi.message_end_tag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
291 | 14 | { &hf_omapi_object_end_tag, { "Object end tag", "omapi.object_end_tag", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
292 | | |
293 | 14 | }; |
294 | | |
295 | 14 | static int *ett[] = { |
296 | 14 | &ett_omapi |
297 | 14 | }; |
298 | | |
299 | 14 | proto_omapi = proto_register_protocol("ISC Object Management API", "OMAPI", "omapi"); |
300 | 14 | proto_register_field_array(proto_omapi, hf, array_length(hf)); |
301 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
302 | | |
303 | 14 | omapi_handle = register_dissector("omapi", dissect_omapi, proto_omapi); |
304 | 14 | } |
305 | | |
306 | | void |
307 | | proto_reg_handoff_omapi(void) |
308 | 14 | { |
309 | 14 | dissector_add_uint_with_preference("tcp.port", OMAPI_PORT, omapi_handle); |
310 | 14 | } |
311 | | |
312 | | /* |
313 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
314 | | * |
315 | | * Local Variables: |
316 | | * c-basic-offset: 2 |
317 | | * tab-width: 8 |
318 | | * indent-tabs-mode: nil |
319 | | * End: |
320 | | * |
321 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
322 | | * :indentSize=2:tabSize=8:noTabs=true: |
323 | | */ |