1 /* packet-rtps-virtual-transport.c
2 * Dissector for the Real-Time Publish-Subscribe (RTPS) Virtual Transport
5 * (c) 2020 Copyright, Real-Time Innovations, Inc.
6 * Real-Time Innovations, Inc.
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
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
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
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(
93 static int dissect_rtps_virtual_transport_rtps_type(
97 proto_tree
*tree_transport
,
99 struct rtpsvt_data
*transport_data
);
100 static int dissect_parameter_transport_rtps_type(
102 proto_tree
*rtpsvt_tree_general
,
103 proto_tree
*rtpsvt_tree_identifier
,
104 proto_tree
*rtpsvt_tree_information
,
107 struct rtpsvt_data
*transport_data
);
108 static int dissect_rtps_virtual_transport_loss_info_type(
111 proto_tree
*tree_transport
,
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" },
174 static int dissect_rtps_virtual_transport(
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
;
187 uint8_t content_type
;
188 const char *content_type_label
;
192 /* Add transport tree, used for the fields of our proto_rtpsvt */
193 rtpsvt_ti_transport
= proto_tree_add_item(
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
,
211 2, /* 2B: sizeof(uint16_t) */
214 transport_data
.version_major
,
215 transport_data
.version_minor
);
216 rtpsvt_tree_version
= proto_item_add_subtree(
222 hf_rtpsvt_version_major
,
225 1, /* length: sizeof(uint8_t) */
229 hf_rtpsvt_version_minor
,
232 1, /* length: sizeof(uint8_t) */
236 /* Add the content kind. */
237 content_type
= tvb_get_uint8(tvb
, offset
);
238 rtpsvt_ti_content_kind
= proto_tree_add_item(
240 hf_rtpsvt_content_kind
,
243 1, /* length: sizeof(uint8_t) */
245 if (content_type
== CONTENT_KIND_RTPS
) {
246 content_type_label
= "RTPS";
248 content_type_label
= "LOST_INFO";
250 proto_item_append_text(rtpsvt_ti_content_kind
, " (%s)", content_type_label
);
253 switch(content_type
) {
254 case CONTENT_KIND_RTPS
:
255 output
= dissect_rtps_virtual_transport_rtps_type(
259 rtpsvt_tree_transport
,
264 case CONTENT_KIND_LOSS_INFO
:
265 output
= dissect_rtps_virtual_transport_loss_info_type(
268 rtpsvt_tree_transport
,
275 static int dissect_rtps_virtual_transport_rtps_type(
279 proto_tree
*tree_transport
,
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
;
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(
299 hf_rtpsvt_packet_identifier
,
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(
314 hf_rtpsvt_information
,
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(
330 rtpsvt_tree_identifier
,
331 rtpsvt_tree_information
,
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.
345 param_id
= tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
347 param_length
= tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
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(
359 "Real-Time Publish-Subscribe Wire Protocol (content)");
366 2, /* 2B: sizeof(uint16_t) */
370 hf_rtpsvt_param_length
,
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
390 advanced_payload
= tvb_new_subset_length(tvb
, offset
, -1);
391 advanced_handle
= find_dissector("rtpsproc");
392 call_dissector_with_data(
397 (void *) transport_data
);
399 return tvb_captured_length(tvb
);
402 static int dissect_parameter_transport_rtps_type(
404 proto_tree
*rtpsvt_tree_general
,
405 proto_tree
*rtpsvt_tree_identifier
,
406 proto_tree
*rtpsvt_tree_information
,
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
;
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(
432 ndds_transport_class_id_vals
,
435 rtpsvt_tree_information_class
= proto_tree_add_subtree_format(
436 rtpsvt_tree_information
,
440 ett_rtpsvt_information_class
,
445 /* Add parameter identifier and length */
447 rtpsvt_tree_information_class
,
451 2, /* length: sizeof(uint16_t) */
455 rtpsvt_tree_information_class
,
456 hf_rtpsvt_param_length
,
459 2, /* length: sizeof(uint16_t) */
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
,
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
,
487 case PARAM_ID_MONITORING_GUID
:
489 proto_tree
*rtpsvt_tree_monitoring_guid
;
490 const uint8_t *guid_bytes
= tvb_get_ptr(
494 const char *guid_string
= bytes_to_str_punct(
497 MIN(param_length
, 12),
500 rtpsvt_tree_monitoring_guid
= proto_tree_add_subtree_format(
501 rtpsvt_tree_identifier
,
505 ett_rtpsvt_information_src_addr
,
507 "Monitoring GUID Prefix: %s",
510 /* Add parameter identifier and length */
512 rtpsvt_tree_monitoring_guid
,
516 2, /* length: sizeof(uint16_t) */
520 rtpsvt_tree_monitoring_guid
,
521 hf_rtpsvt_param_length
,
524 2, /* length: sizeof(uint16_t) */
529 rtpsvt_tree_monitoring_guid
,
530 hf_rtpsvt_monitoring_guid
,
535 offset
+= param_length
;
537 /* Add summary to packet identifier header */
538 proto_item_append_text(
539 rtpsvt_tree_identifier
,
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
,
554 ett_rtpsvt_monitoring_sn
,
556 "Monitoring Sequence Number: %" PRIu64
,
559 /* Add parameter identifier and length */
565 2, /* length: sizeof(uint16_t) */
570 hf_rtpsvt_param_length
,
573 2, /* length: sizeof(uint16_t) */
577 proto_tree_add_uint64(
579 hf_rtpsvt_monitoring_seqNr
,
584 offset
+= param_length
;
586 /* Add summary to packet identifier header */
587 proto_item_append_text(
588 rtpsvt_tree_identifier
,
589 ", SeqNum: %" PRIu64
,
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(
610 OFFSET_TO_VAL
+ (int) (strlen(prefix
)),
612 snprintf(addr
, sizeof(addr
), "%u", pid
);
616 sizeof(bytes_zeroed
)) == 0){
621 tvb_ip_to_str(pinfo
->pool
, tvb
, OFFSET_TO_VAL
+ sizeof(bytes_zeroed
)));
627 tvb_ip6_to_str(pinfo
->pool
, tvb
, OFFSET_TO_VAL
));
630 /* Add source to destination column field */
632 col_append_str(pinfo
->cinfo
, COL_DEF_SRC
, addr
);
635 rtpsvt_tree_information_address
= proto_tree_add_subtree_format(
636 rtpsvt_tree_information
,
640 ett_rtpsvt_information_src_addr
,
646 /* Add parameter identifier and length */
648 rtpsvt_tree_information_address
,
652 2, /* length: sizeof(uint16_t) */
656 rtpsvt_tree_information_address
,
657 hf_rtpsvt_param_length
,
660 2, /* length: sizeof(uint16_t) */
664 /* Add source to the transport information tree */
665 proto_tree_add_string(
666 rtpsvt_tree_information_address
,
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
,
684 case PARAM_ID_SOURCE_PORT
:
686 proto_tree
*rtpsvt_tree_information_port
;
687 uint32_t port
= tvb_get_uint32(
692 rtpsvt_tree_information_port
= proto_tree_add_subtree_format(
693 rtpsvt_tree_information
,
697 ett_rtpsvt_information_src_port
,
702 /* Add parameter identifier and length */
704 rtpsvt_tree_information_port
,
708 2, /* length: sizeof(uint16_t) */
712 rtpsvt_tree_information_port
,
713 hf_rtpsvt_param_length
,
716 2, /* length: sizeof(uint16_t) */
721 rtpsvt_tree_information_port
,
722 hf_rtpsvt_source_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
,
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
;
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(
763 OFFSET_TO_VAL
+ (int) (strlen(prefix
)),
765 snprintf(addr
, sizeof(addr
), "%u", pid
);
769 sizeof(bytes_zeroed
)) == 0){
774 tvb_ip_to_str(pinfo
->pool
, tvb
, OFFSET_TO_VAL
+ sizeof(bytes_zeroed
)));
780 tvb_ip6_to_str(pinfo
->pool
, tvb
, OFFSET_TO_VAL
));
783 /* Add address to destination column field */
785 col_append_str(pinfo
->cinfo
, COL_DEF_DST
, addr
);
788 rtpsvt_tree_information_address
= proto_tree_add_subtree_format(
789 rtpsvt_tree_information
,
793 ett_rtpsvt_information_dst_addr
,
799 /* Add parameter identifier and length */
801 rtpsvt_tree_information_address
,
805 2, /* length: sizeof(uint16_t) */
809 rtpsvt_tree_information_address
,
810 hf_rtpsvt_param_length
,
813 2, /* length: sizeof(uint16_t) */
817 /* Add destination to the transport information tree */
818 proto_tree_add_string(
819 rtpsvt_tree_information_address
,
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
,
837 case PARAM_ID_DESTINATION_RTPS_PORT
:
839 uint32_t port
= tvb_get_uint32(tvb
, OFFSET_TO_VAL
, ENC_BIG_ENDIAN
);
842 rtpsvt_tree_information
,
843 hf_rtpsvt_destination_rtps_port
,
849 offset
= OFFSET_TO_VAL
+ param_length
;
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
,
862 ett_rtpsvt_information_dst_port
,
864 "Destination port: %d",
867 /* Add parameter identifier and length */
869 rtpsvt_tree_information_port
,
873 2, /* length: sizeof(uint16_t) */
877 rtpsvt_tree_information_port
,
878 hf_rtpsvt_param_length
,
881 2, /* length: sizeof(uint16_t) */
886 rtpsvt_tree_information_port
,
887 hf_rtpsvt_destination_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
,
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
;
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(
922 ett_rtpsvt_information_src_addr
,
924 "Traffic Direction: %s",
927 /* Add parameter identifier and length */
929 rtpsvt_tree_direction
,
933 2, /* length: sizeof(uint16_t) */
937 rtpsvt_tree_direction
,
938 hf_rtpsvt_param_length
,
941 2, /* length: sizeof(uint16_t) */
944 proto_tree_add_string(
945 rtpsvt_tree_direction
,
951 offset
= OFFSET_TO_VAL
+ param_length
;
953 /* Save transport direction for the RTPS-PROC protocol */
954 transport_data
->direction
= value
;
961 static int dissect_rtps_virtual_transport_loss_info_type(
964 proto_tree
*tree_transport
,
970 param_id
= tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
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
);
978 char info
[COL_MAX_INFO_LEN
] = {'\0'};
982 "Missing RTPS messages [%" PRIu64
"-%" PRIu64
"]",
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 */
995 proto_register_rtps_virtual_transport(void)
997 expert_module_t
* expert_info
;
999 static hf_register_info hf
[] = {
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
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
[] = {
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
,
1158 static ei_register_info ei
[] = {
1162 "rtpsvt.expert.missing_messages",
1165 "Missing RTPS Messages because of full buffer pool",
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
1192 * indent-tabs-mode: nil
1195 * vi: set shiftwidth=4 tabstop=8 expandtab:
1196 * :indentSize=4:tabSize=8:noTabs=true: