Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-rtps-virtual-transport.c
blob497372a0b6dd7ca3da56986f6636b68132b47414
1 /* packet-rtps-virtual-transport.c
2 * Dissector for the Real-Time Publish-Subscribe (RTPS) Virtual Transport
3 * Protocol.
5 * (c) 2020 Copyright, Real-Time Innovations, Inc.
6 * Real-Time Innovations, Inc.
7 * 232 East Java Drive
8 * Sunnyvale, CA 94089
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
16 * -----------------------------------------------------------------------------
17 * RTI Connext DDS can capture RTPS-related traffic by using the Network Capture
18 * Utility. The generated .pcap capture files will follow the RTPS-VT protocol,
19 * which establishes a format for how information must be saved, and then
20 * parsed.
22 * The protocol is divided into two layers: transport
23 * (packet-rtps-virtual-transport.c) and advanced (packet-rtps-processed.c).
24 * This file is about the transport dissector. For more information about the
25 * advanced dissector, read the documentation at the beginning of
26 * packet-rtps-processed.c.
28 * Every packet saved in the capture file follows the PCAP file format.
29 * As a consequence, there are two headers: a global one (unique per file) and
30 * a per-packet header. These headers have the typical content described in the
31 * PCAP format: a magic number, version number, some timestamps, information
32 * describing the length of the packet and the data link layer (0x000000fc, i.e.
33 * custom protocol), etc. Then, we have a header that indicates Wireshark the
34 * name of the protocol: "rtpsvt". The transport dissector is called when
35 * Wireshark finds "rtpsvt" as the protocol name.
37 * After the RTPS-VT header, we have the frame type. The frame type determines
38 * what kind of information has the dumped packet. RTPS-VT data comes as a
39 * series of [parameter identifier, content length, content]. Depending on the
40 * type of frame (RTPS or lossInfo), the dissector will expect some parameters
41 * or others.
43 * If the frame type is RTPS, we will continue parsing transport-layer data.
44 * The transport layer contains all information about the source and destination
45 * of a packet. This corresponds to data typically found on Network or Transport
46 * protocols. However, because RTI Connext DDS generates the capture file
47 * directly at application-level, this information is added at the moment of
48 * writing the capture file.
49 * After the transport-layer information, we will call the advanced dissector.
51 * If the frame type is lossInfo, the dissector will generate a packet
52 * indicating that there were missing frames (and the range of sequence
53 * numbers).
55 #include "config.h"
57 #include <epan/packet.h>
58 #include <epan/expert.h>
59 #include <epan/prefs.h>
60 #include <epan/addr_resolv.h>
61 #include <epan/wmem_scopes.h>
62 #include <epan/conversation.h>
63 #include "packet-tcp.h"
64 #include "packet-rtps.h"
67 #define CONTENT_KIND_RTPS 0x01
68 #define CONTENT_KIND_LOSS_INFO 0x02
70 #define PARAM_ID_TRANSPORT_CLASS 0x0001
71 #define PARAM_ID_MONITORING_GUID 0x0002
72 #define PARAM_ID_MONITORING_SN 0x0003
73 #define PARAM_ID_SOURCE_IP_ADDRESS 0x0004
74 #define PARAM_ID_SOURCE_PORT 0x0005
75 #define PARAM_ID_DESTINATION_IP_ADDRESS 0x0006
76 #define PARAM_ID_DESTINATION_RTPS_PORT 0x0007
77 #define PARAM_ID_DESTINATION_PORT 0x0008
78 #define PARAM_ID_DIRECTION 0x0009
79 #define FIRST_PARAM_ID_RTPS PARAM_ID_TRANSPORT_CLASS
80 #define LAST_PARAM_ID_RTPS PARAM_ID_DIRECTION
82 /* First parameter Identifier that the "rtpsproc" protocol accepts */
83 #define PARAM_ID_MAIN_FRAME 0x00C0
85 #define PARAM_ID_LOST_MESSAGES 0x0001
87 void proto_register_rtps_virtual_transport(void);
88 static int dissect_rtps_virtual_transport(
89 tvbuff_t *tvb,
90 packet_info *pinfo,
91 proto_tree *tree,
92 void *data _U_);
93 static int dissect_rtps_virtual_transport_rtps_type(
94 tvbuff_t *tvb,
95 packet_info *pinfo,
96 proto_tree *tree,
97 proto_tree *tree_transport,
98 int offset,
99 struct rtpsvt_data *transport_data);
100 static int dissect_parameter_transport_rtps_type(
101 tvbuff_t *tvb,
102 proto_tree *rtpsvt_tree_general,
103 proto_tree *rtpsvt_tree_identifier,
104 proto_tree *rtpsvt_tree_information,
105 int offset,
106 packet_info *pinfo,
107 struct rtpsvt_data *transport_data);
108 static int dissect_rtps_virtual_transport_loss_info_type(
109 tvbuff_t *tvb,
110 packet_info *pinfo,
111 proto_tree *tree_transport,
112 int offset);
114 /* Subtree pointers */
115 static int proto_rtpsvt;
116 static int ett_rtpsvt;
117 static int ett_rtpsvt_version;
118 static int ett_rtpsvt_identifier;
119 static int ett_rtpsvt_information;
120 static int ett_rtpsvt_information_class;
121 static int ett_rtpsvt_information_src_port;
122 static int ett_rtpsvt_information_dst_port;
123 static int ett_rtpsvt_information_src_addr;
124 static int ett_rtpsvt_information_dst_addr;
125 static int ett_rtpsvt_information_direction;
126 static int ett_rtpsvt_monitoring_sn;
127 static int ett_rtpsvt_frame;
129 /* Initialize the protocol and registered fields */
130 static header_field_info *rtpsvt_hf;
131 static int hf_rtpsvt_version;
132 static int hf_rtpsvt_version_major;
133 static int hf_rtpsvt_version_minor;
134 static int hf_rtpsvt_content_kind;
135 static int hf_rtpsvt_param_id;
136 static int hf_rtpsvt_param_length;
137 static int hf_rtpsvt_packet_identifier;
138 static int hf_rtpsvt_monitoring_guid;
139 static int hf_rtpsvt_monitoring_seqNr;
140 static int hf_rtpsvt_information;
141 static int hf_rtpsvt_class;
142 static int hf_rtpsvt_source_port;
143 static int hf_rtpsvt_source_address;
144 static int hf_rtpsvt_source_pid;
145 static int hf_rtpsvt_destination_port;
146 static int hf_rtpsvt_destination_rtps_port;
147 static int hf_rtpsvt_destination_address;
148 static int hf_rtpsvt_direction;
149 static int hf_rtpsvt_destination_pid;
150 static int hf_rtpsvt_missing_messages;
152 /* expert info fields */
153 static expert_field ei_missing_msg;
155 /* Vendor specific: RTI */
156 static const value_string ndds_transport_class_id_vals[] = {
157 { NDDS_TRANSPORT_CLASSID_ANY, "ANY" },
158 { NDDS_TRANSPORT_CLASSID_UDPv4, "UDPv4" },
159 { NDDS_TRANSPORT_CLASSID_UDPv4_WAN, "UDPv4_WAN"},
160 { NDDS_TRANSPORT_CLASSID_SHMEM, "SHMEM" },
161 { NDDS_TRANSPORT_CLASSID_INTRA, "INTRA" },
162 { NDDS_TRANSPORT_CLASSID_UDPv6, "UDPv6" },
163 { NDDS_TRANSPORT_CLASSID_DTLS, "DTLS" },
164 { NDDS_TRANSPORT_CLASSID_WAN, "WAN" },
165 { NDDS_TRANSPORT_CLASSID_TCPV4_LAN, "TCPv4_LAN" },
166 { NDDS_TRANSPORT_CLASSID_TCPV4_WAN, "TCPv4_WAN" },
167 { NDDS_TRANSPORT_CLASSID_TLSV4_LAN, "TLSv4_LAN" },
168 { NDDS_TRANSPORT_CLASSID_TLSV4_WAN, "TLSv4_WAN" },
169 { NDDS_TRANSPORT_CLASSID_PCIE, "PCIE" },
170 { NDDS_TRANSPORT_CLASSID_ITP, "ITP" },
171 { 0, NULL }
174 static int dissect_rtps_virtual_transport(
175 tvbuff_t *tvb,
176 packet_info *pinfo,
177 proto_tree *tree,
178 void *data _U_)
180 proto_tree *rtpsvt_tree_transport;
181 proto_item *rtpsvt_ti_transport;
182 proto_item *rtpsvt_ti_version;
183 proto_tree *rtpsvt_tree_version;
184 proto_item *rtpsvt_ti_content_kind;
185 struct rtpsvt_data transport_data;
186 uint16_t version;
187 uint8_t content_type;
188 const char *content_type_label;
189 int offset = 0;
190 int output = 0;
192 /* Add transport tree, used for the fields of our proto_rtpsvt */
193 rtpsvt_ti_transport = proto_tree_add_item(
194 tree,
195 proto_rtpsvt,
196 tvb,
197 offset,
199 ENC_BIG_ENDIAN);
200 rtpsvt_tree_transport = proto_item_add_subtree(rtpsvt_ti_transport, ett_rtpsvt);
202 /* Add the version to the transport protocol */
203 version = tvb_get_ntohs(tvb, offset);
204 transport_data.version_major = version >> 8;
205 transport_data.version_minor = version & 0xff;
206 rtpsvt_ti_version = proto_tree_add_uint_format(
207 rtpsvt_tree_transport,
208 hf_rtpsvt_version,
209 tvb,
210 offset,
211 2, /* 2B: sizeof(uint16_t) */
212 version,
213 "Version: %d.%d",
214 transport_data.version_major,
215 transport_data.version_minor);
216 rtpsvt_tree_version = proto_item_add_subtree(
217 rtpsvt_ti_version,
218 ett_rtpsvt_version);
220 proto_tree_add_item(
221 rtpsvt_tree_version,
222 hf_rtpsvt_version_major,
223 tvb,
224 offset,
225 1, /* length: sizeof(uint8_t) */
226 ENC_NA);
227 proto_tree_add_item(
228 rtpsvt_tree_version,
229 hf_rtpsvt_version_minor,
230 tvb,
231 offset + 1,
232 1, /* length: sizeof(uint8_t) */
233 ENC_NA);
234 offset += 2;
236 /* Add the content kind. */
237 content_type = tvb_get_uint8(tvb, offset);
238 rtpsvt_ti_content_kind = proto_tree_add_item(
239 rtpsvt_ti_transport,
240 hf_rtpsvt_content_kind,
241 tvb,
242 offset,
243 1, /* length: sizeof(uint8_t) */
244 ENC_NA);
245 if (content_type == CONTENT_KIND_RTPS) {
246 content_type_label = "RTPS";
247 } else {
248 content_type_label = "LOST_INFO";
250 proto_item_append_text(rtpsvt_ti_content_kind, " (%s)", content_type_label);
251 offset += 1;
253 switch(content_type) {
254 case CONTENT_KIND_RTPS:
255 output = dissect_rtps_virtual_transport_rtps_type(
256 tvb,
257 pinfo,
258 tree,
259 rtpsvt_tree_transport,
260 offset,
261 &transport_data);
262 break;
264 case CONTENT_KIND_LOSS_INFO:
265 output = dissect_rtps_virtual_transport_loss_info_type(
266 tvb,
267 pinfo,
268 rtpsvt_tree_transport,
269 offset);
270 break;
272 return output;
275 static int dissect_rtps_virtual_transport_rtps_type(
276 tvbuff_t *tvb,
277 packet_info *pinfo,
278 proto_tree *tree,
279 proto_tree *tree_transport,
280 int offset,
281 struct rtpsvt_data *transport_data)
283 proto_item *rtpsvt_ti_identifier;
284 proto_tree *rtpsvt_tree_identifier;
285 proto_item *rtpsvt_ti_information;
286 proto_tree *rtpsvt_tree_information;
287 tvbuff_t *advanced_payload;
288 static dissector_handle_t advanced_handle = NULL;
289 unsigned int idx = FIRST_PARAM_ID_RTPS;
290 uint16_t param_id;
291 uint16_t param_length;
294 * Add the tree for the packet identifier, which will be populated in
295 * dissect_parameter_transport_rtps_type.
297 rtpsvt_ti_identifier = proto_tree_add_item(
298 tree_transport,
299 hf_rtpsvt_packet_identifier,
300 tvb,
301 offset,
303 ENC_NA);
304 rtpsvt_tree_identifier = proto_item_add_subtree(
305 rtpsvt_ti_identifier,
306 ett_rtpsvt_identifier);
309 * Add the tree for the transport information, which will be populated in
310 * dissect_parameter_transport_rtps_type.
312 rtpsvt_ti_information = proto_tree_add_item(
313 tree_transport,
314 hf_rtpsvt_information,
315 tvb,
316 offset,
318 ENC_NA);
319 rtpsvt_tree_information = proto_item_add_subtree(
320 rtpsvt_ti_information,
321 ett_rtpsvt_information);
324 * Each parameter has an id, a length and a value.
326 for (idx = FIRST_PARAM_ID_RTPS; idx <= LAST_PARAM_ID_RTPS; idx++) {
327 offset = dissect_parameter_transport_rtps_type(
328 tvb,
329 tree_transport,
330 rtpsvt_tree_identifier,
331 rtpsvt_tree_information,
332 offset,
333 pinfo,
334 transport_data);
338 * In the future we may have more transport parameters.
339 * These parameters will have an identifier less than PARAM_ID_MAIN_FRAME
340 * (which is parsed by the rtpsproc dissector).
341 * If we open a "future" capture file with this dissector, we will skip all
342 * of those parameters and parse only the ones we know about.
344 do {
345 param_id = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
346 offset += 2;
347 param_length = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
348 offset += 2;
349 if (param_id == PARAM_ID_MAIN_FRAME) {
350 proto_tree *rtpsvt_tree_frame;
351 transport_data->rtps_length = param_length;
352 rtpsvt_tree_frame = proto_tree_add_subtree_format(
353 tree_transport,
354 tvb,
355 offset,
357 ett_rtpsvt_frame,
358 NULL,
359 "Real-Time Publish-Subscribe Wire Protocol (content)");
361 proto_tree_add_uint(
362 rtpsvt_tree_frame,
363 hf_rtpsvt_param_id,
364 tvb,
365 offset,
366 2, /* 2B: sizeof(uint16_t) */
367 param_id);
368 proto_tree_add_uint(
369 rtpsvt_tree_frame,
370 hf_rtpsvt_param_length,
371 tvb,
372 offset + 2,
374 param_length);
375 break;
377 offset += param_length;
378 } while (tvb_reported_length_remaining(tvb, offset) > 0);
380 if (param_id != PARAM_ID_MAIN_FRAME || param_length <= 0) {
382 * Reject the packet if we don't have an RTPS frame.
383 * The rtpsproc dissector assumes that the contents start with the
384 * RTPS frame (parameter value; the length is obtained from
385 * transport_data).
387 return 0;
390 advanced_payload = tvb_new_subset_length(tvb, offset, -1);
391 advanced_handle = find_dissector("rtpsproc");
392 call_dissector_with_data(
393 advanced_handle,
394 advanced_payload,
395 pinfo,
396 tree,
397 (void *) transport_data);
399 return tvb_captured_length(tvb);
402 static int dissect_parameter_transport_rtps_type(
403 tvbuff_t *tvb,
404 proto_tree *rtpsvt_tree_general,
405 proto_tree *rtpsvt_tree_identifier,
406 proto_tree *rtpsvt_tree_information,
407 int offset,
408 packet_info *pinfo,
409 struct rtpsvt_data *transport_data)
412 * We will add the parameter id and length later, as part of a subtree
413 * dependent of the parameter.
414 * That is why value of the parameter is now at offset + 4
415 * (i.e. offset + sizeof(param_id) + sizeof(param_length))
417 uint16_t param_id = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
418 uint16_t param_length = tvb_get_uint16(tvb, offset + 2, ENC_BIG_ENDIAN);
419 const int OFFSET_TO_VAL = offset + 4;
420 if (param_length <=0) {
421 /* Length not valid: skip parameter (id + length) */
422 return OFFSET_TO_VAL;
425 switch(param_id) {
426 case PARAM_ID_TRANSPORT_CLASS:
428 proto_tree *rtpsvt_tree_information_class;
429 int32_t classId = tvb_get_int32(tvb, OFFSET_TO_VAL, ENC_BIG_ENDIAN);
430 const char *className = val_to_str(
431 classId,
432 ndds_transport_class_id_vals,
433 "%d");
435 rtpsvt_tree_information_class = proto_tree_add_subtree_format(
436 rtpsvt_tree_information,
437 tvb,
438 offset,
440 ett_rtpsvt_information_class,
441 NULL,
442 "Class: %s",
443 className);
445 /* Add parameter identifier and length */
446 proto_tree_add_uint(
447 rtpsvt_tree_information_class,
448 hf_rtpsvt_param_id,
449 tvb,
450 offset,
451 2, /* length: sizeof(uint16_t) */
452 param_id);
453 offset += 2;
454 proto_tree_add_uint(
455 rtpsvt_tree_information_class,
456 hf_rtpsvt_param_length,
457 tvb,
458 offset,
459 2, /* length: sizeof(uint16_t) */
460 param_length);
461 offset += 2;
464 * Add transport class as item to the tree.
465 * This is useful to apply as column or filter.
467 proto_tree_add_string(
468 rtpsvt_tree_information_class,
469 hf_rtpsvt_class,
470 tvb,
471 offset,
472 param_length,
473 className);
474 offset += param_length;
476 /* Add summary to protocol header */
477 proto_item_append_text(rtpsvt_tree_general, ", %s", className);
479 /* Add summary to the transport information header */
480 proto_item_append_text(
481 rtpsvt_tree_information,
482 ", %s",
483 className);
485 break;
487 case PARAM_ID_MONITORING_GUID:
489 proto_tree *rtpsvt_tree_monitoring_guid;
490 const uint8_t *guid_bytes = tvb_get_ptr(
491 tvb,
492 OFFSET_TO_VAL,
493 param_length);
494 const char *guid_string = bytes_to_str_punct(
495 pinfo->pool,
496 guid_bytes,
497 MIN(param_length, 12),
500 rtpsvt_tree_monitoring_guid = proto_tree_add_subtree_format(
501 rtpsvt_tree_identifier,
502 tvb,
503 offset,
505 ett_rtpsvt_information_src_addr,
506 NULL,
507 "Monitoring GUID Prefix: %s",
508 guid_string);
510 /* Add parameter identifier and length */
511 proto_tree_add_uint(
512 rtpsvt_tree_monitoring_guid,
513 hf_rtpsvt_param_id,
514 tvb,
515 offset,
516 2, /* length: sizeof(uint16_t) */
517 param_id);
518 offset += 2;
519 proto_tree_add_uint(
520 rtpsvt_tree_monitoring_guid,
521 hf_rtpsvt_param_length,
522 tvb,
523 offset,
524 2, /* length: sizeof(uint16_t) */
525 param_length);
526 offset += 2;
528 proto_tree_add_item(
529 rtpsvt_tree_monitoring_guid,
530 hf_rtpsvt_monitoring_guid,
531 tvb,
532 offset,
533 param_length,
534 ENC_NA);
535 offset += param_length;
537 /* Add summary to packet identifier header */
538 proto_item_append_text(
539 rtpsvt_tree_identifier,
540 ", GUID: %s",
541 guid_string);
543 break;
544 case PARAM_ID_MONITORING_SN:
546 proto_tree *rtpsvt_tree_seqNr;
547 uint64_t seqNr = tvb_get_uint64(tvb, OFFSET_TO_VAL, ENC_BIG_ENDIAN);
549 rtpsvt_tree_seqNr = proto_tree_add_subtree_format(
550 rtpsvt_tree_identifier,
551 tvb,
552 offset,
554 ett_rtpsvt_monitoring_sn,
555 NULL,
556 "Monitoring Sequence Number: %" PRIu64,
557 seqNr);
559 /* Add parameter identifier and length */
560 proto_tree_add_uint(
561 rtpsvt_tree_seqNr,
562 hf_rtpsvt_param_id,
563 tvb,
564 offset,
565 2, /* length: sizeof(uint16_t) */
566 param_id);
567 offset += 2;
568 proto_tree_add_uint(
569 rtpsvt_tree_seqNr,
570 hf_rtpsvt_param_length,
571 tvb,
572 offset,
573 2, /* length: sizeof(uint16_t) */
574 param_length);
575 offset += 2;
577 proto_tree_add_uint64(
578 rtpsvt_tree_seqNr,
579 hf_rtpsvt_monitoring_seqNr,
580 tvb,
581 offset,
582 param_length,
583 seqNr);
584 offset += param_length;
586 /* Add summary to packet identifier header */
587 proto_item_append_text(
588 rtpsvt_tree_identifier,
589 ", SeqNum: %" PRIu64,
590 seqNr);
592 break;
593 case PARAM_ID_SOURCE_IP_ADDRESS:
595 proto_tree *rtpsvt_tree_information_address;
596 int temporary_hf = hf_rtpsvt_source_address;
597 const char *prefix = "shmem_prefix";
598 const char *title_tree = "Source address";
599 char addr[COL_MAX_LEN];
600 ws_in6_addr addr_raw;
601 static const uint8_t bytes_zeroed[12] = {0};
602 tvb_get_ipv6(tvb, OFFSET_TO_VAL, &addr_raw);
604 /* shared memory pid or address? */
605 if (memcmp(&addr_raw.bytes, prefix, strlen(prefix)) == 0) {
606 temporary_hf = hf_rtpsvt_source_pid;
607 title_tree = "Source process ID";
608 uint32_t pid = tvb_get_uint32(
609 tvb,
610 OFFSET_TO_VAL + (int) (strlen(prefix)),
611 ENC_BIG_ENDIAN);
612 snprintf(addr, sizeof(addr), "%u", pid);
613 } else if (memcmp(
614 &addr_raw.bytes,
615 bytes_zeroed,
616 sizeof(bytes_zeroed)) == 0){
617 snprintf(
618 addr,
619 sizeof(addr),
620 "%s",
621 tvb_ip_to_str(pinfo->pool, tvb, OFFSET_TO_VAL + sizeof(bytes_zeroed)));
622 } else {
623 snprintf(
624 addr,
625 sizeof(addr),
626 "%s",
627 tvb_ip6_to_str(pinfo->pool, tvb, OFFSET_TO_VAL));
630 /* Add source to destination column field */
631 if (pinfo->cinfo) {
632 col_append_str(pinfo->cinfo, COL_DEF_SRC, addr);
635 rtpsvt_tree_information_address = proto_tree_add_subtree_format(
636 rtpsvt_tree_information,
637 tvb,
638 offset,
640 ett_rtpsvt_information_src_addr,
641 NULL,
642 "%s: %s",
643 title_tree,
644 addr);
646 /* Add parameter identifier and length */
647 proto_tree_add_uint(
648 rtpsvt_tree_information_address,
649 hf_rtpsvt_param_id,
650 tvb,
651 offset,
652 2, /* length: sizeof(uint16_t) */
653 param_id);
654 offset += 2;
655 proto_tree_add_uint(
656 rtpsvt_tree_information_address,
657 hf_rtpsvt_param_length,
658 tvb,
659 offset,
660 2, /* length: sizeof(uint16_t) */
661 param_length);
662 offset += 2;
664 /* Add source to the transport information tree */
665 proto_tree_add_string(
666 rtpsvt_tree_information_address,
667 temporary_hf,
668 tvb,
669 offset,
670 param_length,
671 addr);
672 offset += param_length;
674 /* Add summary to protocol header */
675 proto_item_append_text(rtpsvt_tree_general, ", Src: (%s", addr);
677 /* Add summary to transport information header */
678 proto_item_append_text(
679 rtpsvt_tree_information,
680 ", Src: (%s",
681 addr);
683 break;
684 case PARAM_ID_SOURCE_PORT:
686 proto_tree *rtpsvt_tree_information_port;
687 uint32_t port = tvb_get_uint32(
688 tvb,
689 OFFSET_TO_VAL,
690 ENC_BIG_ENDIAN);
692 rtpsvt_tree_information_port = proto_tree_add_subtree_format(
693 rtpsvt_tree_information,
694 tvb,
695 offset,
697 ett_rtpsvt_information_src_port,
698 NULL,
699 "Source port: %d",
700 port);
702 /* Add parameter identifier and length */
703 proto_tree_add_uint(
704 rtpsvt_tree_information_port,
705 hf_rtpsvt_param_id,
706 tvb,
707 offset,
708 2, /* length: sizeof(uint16_t) */
709 param_id);
710 offset += 2;
711 proto_tree_add_uint(
712 rtpsvt_tree_information_port,
713 hf_rtpsvt_param_length,
714 tvb,
715 offset,
716 2, /* length: sizeof(uint16_t) */
717 param_length);
718 offset += 2;
720 proto_tree_add_uint(
721 rtpsvt_tree_information_port,
722 hf_rtpsvt_source_port,
723 tvb,
724 offset,
725 param_length,
726 port);
727 offset += param_length;
729 /* Add summary to protocol header */
730 proto_item_append_text(rtpsvt_tree_general, ":%d)", port);
732 /* Add summary to transport information header */
733 proto_item_append_text(
734 rtpsvt_tree_information,
735 ":%d)",
736 port);
739 * Add the source port to pinfo.
740 * This is used by the RTPS dissector to get the domainId and
741 * participantIdx information displayed in discovery packets.
743 pinfo->srcport = port;
745 break;
746 case PARAM_ID_DESTINATION_IP_ADDRESS:
748 proto_tree *rtpsvt_tree_information_address;
749 int temporary_hf= hf_rtpsvt_destination_address;
750 const char *prefix = "shmem_prefix";
751 const char *title_tree = "Destination address";
752 char addr[COL_MAX_LEN];
753 ws_in6_addr addr_raw;
754 static const uint8_t bytes_zeroed[12] = {0};
755 tvb_get_ipv6(tvb, OFFSET_TO_VAL, &addr_raw);
757 /* shared memory pid or address? */
758 if (memcmp(&addr_raw.bytes, prefix, strlen(prefix)) == 0) {
759 temporary_hf = hf_rtpsvt_destination_pid;
760 title_tree = "Destination process ID";
761 uint32_t pid = tvb_get_uint32(
762 tvb,
763 OFFSET_TO_VAL + (int) (strlen(prefix)),
764 ENC_BIG_ENDIAN);
765 snprintf(addr, sizeof(addr), "%u", pid);
766 } else if (memcmp(
767 &addr_raw.bytes,
768 bytes_zeroed,
769 sizeof(bytes_zeroed)) == 0){
770 snprintf(
771 addr,
772 sizeof(addr),
773 "%s",
774 tvb_ip_to_str(pinfo->pool, tvb, OFFSET_TO_VAL + sizeof(bytes_zeroed)));
775 } else {
776 snprintf(
777 addr,
778 sizeof(addr),
779 "%s",
780 tvb_ip6_to_str(pinfo->pool, tvb, OFFSET_TO_VAL));
783 /* Add address to destination column field */
784 if (pinfo->cinfo) {
785 col_append_str(pinfo->cinfo, COL_DEF_DST, addr);
788 rtpsvt_tree_information_address = proto_tree_add_subtree_format(
789 rtpsvt_tree_information,
790 tvb,
791 offset,
793 ett_rtpsvt_information_dst_addr,
794 NULL,
795 "%s: %s",
796 title_tree,
797 addr);
799 /* Add parameter identifier and length */
800 proto_tree_add_uint(
801 rtpsvt_tree_information_address,
802 hf_rtpsvt_param_id,
803 tvb,
804 offset,
805 2, /* length: sizeof(uint16_t) */
806 param_id);
807 offset += 2;
808 proto_tree_add_uint(
809 rtpsvt_tree_information_address,
810 hf_rtpsvt_param_length,
811 tvb,
812 offset,
813 2, /* length: sizeof(uint16_t) */
814 param_length);
815 offset += 2;
817 /* Add destination to the transport information tree */
818 proto_tree_add_string(
819 rtpsvt_tree_information_address,
820 temporary_hf,
821 tvb,
822 offset,
823 param_length,
824 addr);
825 offset += param_length;
827 /* Add summary to protocol header */
828 proto_item_append_text(rtpsvt_tree_general, ", Dst: (%s", addr);
830 /* Add summary to transport information header */
831 proto_item_append_text(
832 rtpsvt_tree_information,
833 ", Dst: (%s",
834 addr);
836 break;
837 case PARAM_ID_DESTINATION_RTPS_PORT:
839 uint32_t port = tvb_get_uint32(tvb, OFFSET_TO_VAL, ENC_BIG_ENDIAN);
841 proto_tree_add_uint(
842 rtpsvt_tree_information,
843 hf_rtpsvt_destination_rtps_port,
844 tvb,
845 OFFSET_TO_VAL,
846 param_length,
847 port);
849 offset = OFFSET_TO_VAL + param_length;
851 break;
852 case PARAM_ID_DESTINATION_PORT:
854 proto_tree *rtpsvt_tree_information_port;
855 uint32_t port = tvb_get_uint32(tvb, OFFSET_TO_VAL, ENC_BIG_ENDIAN);
857 rtpsvt_tree_information_port = proto_tree_add_subtree_format(
858 rtpsvt_tree_information,
859 tvb,
860 offset,
862 ett_rtpsvt_information_dst_port,
863 NULL,
864 "Destination port: %d",
865 port);
867 /* Add parameter identifier and length */
868 proto_tree_add_uint(
869 rtpsvt_tree_information_port,
870 hf_rtpsvt_param_id,
871 tvb,
872 offset,
873 2, /* length: sizeof(uint16_t) */
874 param_id);
875 offset += 2;
876 proto_tree_add_uint(
877 rtpsvt_tree_information_port,
878 hf_rtpsvt_param_length,
879 tvb,
880 offset,
881 2, /* length: sizeof(uint16_t) */
882 param_length);
883 offset += 2;
885 proto_tree_add_uint(
886 rtpsvt_tree_information_port,
887 hf_rtpsvt_destination_port,
888 tvb,
889 offset,
890 param_length,
891 port);
892 offset += param_length;
894 /* Add summary to protocol header */
895 proto_item_append_text(rtpsvt_tree_general, ":%d)", port);
897 /* Add summary to transport information header */
898 proto_item_append_text(
899 rtpsvt_tree_information,
900 ":%d)",
901 port);
904 * Add the destination port to pinfo.
905 * This is used by the RTPS dissector to get the domainId and
906 * participantIdx information displayed in discovery packets.
908 pinfo->destport = port;
910 break;
911 case PARAM_ID_DIRECTION:
913 proto_tree *rtpsvt_tree_direction;
914 uint8_t value = tvb_get_uint8(tvb, OFFSET_TO_VAL);
915 const char *direction = value ? "INBOUND" : "OUTBOUND";
917 rtpsvt_tree_direction = proto_tree_add_subtree_format(
918 rtpsvt_tree_general,
919 tvb,
920 offset,
922 ett_rtpsvt_information_src_addr,
923 NULL,
924 "Traffic Direction: %s",
925 direction);
927 /* Add parameter identifier and length */
928 proto_tree_add_uint(
929 rtpsvt_tree_direction,
930 hf_rtpsvt_param_id,
931 tvb,
932 offset,
933 2, /* length: sizeof(uint16_t) */
934 param_id);
935 offset += 2;
936 proto_tree_add_uint(
937 rtpsvt_tree_direction,
938 hf_rtpsvt_param_length,
939 tvb,
940 offset,
941 2, /* length: sizeof(uint16_t) */
942 param_length);
944 proto_tree_add_string(
945 rtpsvt_tree_direction,
946 hf_rtpsvt_direction,
947 tvb,
948 OFFSET_TO_VAL,
949 param_length,
950 direction);
951 offset = OFFSET_TO_VAL + param_length;
953 /* Save transport direction for the RTPS-PROC protocol */
954 transport_data->direction = value;
956 break;
958 return offset;
961 static int dissect_rtps_virtual_transport_loss_info_type(
962 tvbuff_t *tvb,
963 packet_info *pinfo,
964 proto_tree *tree_transport,
965 int offset)
968 uint16_t param_id;
970 param_id = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
971 offset += 2;
972 offset += 2; /* parameter length */
973 if (param_id == PARAM_ID_LOST_MESSAGES) {
974 uint64_t first_lost = tvb_get_uint64(tvb, offset, ENC_BIG_ENDIAN);
975 uint64_t last_lost = tvb_get_uint64(tvb, offset+8, ENC_BIG_ENDIAN);
977 if (pinfo->cinfo) {
978 char info[COL_MAX_INFO_LEN] = {'\0'};
979 snprintf(
980 info,
981 sizeof(info),
982 "Missing RTPS messages [%" PRIu64 "-%" PRIu64 "]",
983 first_lost,
984 last_lost);
985 col_append_str(pinfo->cinfo, COL_INFO, info);
987 expert_add_info(NULL, tree_transport, &ei_missing_msg);
990 return tvb_captured_length(tvb);
993 /* Register the protocol with Wireshark */
994 void
995 proto_register_rtps_virtual_transport(void)
997 expert_module_t* expert_info;
999 static hf_register_info hf[] = {
1001 &hf_rtpsvt_version,
1003 "Version", "rtpsvt.version",
1004 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL
1008 &hf_rtpsvt_version_major,
1010 "Major", "rtpsvt.version.major",
1011 FT_INT8, BASE_DEC, NULL, 0, NULL, HFILL
1015 &hf_rtpsvt_version_minor,
1017 "Minor", "rtpsvt.version.minor",
1018 FT_INT8, BASE_DEC, NULL, 0, NULL, HFILL
1022 &hf_rtpsvt_content_kind,
1024 "Content kind", "rtpsvt.content.kind",
1025 FT_INT8, BASE_DEC, NULL, 0, NULL, HFILL
1029 &hf_rtpsvt_param_id,
1031 "Parameter Identifier", "rtpsvt.param.id",
1032 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
1036 &hf_rtpsvt_param_length,
1038 "Parameter Length", "rtpsvt.param.length",
1039 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL
1043 &hf_rtpsvt_direction,
1045 "Traffic Direction", "rtpsvt.direction",
1046 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL
1050 &hf_rtpsvt_packet_identifier,
1052 "Packet identifier", "rtpsvt.identifier",
1053 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1057 &hf_rtpsvt_monitoring_guid,
1059 "GUID", "rtpsvt.monitoring_guid",
1060 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL
1064 &hf_rtpsvt_monitoring_seqNr,
1066 "SeqNum", "rtpsvt.seqNr",
1067 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL
1071 &hf_rtpsvt_information,
1073 "Transport Information", "rtpsvt.information",
1074 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL
1078 &hf_rtpsvt_source_port,
1080 "Source Port", "rtpsvt.source_port",
1081 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
1085 &hf_rtpsvt_source_address,
1087 "Source address", "rtpsvt.source_address",
1088 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
1092 &hf_rtpsvt_source_pid,
1094 "Source process ID", "rtpsvt.source_pid",
1095 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
1099 &hf_rtpsvt_destination_port,
1101 "Destination Port", "rtpsvt.port",
1102 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
1106 &hf_rtpsvt_destination_rtps_port,
1108 "Destination RTPS Port", "rtpsvt.rtps_port",
1109 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
1113 &hf_rtpsvt_destination_address,
1115 "Destination address", "rtpsvt.destination_address",
1116 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
1120 &hf_rtpsvt_destination_pid,
1122 "Destination process ID", "rtpsvt.destination_pid",
1123 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
1127 &hf_rtpsvt_class,
1129 "Transport class", "rtpsvt.class",
1130 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
1134 /* Information related to the 'lost' content type */
1135 &hf_rtpsvt_missing_messages,
1137 "Packets lost", "rtpsvt.missing_messages",
1138 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL
1143 static int *ett[] = {
1144 &ett_rtpsvt,
1145 &ett_rtpsvt_version,
1146 &ett_rtpsvt_identifier,
1147 &ett_rtpsvt_information,
1148 &ett_rtpsvt_information_class,
1149 &ett_rtpsvt_information_src_port,
1150 &ett_rtpsvt_information_dst_port,
1151 &ett_rtpsvt_information_src_addr,
1152 &ett_rtpsvt_information_dst_addr,
1153 &ett_rtpsvt_information_direction,
1154 &ett_rtpsvt_monitoring_sn,
1155 &ett_rtpsvt_frame
1158 static ei_register_info ei[] = {
1160 &ei_missing_msg,
1162 "rtpsvt.expert.missing_messages",
1163 PI_PROTOCOL,
1164 PI_NOTE,
1165 "Missing RTPS Messages because of full buffer pool",
1166 EXPFILL
1171 /* Register the protocol name and description */
1172 proto_rtpsvt = proto_register_protocol("Real-Time Publish-Subscribe Virtual Transport", "RTPS-VT", "rtpsvt");
1174 /* Required function calls to register the header fields and subtrees */
1175 rtpsvt_hf = proto_registrar_get_nth(proto_rtpsvt);
1176 proto_register_field_array(proto_rtpsvt, hf, array_length(hf));
1177 proto_register_subtree_array(ett, array_length(ett));
1179 /* Register expert information */
1180 expert_info = expert_register_protocol(proto_rtpsvt);
1181 expert_register_field_array(expert_info, ei, array_length(ei));
1183 register_dissector("rtpsvt", dissect_rtps_virtual_transport, proto_rtpsvt);
1187 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1189 * Local variables:
1190 * c-basic-offset: 4
1191 * tab-width: 8
1192 * indent-tabs-mode: nil
1193 * End:
1195 * vi: set shiftwidth=4 tabstop=8 expandtab:
1196 * :indentSize=4:tabSize=8:noTabs=true: