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
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
;
58 /* Unreliable packets */
59 PACKET_TYPE_WHOIS_REQUEST
= 0,
60 PACKET_TYPE_WHOIS_REPLY
,
61 PACKET_TYPE_REPAIR_REQUEST
,
63 /* Reliable packets */
64 FIRST_RELIABLE_PACKET
= 0xf,
65 PACKET_TYPE_DATA
= FIRST_RELIABLE_PACKET
,
66 /* No data just acknowledgement */
68 /* Some nodes failed */
70 /* Start a joining attempt */
71 PACKET_TYPE_ATTEMPT_JOIN
,
74 /* Leaving now, bye */
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" },
94 { PACKET_TYPE_JOIN
, "Join" },
95 /* Leaving now, bye */
96 { PACKET_TYPE_BYE
, "Bye" },
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
)
111 count
= tvb_get_uint8(tvb
, offset
);
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
);
118 for (i
= 0; i
< count
; i
++, offset
+= 4)
119 proto_tree_add_item(tree
, hf_header_sender
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
123 dissect_data_packet(proto_tree
*clique_rm_tree
, tvbuff_t
*tvb
, int offset
)
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
);
132 proto_tree_add_item(tree
, hf_clique_rm_data_stream_id
, tvb
, offset
, 2,
136 proto_tree_add_item(tree
, hf_clique_rm_data_size
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
140 proto_tree_add_item(tree
, hf_clique_rm_data_data
, tvb
, offset
, -1, ENC_NA
);
144 dissect_depends(proto_tree
*clique_rm_tree
, tvbuff_t
*tvb
, int offset
)
147 proto_tree
*tree
, *depend_tree
;
151 count
= tvb_get_uint8(tvb
, offset
);
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
);
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
);
175 /* Code to actually dissect the packets */
177 dissect_reliable_packet(proto_tree
*clique_rm_tree
, uint8_t type
, tvbuff_t
*tvb
, int offset
)
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,
186 offset
+= dissect_depends(clique_rm_tree
, tvb
, offset
);
190 case PACKET_TYPE_DATA
:
191 dissect_data_packet(clique_rm_tree
, tvb
, offset
);
193 case PACKET_TYPE_NO_DATA
:
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
);
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
);
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
);
207 case PACKET_TYPE_BYE
:
215 dissect_unreliable_packet(proto_tree
*clique_rm_tree
, uint8_t type
, tvbuff_t
*tvb
, int offset
)
220 return; /* no col_..() or expert...() calls in following */
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
);
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
);
233 proto_tree_add_item(clique_rm_tree
,
234 hf_clique_rm_whois_reply_name
, tvb
, offset
, len
, ENC_ASCII
);
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
);
241 proto_tree_add_item(clique_rm_tree
,
242 hf_clique_rm_repair_request_packet_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
244 case PACKET_TYPE_SESSION
:
245 dissect_depends(clique_rm_tree
, tvb
, offset
);
254 dissect_clique_rm_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
257 proto_tree
*clique_rm_tree
;
263 if (tvb_captured_length(tvb
) < 12)
266 qword
= tvb_get_ntoh48(tvb
,0);
267 /* ASCII str for 'Clique' = 0x436c69717565 */
268 if(qword
!= UINT64_C (0x436c69717565))
272 version
= tvb_get_uint8(tvb
, offset
);
277 type
= tvb_get_uint8(tvb
, 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 */
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,
294 proto_tree_add_item(clique_rm_tree
, hf_clique_rm_type
, tvb
, offset
, 1,
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
,
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
);
311 dissect_unreliable_packet(clique_rm_tree
, type
, tvb
, offset
);
318 /* Register the protocol with Wireshark */
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,
331 { &hf_clique_rm_type
,
332 { "Type", "clique_rm.type",
333 FT_UINT8
, BASE_HEX
, VALS(packet_type_vals
), 0x0,
336 { &hf_clique_rm_sender
,
337 { "Sender", "clique_rm.sender",
338 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
341 { &hf_clique_rm_packet_id
,
342 { "Packet id", "clique_rm.packet_id",
343 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
346 { &hf_clique_rm_depends
,
347 { "Depends", "clique_rm.depends",
348 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
351 { &hf_clique_rm_depend_sender
,
352 { "Sender", "clique_rm.depends.sender",
353 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
356 { &hf_clique_rm_depend_packet_id
,
357 { "Packet id", "clique_rm.depends.packet_id",
358 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
361 { &hf_clique_rm_failures
,
362 { "Failures", "clique_rm.failures",
363 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
366 { &hf_clique_rm_failures_senders
,
367 { "Sender", "clique_rm.failures.sender",
368 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
371 { &hf_clique_rm_attempt_join
,
372 { "New attempt join senders", "clique_rm.attempt_join",
373 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
376 { &hf_clique_rm_attempt_join_senders
,
377 { "Sender", "clique_rm.attempt_join.sender",
378 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
381 { &hf_clique_rm_join_failures
,
382 { "Join failures", "clique_rm.join_failures",
383 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
386 { &hf_clique_rm_join_failures_senders
,
387 { "Sender", "clique_rm.join_failures.sender",
388 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
391 { &hf_clique_rm_data_flags
,
392 { "Data flags", "clique_rm.data.flags",
393 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
396 { &hf_clique_rm_data_size
,
397 { "Data total size", "clique_rm.data.size",
398 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
401 { &hf_clique_rm_data_stream_id
,
402 { "Data stream id", "clique_rm.data.stream_id",
403 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
406 { &hf_clique_rm_data_data
,
407 { "Raw data", "clique_rm.data.data",
408 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
411 { &hf_clique_rm_whois_request_id
,
412 { "Whois request id", "clique_rm.whois_request.id",
413 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
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,
421 { &hf_clique_rm_whois_reply_name
,
422 { "Whois reply name", "clique_rm.whois_reply.name",
423 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
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,
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,
440 /* Setup protocol subtree array */
441 static int *ett
[] = {
443 &ett_clique_rm_depends
,
444 &ett_clique_rm_depends_item
,
446 &ett_clique_rm_failures
,
447 &ett_clique_rm_join_failures
,
448 &ett_clique_rm_attempt_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
));
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
473 * indent-tabs-mode: nil
476 * ex: set shiftwidth=2 tabstop=8 expandtab:
477 * :indentSize=2:tabSize=8:noTabs=true: