Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-clique-rm.c
bloba95e87b250a7b8bff171ec6b1da1a0415fb930ff
1 /* packet-clique_rm.c
2 * Routines for clique reliable multicast dissector
3 * Copyright 2007, Collabora Ltd.
4 * @author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
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>
17 void proto_register_clique_rm(void);
18 void proto_reg_handoff_clique_rm(void);
20 /* Initialize the protocol and registered fields */
21 static int proto_clique_rm;
23 static int hf_clique_rm_version;
24 static int hf_clique_rm_type;
25 static int hf_clique_rm_sender;
26 static int hf_clique_rm_packet_id;
27 static int hf_clique_rm_depends;
28 static int hf_clique_rm_depend_sender;
29 static int hf_clique_rm_depend_packet_id;
30 static int hf_clique_rm_failures;
31 static int hf_clique_rm_failures_senders;
32 static int hf_clique_rm_attempt_join;
33 static int hf_clique_rm_attempt_join_senders;
34 static int hf_clique_rm_join_failures;
35 static int hf_clique_rm_join_failures_senders;
36 static int hf_clique_rm_data_flags;
37 static int hf_clique_rm_data_size;
38 static int hf_clique_rm_data_stream_id;
39 static int hf_clique_rm_data_data;
40 static int hf_clique_rm_whois_request_id;
41 static int hf_clique_rm_whois_reply_name;
42 static int hf_clique_rm_whois_reply_name_length;
43 static int hf_clique_rm_repair_request_sender_id;
44 static int hf_clique_rm_repair_request_packet_id;
46 /* Initialize the subtree pointers */
47 static int ett_clique_rm;
48 static int ett_clique_rm_data;
49 static int ett_clique_rm_depends;
50 static int ett_clique_rm_depends_item;
51 static int ett_clique_rm_failures;
52 static int ett_clique_rm_join_failures;
53 static int ett_clique_rm_attempt_join;
54 static int ett_clique_rm_join;
56 /* Packet types */
57 typedef enum {
58 /* Unreliable packets */
59 PACKET_TYPE_WHOIS_REQUEST = 0,
60 PACKET_TYPE_WHOIS_REPLY,
61 PACKET_TYPE_REPAIR_REQUEST,
62 PACKET_TYPE_SESSION,
63 /* Reliable packets */
64 FIRST_RELIABLE_PACKET = 0xf,
65 PACKET_TYPE_DATA = FIRST_RELIABLE_PACKET,
66 /* No data just acknowledgement */
67 PACKET_TYPE_NO_DATA,
68 /* Some nodes failed */
69 PACKET_TYPE_FAILURE,
70 /* Start a joining attempt */
71 PACKET_TYPE_ATTEMPT_JOIN,
72 /* The real join */
73 PACKET_TYPE_JOIN,
74 /* Leaving now, bye */
75 PACKET_TYPE_BYE,
76 PACKET_TYPE_INVALID
77 } GibberRMulticastPacketType;
79 #define IS_RELIABLE(type) (type >= FIRST_RELIABLE_PACKET)
81 static const value_string packet_type_vals[] = {
82 { PACKET_TYPE_WHOIS_REQUEST, "Whois request" },
83 { PACKET_TYPE_WHOIS_REPLY, "Whois reply" },
84 { PACKET_TYPE_REPAIR_REQUEST, "Repair request"},
85 { PACKET_TYPE_SESSION, "Session" },
86 { PACKET_TYPE_DATA, "Data" },
87 /* No data just acknowledgement */
88 { PACKET_TYPE_NO_DATA, "No data" },
89 /* Some nodes failed */
90 { PACKET_TYPE_FAILURE, "Failure" },
91 /* Start a joining attempt */
92 { PACKET_TYPE_ATTEMPT_JOIN, "Attempt join" },
93 /* The real join */
94 { PACKET_TYPE_JOIN, "Join" },
95 /* Leaving now, bye */
96 { PACKET_TYPE_BYE, "Bye" },
98 { 0, NULL }
101 static void
102 dissect_sender_array(proto_tree *clique_rm_tree, int hf_header, int ett_header,
103 int hf_header_sender, tvbuff_t *tvb, int offset)
105 unsigned i, count;
106 int len;
107 proto_item *ti;
108 proto_tree *tree;
111 count = tvb_get_uint8(tvb, offset);
112 len = 1 + 4 * count;
113 ti = proto_tree_add_item(clique_rm_tree, hf_header, tvb, offset, 1, ENC_BIG_ENDIAN);
114 proto_item_set_len(ti, len);
115 tree = proto_item_add_subtree(ti, ett_header);
116 offset++;
118 for (i = 0; i < count; i++, offset += 4)
119 proto_tree_add_item(tree, hf_header_sender, tvb, offset, 4, ENC_BIG_ENDIAN);
122 static void
123 dissect_data_packet(proto_tree *clique_rm_tree, tvbuff_t *tvb, int offset)
125 proto_tree *tree;
127 tree = proto_tree_add_subtree(clique_rm_tree, tvb, offset, -1, ett_clique_rm_data, NULL, "Data");
129 proto_tree_add_item(tree, hf_clique_rm_data_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
130 offset += 1;
132 proto_tree_add_item(tree, hf_clique_rm_data_stream_id, tvb, offset, 2,
133 ENC_BIG_ENDIAN);
134 offset += 2;
136 proto_tree_add_item(tree, hf_clique_rm_data_size, tvb, offset, 4, ENC_BIG_ENDIAN);
137 offset += 4;
140 proto_tree_add_item(tree, hf_clique_rm_data_data, tvb, offset, -1, ENC_NA);
143 static int
144 dissect_depends(proto_tree *clique_rm_tree, tvbuff_t *tvb, int offset)
146 proto_item *ti;
147 proto_tree *tree, *depend_tree;
148 unsigned ii, count;
149 int len;
151 count = tvb_get_uint8(tvb, offset);
152 len = 1 + count * 8;
154 ti = proto_tree_add_item(clique_rm_tree,
155 hf_clique_rm_depends, tvb, offset, 1, ENC_BIG_ENDIAN);
156 proto_item_set_len(ti, len);
157 offset += 1;
159 tree = proto_item_add_subtree(ti, ett_clique_rm_depends);
160 for (ii = 0; ii < count; ii++)
162 depend_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8,
163 ett_clique_rm_depends_item, NULL, "Depend item %d", ii+1);
165 proto_tree_add_item(depend_tree, hf_clique_rm_depend_sender,
166 tvb, offset, 4, ENC_BIG_ENDIAN);
167 proto_tree_add_item(depend_tree, hf_clique_rm_depend_packet_id,
168 tvb, offset+4, 4, ENC_BIG_ENDIAN);
169 offset += 8;
172 return len;
175 /* Code to actually dissect the packets */
176 static void
177 dissect_reliable_packet(proto_tree *clique_rm_tree, uint8_t type, tvbuff_t *tvb, int offset)
179 if (!clique_rm_tree)
180 return; /* no col_..() or expert...() calls in following */
182 proto_tree_add_item(clique_rm_tree, hf_clique_rm_packet_id, tvb, offset, 4,
183 ENC_BIG_ENDIAN);
184 offset += 4;
186 offset += dissect_depends(clique_rm_tree, tvb, offset);
188 switch (type)
190 case PACKET_TYPE_DATA:
191 dissect_data_packet(clique_rm_tree, tvb, offset);
192 break;
193 case PACKET_TYPE_NO_DATA:
194 break;
195 case PACKET_TYPE_FAILURE:
196 dissect_sender_array(clique_rm_tree, hf_clique_rm_failures,
197 ett_clique_rm_failures, hf_clique_rm_failures_senders, tvb, offset);
198 break;
199 case PACKET_TYPE_ATTEMPT_JOIN:
200 dissect_sender_array(clique_rm_tree, hf_clique_rm_attempt_join,
201 ett_clique_rm_attempt_join, hf_clique_rm_attempt_join_senders, tvb, offset);
202 break;
203 case PACKET_TYPE_JOIN:
204 dissect_sender_array(clique_rm_tree, hf_clique_rm_join_failures,
205 ett_clique_rm_join_failures, hf_clique_rm_join_failures_senders, tvb, offset);
206 break;
207 case PACKET_TYPE_BYE:
208 break;
209 default:
210 break;
214 static void
215 dissect_unreliable_packet(proto_tree *clique_rm_tree, uint8_t type, tvbuff_t *tvb, int offset)
217 unsigned len;
219 if (!clique_rm_tree)
220 return; /* no col_..() or expert...() calls in following */
222 switch (type)
224 case PACKET_TYPE_WHOIS_REQUEST:
225 proto_tree_add_item(clique_rm_tree,
226 hf_clique_rm_whois_request_id, tvb, offset, 4, ENC_BIG_ENDIAN);
227 break;
228 case PACKET_TYPE_WHOIS_REPLY:
229 len = tvb_get_uint8(tvb, offset);
230 proto_tree_add_item(clique_rm_tree,
231 hf_clique_rm_whois_reply_name_length, tvb, offset, 1, ENC_BIG_ENDIAN);
232 offset += 1;
233 proto_tree_add_item(clique_rm_tree,
234 hf_clique_rm_whois_reply_name, tvb, offset, len, ENC_ASCII);
235 break;
236 case PACKET_TYPE_REPAIR_REQUEST:
237 proto_tree_add_item(clique_rm_tree,
238 hf_clique_rm_repair_request_sender_id, tvb, offset, 4, ENC_BIG_ENDIAN);
239 offset += 4;
241 proto_tree_add_item(clique_rm_tree,
242 hf_clique_rm_repair_request_packet_id, tvb, offset, 4, ENC_BIG_ENDIAN);
243 break;
244 case PACKET_TYPE_SESSION:
245 dissect_depends(clique_rm_tree, tvb, offset);
246 break;
247 default:
248 break;
253 static bool
254 dissect_clique_rm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
256 proto_item *ti;
257 proto_tree *clique_rm_tree;
258 uint8_t version;
259 uint8_t type;
260 int offset = 0;
261 uint64_t qword;
263 if (tvb_captured_length(tvb) < 12)
264 return false;
266 qword = tvb_get_ntoh48(tvb,0);
267 /* ASCII str for 'Clique' = 0x436c69717565 */
268 if(qword != UINT64_C (0x436c69717565))
269 return false;
270 offset += 6;
272 version = tvb_get_uint8(tvb, offset);
273 if (version != 1)
274 return false;
275 offset++;
277 type = tvb_get_uint8(tvb, offset);
278 offset++;
280 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Clique-rm");
281 col_add_str(pinfo->cinfo, COL_INFO,
282 val_to_str(type, packet_type_vals, "Unknown (0x%02x)"));
284 /* rewind back to just behind the prefix */
285 offset = 6;
287 ti = proto_tree_add_item(tree, proto_clique_rm, tvb, 0, -1, ENC_NA);
288 clique_rm_tree = proto_item_add_subtree(ti, ett_clique_rm);
290 proto_tree_add_item(clique_rm_tree, hf_clique_rm_version, tvb, offset, 1,
291 ENC_BIG_ENDIAN);
292 offset++;
294 proto_tree_add_item(clique_rm_tree, hf_clique_rm_type, tvb, offset, 1,
295 ENC_BIG_ENDIAN);
296 offset++;
298 col_append_fstr(pinfo->cinfo, COL_INFO, ", sender: 0x%x",
299 tvb_get_ntohl(tvb, offset));
301 proto_tree_add_item(clique_rm_tree, hf_clique_rm_sender, tvb, offset,
302 4, ENC_BIG_ENDIAN);
303 offset += 4;
305 if (IS_RELIABLE(type)) {
306 col_append_fstr(pinfo->cinfo, COL_INFO, ", id: 0x%x",
307 tvb_get_ntohl(tvb, offset));
309 dissect_reliable_packet(clique_rm_tree, type, tvb, offset);
310 } else {
311 dissect_unreliable_packet(clique_rm_tree, type, tvb, offset);
314 return true;
318 /* Register the protocol with Wireshark */
320 void
321 proto_register_clique_rm(void)
324 /* Setup list of header fields See Section 1.6.1 for details*/
325 static hf_register_info hf[] = {
326 { &hf_clique_rm_version,
327 { "Version", "clique_rm.version",
328 FT_UINT8, BASE_DEC, NULL, 0x0,
329 NULL, HFILL }
331 { &hf_clique_rm_type,
332 { "Type", "clique_rm.type",
333 FT_UINT8, BASE_HEX, VALS(packet_type_vals), 0x0,
334 NULL, HFILL }
336 { &hf_clique_rm_sender,
337 { "Sender", "clique_rm.sender",
338 FT_UINT32, BASE_HEX, NULL, 0x0,
339 NULL, HFILL }
341 { &hf_clique_rm_packet_id,
342 { "Packet id", "clique_rm.packet_id",
343 FT_UINT32, BASE_HEX, NULL, 0x0,
344 NULL, HFILL }
346 { &hf_clique_rm_depends,
347 { "Depends", "clique_rm.depends",
348 FT_UINT8, BASE_HEX, NULL, 0x0,
349 NULL, HFILL }
351 { &hf_clique_rm_depend_sender,
352 { "Sender", "clique_rm.depends.sender",
353 FT_UINT32, BASE_HEX, NULL, 0x0,
354 NULL, HFILL }
356 { &hf_clique_rm_depend_packet_id,
357 { "Packet id", "clique_rm.depends.packet_id",
358 FT_UINT32, BASE_HEX, NULL, 0x0,
359 NULL, HFILL }
361 { &hf_clique_rm_failures,
362 { "Failures", "clique_rm.failures",
363 FT_UINT8, BASE_HEX, NULL, 0x0,
364 NULL, HFILL }
366 { &hf_clique_rm_failures_senders,
367 { "Sender", "clique_rm.failures.sender",
368 FT_UINT32, BASE_HEX, NULL, 0x0,
369 NULL, HFILL }
371 { &hf_clique_rm_attempt_join,
372 { "New attempt join senders", "clique_rm.attempt_join",
373 FT_UINT8, BASE_HEX, NULL, 0x0,
374 NULL, HFILL }
376 { &hf_clique_rm_attempt_join_senders,
377 { "Sender", "clique_rm.attempt_join.sender",
378 FT_UINT32, BASE_HEX, NULL, 0x0,
379 NULL, HFILL }
381 { &hf_clique_rm_join_failures,
382 { "Join failures", "clique_rm.join_failures",
383 FT_UINT8, BASE_HEX, NULL, 0x0,
384 NULL, HFILL }
386 { &hf_clique_rm_join_failures_senders,
387 { "Sender", "clique_rm.join_failures.sender",
388 FT_UINT32, BASE_HEX, NULL, 0x0,
389 NULL, HFILL }
391 { &hf_clique_rm_data_flags,
392 { "Data flags", "clique_rm.data.flags",
393 FT_UINT8, BASE_HEX, NULL, 0x0,
394 NULL, HFILL }
396 { &hf_clique_rm_data_size,
397 { "Data total size", "clique_rm.data.size",
398 FT_UINT32, BASE_DEC, NULL, 0x0,
399 NULL, HFILL }
401 { &hf_clique_rm_data_stream_id,
402 { "Data stream id", "clique_rm.data.stream_id",
403 FT_UINT16, BASE_HEX, NULL, 0x0,
404 NULL, HFILL }
406 { &hf_clique_rm_data_data,
407 { "Raw data", "clique_rm.data.data",
408 FT_BYTES, BASE_NONE, NULL, 0x0,
409 NULL, HFILL }
411 { &hf_clique_rm_whois_request_id,
412 { "Whois request id", "clique_rm.whois_request.id",
413 FT_UINT32, BASE_HEX, NULL, 0x0,
414 NULL, HFILL }
416 { &hf_clique_rm_whois_reply_name_length,
417 { "Whois reply name length", "clique_rm.whois_reply.length",
418 FT_UINT8, BASE_DEC, NULL, 0x0,
419 NULL, HFILL }
421 { &hf_clique_rm_whois_reply_name,
422 { "Whois reply name", "clique_rm.whois_reply.name",
423 FT_STRINGZ, BASE_NONE, NULL, 0x0,
424 NULL, HFILL }
426 { &hf_clique_rm_repair_request_sender_id,
427 { "Repair request for sender",
428 "clique_rm.repair_request.sender_id",
429 FT_UINT32, BASE_HEX, NULL, 0x0,
430 NULL, HFILL }
432 { &hf_clique_rm_repair_request_packet_id,
433 { "Repair request for packet",
434 "clique_rm.repair_request.packet_id",
435 FT_UINT32, BASE_HEX, NULL, 0x0,
436 NULL, HFILL }
440 /* Setup protocol subtree array */
441 static int *ett[] = {
442 &ett_clique_rm,
443 &ett_clique_rm_depends,
444 &ett_clique_rm_depends_item,
445 &ett_clique_rm_data,
446 &ett_clique_rm_failures,
447 &ett_clique_rm_join_failures,
448 &ett_clique_rm_attempt_join,
449 &ett_clique_rm_join,
452 /* Register the protocol name and description */
453 proto_clique_rm = proto_register_protocol("Clique Reliable Multicast Protocol", "Clique-rm", "clique-rm");
455 /* Required function calls to register the header fields and subtrees used */
456 proto_register_field_array(proto_clique_rm, hf, array_length(hf));
457 proto_register_subtree_array(ett, array_length(ett));
461 void
462 proto_reg_handoff_clique_rm(void)
464 heur_dissector_add("udp", dissect_clique_rm_heur, "Clique RM over UDP", "clique_rm_udp", proto_clique_rm, HEURISTIC_ENABLE);
468 * Editor modelines - https://www.wireshark.org/tools/modelines.html
470 * Local Variables:
471 * c-basic-offset: 2
472 * tab-width: 8
473 * indent-tabs-mode: nil
474 * End:
476 * ex: set shiftwidth=2 tabstop=8 expandtab:
477 * :indentSize=2:tabSize=8:noTabs=true: