2 * Routines for Real-Time Publish-Subscribe Protocol (RTPS) dissection
4 * Copyright 2003, LUKAS POKORNY <maskis@seznam.cz>
5 * PETR SMOLIK <petr.smolik@wo.cz>
6 * ZDENEK SEBEK <sebek@fel.cvut.cz>
8 * Czech Technical University in Prague
9 * Faculty of Electrical Engineering <www.fel.cvut.cz>
10 * Department of Control Engineering <dce.felk.cvut.cz>
12 * version: 2004/04/15 9:40:45
17 * Ethereal - Network traffic analyzer
18 * By Gerald Combs <gerald@ethereal.com>
19 * Copyright 1998 Gerald Combs
21 * Copied from packet-udp.c, packet-tftp.c, packet-x25.c
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 * *********************************************************************** */
43 #ifdef NEED_SNPRINTF_H
44 # include "snprintf.h"
51 #include <epan/packet.h>
52 #include <epan/resolv.h>
53 #include <epan/conversation.h>
56 /* *********************************************************************** *
57 RTPS protocol was developed by Real Time Innovation, Inc.
59 Protocol specifikation and documenation you can find on these addresses:
63 http://www.rti.com/products/ndds/literature.html
65 http://www.schneider-electric.com.au/Products/Automation/TF_RealTime/
66 /technical%20library/specifications/WireProtocolExternal.pdf
69 * *********************************************************************** */
73 /* redefine types because of definitions in 'packet-rtps.h' */
75 #define u_int8_t guint8
78 #define u_int16_t guint16
79 #define int16_t gint16
81 #define u_int32_t guint32
82 #define int32_t gint32
85 #include "packet-rtps.h"
87 /* number of APP_KIND byte in packet header */
88 #define APP_KIND_BYTE 15
91 /* definitions of flags */
101 /* submessageId's ranges */
102 #define SUBMSG_ID_MIN PAD
103 #define SUBMSG_ID_MAX INFO_DST
105 /* Vendor specific submessageId's ranges */
106 #define VENDOR_SUBMSG_ID_MIN 0x80
107 #define VENDOR_SUBMSG_ID_MAX 0xff
109 /* *********************************************************************** */
112 /* initialize the protocol and registered fields */
113 static int proto_rtps = -1;
114 static int hf_rtps_submessage_id = -1;
115 static int hf_rtps_submessage_flags = -1;
116 static int hf_rtps_octets_to_next_header = -1;
117 static int hf_rtps_parameter_id = -1;
118 static int hf_rtps_parameter_length = -1;
119 static int hf_rtps_issue_data = -1;
121 /* Initialize the subtree pointers */
122 static gint ett_rtps = -1;
123 static gint ett_rtps_submessage = -1;
124 static gint ett_rtps_bitmap = -1;
125 static gint ett_rtps_parameter_sequence = -1;
126 static gint ett_rtps_parameter = -1;
128 /* Functions declarations */
129 static void dissect_PAD(tvbuff_t *tvb,gint offset,guint8 flags,
130 int next_submsg_offset,
131 proto_tree *rtps_submessage_tree);
132 static void dissect_VAR(tvbuff_t *tvb,gint offset,guint8 flags,
133 gboolean little_endian,int next_submsg_offset,
134 proto_tree *rtps_submessage_tree);
135 static void dissect_ISSUE(tvbuff_t *tvb,gint offset,guint8 flags,
136 gboolean little_endian,int next_submsg_offset,
137 proto_tree *rtps_submessage_tree);
138 static void dissect_ACK(tvbuff_t *tvb,gint offset,guint8 flags,
139 gboolean little_endian,int next_submsg_offset,
140 proto_tree *rtps_submessage_tree);
141 static void dissect_HEARTBEAT(tvbuff_t *tvb,gint offset,guint8 flags,
142 gboolean little_endian,int next_submsg_offset,
143 proto_tree *rtps_submessage_tree);
144 static void dissect_GAP(tvbuff_t *tvb,gint offset,guint8 flags,
145 gboolean little_endian,int next_submsg_offset,
146 proto_tree *rtps_submessage_tree);
147 static void dissect_INFO_TS(tvbuff_t *tvb,gint offset,guint8 flags,
148 gboolean little_endian,int next_submsg_offset,
149 proto_tree *rtps_submessage_tree);
150 static void dissect_INFO_SRC(tvbuff_t *tvb,gint offset,guint8 flags,
151 gboolean little_endian,int next_submsg_offset,
152 proto_tree *rtps_submessage_tree);
153 static void dissect_INFO_REPLY(tvbuff_t *tvb,gint offset,guint8 flags,
154 gboolean little_endian,int next_submsg_offset,
155 proto_tree *rtps_submessage_tree);
156 static void dissect_INFO_DST(tvbuff_t *tvb,gint offset,guint8 flags,
157 int next_submsg_offset,
158 proto_tree *rtps_submessage_tree);
160 static guint16 get_guint16(tvbuff_t *tvb, gint offset, gboolean little_endian);
161 static guint32 get_guint32(tvbuff_t *tvb, gint offset, gboolean little_endian);
163 static char *protocol_version_to_string(gint offset,tvbuff_t *tvb,char *buff);
164 static char *vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff);
166 static char *host_id_to_string(gint offset,tvbuff_t *tvb, char buff[]);
167 static char *app_id_to_string(gint offset,tvbuff_t *tvb,char buff[]);
168 static char *object_id_to_string(gint offset, tvbuff_t *tvb, char buff[]);
170 static char *IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]);
171 static char *port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]);
172 static char *get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]);
174 static void get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
175 gint next_submsg, proto_tree *tree);
177 static void get_parameter_sequence(tvbuff_t *tvb, gint *p_offset,
178 gboolean little_endian,
179 gint next_submsg_offset, proto_tree *tree);
181 static gint seq_nr_to_string( gint offset, gboolean little_endian, tvbuff_t *tvb,
182 SequenceNumber *p_seqNumber);
184 static const value_string submessage_id_vals[] = {
189 { HEARTBEAT, "HEARTBEAT" },
191 { INFO_TS, "INFO_TS" },
192 { INFO_SRC, "INFO_SRC" },
193 { INFO_REPLY, "INFO_REPLY" },
194 { INFO_DST, "INFO_DST" },
195 { APP_QUIT, "APP_QUIT" },
199 static const value_string parameter_id_vals[] = {
200 { PID_PAD, "PID_PAD" },
201 { PID_SENTINEL, "PID_SENTINEL" },
202 { PID_EXPIRATION_TIME, "PID_EXPIRATION_TIME" },
203 { PID_PERSISTENCE, "PID_PERSISTENCE" },
204 { PID_MINIMUM_SEPARATION, "PID_MINIMUM_SEPARATION" },
205 { PID_TOPIC, "PID_TOPIC" },
206 { PID_STRENGTH, "PID_STRENGTH" },
207 { PID_TYPE_NAME, "PID_TYPE_NAME" },
208 { PID_TYPE_CHECKSUM, "PID_TYPE_CHECKSUM" },
209 { RTPS_PID_TYPE2_NAME, "RTPS_PID_TYPE2_NAME" },
210 { RTPS_PID_TYPE2_CHECKSUM, "RTPS_PID_TYPE2_CHECKSUM" },
211 { PID_METATRAFFIC_MULTICAST_IPADDRESS, "PID_METATRAFFIC_MULTICAST_IPADDRESS" },
212 { PID_APP_IPADDRESS, "PID_APP_IPADDRESS" },
213 { PID_METATRAFFIC_UNICAST_PORT, "PID_METATRAFFIC_UNICAST_PORT" },
214 { PID_USERDATA_UNICAST_PORT, "PID_USERDATA_UNICAST_PORT" },
215 { PID_IS_RELIABLE, "PID_IS_RELIABLE" },
216 { PID_EXPECTS_ACK, "PID_EXPECTS_ACK" },
217 { PID_USERDATA_MULTICAST_IPADDRESS, "PID_USERDATA_MULTICAST_IPADDRESS" },
218 { PID_MANAGER_KEY, "PID_MANAGER_KEY" },
219 { PID_SEND_QUEUE_SIZE, "PID_SEND_QUEUE_SIZE" },
220 { PID_RELIABILITY_ENABLED, "PID_RELIABILITY_ENABLED" },
221 { PID_PROTOCOL_VERSION, "PID_PROTOCOL_VERSION" },
222 { PID_VENDOR_ID, "PID_VENDOR_ID" },
223 { PID_VARGAPPS_SEQUENCE_NUMBER_LAST, "PID_VARGAPPS_SEQUENCE_NUMBER_LAST" },
224 { PID_RECV_QUEUE_SIZE, "PID_RECV_QUEUE_SIZE" },
225 { PID_RELIABILITY_OFFERED, "PID_RELIABILITY_OFFERED" },
226 { PID_RELIABILITY_REQUESTED, "PID_RELIABILITY_REQUESTED" },
230 /* *********************************************************************** */
233 /* *********************************************************************** *
235 * Code to actually dissect the packets *
237 * *********************************************************************** */
240 dissect_rtps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
243 proto_tree *rtps_tree=NULL;
246 proto_tree *rtps_submessage_tree;
249 gboolean little_endian;
251 int count_msg_type[11];
252 char buff[200], buff_tmp[30];/* buffers */
254 /* offset is the byte offset of 'tvb' at which the new tvbuff
255 should start. The first byte is the 0th byte. */
257 /* --- making disition if protocol is RTPS protocol --- */
258 if (!tvb_bytes_exist(tvb, offset, 4)) return FALSE;
259 if (tvb_get_guint8(tvb,offset++) != 'R') return FALSE;
260 if (tvb_get_guint8(tvb,offset++) != 'T') return FALSE;
261 if (tvb_get_guint8(tvb,offset++) != 'P') return FALSE;
262 if (tvb_get_guint8(tvb,offset++) != 'S') return FALSE;
264 /* --- Make entries in Protocol column ---*/
265 if (check_col(pinfo->cinfo, COL_PROTOCOL))
266 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPS");
268 if (check_col(pinfo->cinfo, COL_INFO))
269 col_clear(pinfo->cinfo, COL_INFO);
271 memset(count_msg_type, 0, sizeof(count_msg_type));
275 /* create display subtree for the protocol */
276 ti = proto_tree_add_item(tree, proto_rtps, tvb, 0, -1, FALSE);
277 rtps_tree = proto_item_add_subtree(ti, ett_rtps);
279 /* Protocol Version */
280 proto_tree_add_text(rtps_tree, tvb, offset, 2,
281 "Protocol RTPS, version %s",
282 protocol_version_to_string(offset, tvb, buff));
286 proto_tree_add_text(rtps_tree, tvb, offset, 2,
288 vendor_id_to_string(offset, tvb, buff));
292 proto_tree_add_text(rtps_tree, tvb, offset, 4,
294 host_id_to_string(offset,tvb,buff));
298 proto_tree_add_text(rtps_tree, tvb, offset, 4,
300 app_id_to_string(offset, tvb, buff));
304 /* offset behind RTPS's Header */
307 while (tvb_reported_length_remaining(tvb, offset) > 0) {
308 submessageId = tvb_get_guint8(tvb, offset);
309 if (submessageId & 0x80) {
310 ti = proto_tree_add_text(tree, tvb, offset, -1, "Submessage: %s",
311 val_to_str(submessageId, submessage_id_vals,
312 "Vendor-specific (0x%02X)"));
314 ti = proto_tree_add_text(tree, tvb, offset, -1, "Submessage: %s",
315 val_to_str(submessageId, submessage_id_vals,
316 "Unknown (0x%02X)"));
318 rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
319 if (submessageId & 0x80) {
320 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_submessage_id,
321 tvb, offset, 1, submessageId,
322 "Submessage Id: Vendor-specific (0x%02x)",
325 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_id,
326 tvb, offset, 1, submessageId);
329 flags = tvb_get_guint8(tvb, offset + 1);
330 /* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
331 if ((flags & FLAG_E) != 0) little_endian = TRUE;
332 else little_endian = FALSE;
334 next_submsg = get_guint16(tvb, offset + 2, little_endian);
335 proto_item_set_len(ti, next_submsg);
337 switch (submessageId)
341 dissect_PAD(tvb, offset + 1, flags, next_submsg,
342 rtps_submessage_tree);
347 dissect_VAR(tvb, offset + 1, flags, little_endian, next_submsg,
348 rtps_submessage_tree);
353 dissect_ISSUE(tvb, offset + 1, flags, little_endian, next_submsg,
354 rtps_submessage_tree);
359 dissect_ACK(tvb, offset + 1, flags, little_endian, next_submsg,
360 rtps_submessage_tree);
365 dissect_HEARTBEAT(tvb, offset + 1, flags, little_endian, next_submsg,
366 rtps_submessage_tree);
371 dissect_GAP(tvb, offset + 1, flags, little_endian, next_submsg,
372 rtps_submessage_tree);
377 dissect_INFO_TS(tvb, offset + 1, flags, little_endian, next_submsg,
378 rtps_submessage_tree);
383 dissect_INFO_SRC(tvb, offset + 1, flags, little_endian, next_submsg,
384 rtps_submessage_tree);
389 dissect_INFO_REPLY(tvb, offset + 1, flags, little_endian, next_submsg,
390 rtps_submessage_tree);
395 dissect_INFO_DST(tvb, offset + 1, flags, next_submsg,
396 rtps_submessage_tree);
401 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
402 tvb, offset + 1, 1, flags);
403 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
404 tvb, offset + 2, 2, next_submsg);
409 /* next submessage's offset */
410 offset += next_submsg+4;
414 /* --- and Info column on summary display ---*/
416 if (check_col(pinfo->cinfo, COL_INFO))
418 appKind = tvb_get_guint8(tvb, APP_KIND_BYTE);
420 if (appKind == MANAGEDAPPLICATION ) {sprintf(buff,"App: ");}
421 if (appKind == MANAGER) {sprintf(buff,"Man: ");}
422 if (appKind == AID_UNKNOWN) {sprintf(buff,"Unknown:");}
424 if (appKind != MANAGEDAPPLICATION && appKind != MANAGER &&
425 appKind != AID_UNKNOWN) {sprintf(buff,"ERROR in APP type");}
427 /* -- counts of submessages - for Information Frame */
428 if (count_msg_type[0]>0) {
429 sprintf(buff_tmp,"PAD(%d) ",count_msg_type[0]);
430 strcat(buff,buff_tmp);
433 if (count_msg_type[1]>0) {
434 sprintf(buff_tmp,"VAR(%d) ",count_msg_type[1]);
435 strcat(buff,buff_tmp);
438 if (count_msg_type[2]>0) {
439 sprintf(buff_tmp,"ISSUE(%d) ",count_msg_type[2]);
440 strcat(buff,buff_tmp);
443 if (count_msg_type[3]>0) {
444 sprintf(buff_tmp,"ACK(%d) ",count_msg_type[3]);
445 strcat(buff,buff_tmp);
448 if (count_msg_type[4]>0) {
449 sprintf(buff_tmp,"HEARTBEAT(%d) ",count_msg_type[4]);
450 strcat(buff,buff_tmp);
453 if (count_msg_type[5]>0) {
454 sprintf(buff_tmp,"GAP(%d) ",count_msg_type[5]);
455 strcat(buff,buff_tmp);
458 if (count_msg_type[6]>0) {
459 sprintf(buff_tmp,"INFO_TS(%d) ",count_msg_type[6]);
460 strcat(buff,buff_tmp);
463 if (count_msg_type[7]>0) {
464 sprintf(buff_tmp, "INFO_SRC(%d) ",count_msg_type[7]);
465 strcat(buff,buff_tmp);
468 if (count_msg_type[8]>0) {
469 sprintf(buff_tmp,"INFO_REPLY(%d) ",count_msg_type[8]);
470 strcat(buff,buff_tmp);
473 if (count_msg_type[9]>0) {
474 sprintf(buff_tmp,"INFO_DST(%d) ",count_msg_type[9]);
475 strcat(buff,buff_tmp);
478 if (count_msg_type[10]>0) {
479 sprintf(buff_tmp,"vendor specific(%d) ",count_msg_type[10]);
480 strcat(buff,buff_tmp);
483 col_add_fstr(pinfo->cinfo, COL_INFO, buff);
490 } /* end dissect_rtps(...) */
492 /* *********************************************************************** */
495 /* *********************************************************************** *
497 * get 16 bit from the stream *
499 * *********************************************************************** */
501 static guint16 get_guint16(tvbuff_t *tvb, gint offset, gboolean little_endian)
506 value = tvb_get_letohs(tvb, offset);
508 value = tvb_get_ntohs(tvb, offset);
513 /* *********************************************************************** */
516 /* *********************************************************************** *
518 * get 32 bit from the stream *
520 * *********************************************************************** */
522 static guint32 get_guint32(tvbuff_t *tvb, gint offset, gboolean little_endian)
527 value = tvb_get_letohl(tvb, offset);
529 value = tvb_get_ntohl(tvb, offset);
534 /* *********************************************************************** */
537 /* *********************************************************************** *
539 * get Protocol version *
541 * *********************************************************************** */
544 protocol_version_to_string(gint offset,tvbuff_t *tvb,char *buff)
548 /* protocol verzion = major.minor */
549 major = tvb_get_guint8(tvb, offset);
550 minor = tvb_get_guint8(tvb, (offset+1));
552 sprintf(buff,"%d.%d", major, minor);
557 /* *********************************************************************** */
560 /* *********************************************************************** *
564 * *********************************************************************** */
567 vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff)
570 VendorId vendorId_rti;
572 VENDOR_ID_RTI(vendorId_rti);
574 major = tvb_get_guint8(tvb, offset);
575 minor = tvb_get_guint8(tvb, (offset+1));
577 if (major == vendorId_rti.major &&
578 minor == vendorId_rti.minor)
579 { sprintf(buff,"Real-Time Innovations,Inc.,CA,USA");
582 sprintf(buff,"Vendor unknown");
586 /* *********************************************************************** */
589 /* *********************************************************************** *
593 * *********************************************************************** */
596 IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[])
599 guint8 a = 0, b = 0, c = 0, d = 0; /* IP Adresss = a.b.c.d */
601 ip = get_guint32(tvb, offset, little_endian);
602 /* get_guint32() - reads + endian conversion */
604 b = (ip >> 16) & 0xff;
605 c = (ip >> 8) & 0xff;
608 sprintf(buff,"%d.%d.%d.%d", a, b, c, d);
612 /* *********************************************************************** */
615 /* *********************************************************************** *
619 * *********************************************************************** */
622 port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[])
624 Port port = get_guint32(tvb, offset, little_endian);
625 /* get_guint32() - reads + endian conversion */
627 if (port == PORT_INVALID)
628 sprintf(buff,"PORT_INVALID");
630 sprintf(buff,"0x%X",port);
635 /* *********************************************************************** */
638 /* *********************************************************************** *
642 * *********************************************************************** */
645 get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[])
650 /* get_guint32() - reads + endian conversion */
651 ntpTime.seconds = get_guint32(tvb, offset, little_endian);
652 ntpTime.fraction = get_guint32(tvb, (offset + 4), little_endian);
653 time = (float) ntpTime.seconds + (ntpTime.fraction / 2^(32));
655 sprintf(buff,"%f", time);
659 /* *********************************************************************** */
662 /* *********************************************************************** *
666 * *********************************************************************** */
669 host_id_to_string(gint offset,tvbuff_t *tvb, char buff[])
671 guint32 hostId = tvb_get_ntohl(tvb, offset);
672 /* get_ntohl() automaticaly convert data to BIG ENDIAN */
674 sprintf(buff,"0x%X", hostId);
678 /* *********************************************************************** */
681 /* *********************************************************************** *
685 * *********************************************************************** */
688 app_id_to_string(gint offset,tvbuff_t *tvb,char buff[])
690 guint32 appId = tvb_get_ntohl(tvb, offset);
691 /* get_ntohl() automaticaly convert data to BIG ENDIAN */
694 guint32 instanceId = (appId >> 8);
695 /* applicatin Kind */
696 guint8 appKind = (appId & 0xff);
698 if (appKind == MANAGEDAPPLICATION)
700 sprintf(buff,"Managed App, InstanceId: 0x%X",instanceId);
704 if (appKind == MANAGER)
706 sprintf(buff,"Manager, InstanceId: 0x%X",instanceId);
710 sprintf(buff,"Unknown");
715 /* *********************************************************************** */
718 /* *********************************************************************** *
720 * get Object_Id (32 bit) *
722 * *********************************************************************** */
725 object_id_to_string(gint offset, tvbuff_t *tvb, char buff[])
727 guint32 objectId = tvb_get_ntohl(tvb, offset);
728 /* get_ntohl() automaticaly convert data to BIG ENDIAN */
730 if (objectId == OID_UNKNOWN) { sprintf(buff,"Unknown ObjectId");
732 if (objectId == OID_APP) { sprintf(buff,"applicationSelf");
734 if (objectId == OID_WRITE_APPSELF){ sprintf(buff,"writerApplicationSelf");
736 if (objectId == OID_WRITE_APP) { sprintf(buff,"writerApplications");
738 if (objectId == OID_READ_APP) { sprintf(buff,"readerApplications");
740 if (objectId == OID_WRITE_MGR) { sprintf(buff,"writerManagers");
742 if (objectId == OID_READ_MGR) { sprintf(buff,"readerManagers ");
744 if (objectId == OID_WRITE_PUBL) { sprintf(buff,"writerPublications");
746 if (objectId == OID_READ_PUBL) { sprintf(buff,"readerPublications");
748 if (objectId == OID_WRITE_SUBS) { sprintf(buff,"writerSubscriptions");
750 if (objectId == OID_READ_SUBS) { sprintf(buff,"readerSubscriptions");
753 /* nothing from the possibilites above */
754 sprintf(buff,"instanceId: 0x%X, objKind: 0x%X",
755 (objectId >> 8),(objectId & 0xff));
760 #define OID_APPLICATION 0x01
761 #define OID_CSTWRITER 0x02
762 #define OID_PUBLICATION 0x03
763 #define OID_SUBSCRIPTION 0x04
764 #define OID_CSTREADER 0x07
766 #define OID_USEROBJ 0x00
767 #define OID_RESUSEROBJ 0x40
768 #define OID_METAOBJ 0x80
769 #define OID_RESMETAOBJ 0xC0
773 /* *********************************************************************** */
776 /* *********************************************************************** *
778 * get Sequence Number (64 bit) *
780 * *********************************************************************** */
783 seq_nr_to_string(gint offset, gboolean little_endian, tvbuff_t *tvb,
784 SequenceNumber *p_seqNumber)
786 p_seqNumber->high = get_guint32(tvb, offset, little_endian);
787 p_seqNumber->low = get_guint32(tvb, offset + 4, little_endian);
792 /* *********************************************************************** */
795 /* *********************************************************************** *
799 * *********************************************************************** */
802 get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
803 gint next_submsg, proto_tree *tree)
806 proto_tree *rtps_bitmap_tree;
808 gint offset = *p_offset;
809 SequenceNumber sequenceNumber;
813 /* making subtree for the bitmap */
814 ti = proto_tree_add_text(tree,tvb,offset,(next_submsg-offset),"Bitmap");
815 rtps_bitmap_tree = proto_item_add_subtree(ti, ett_rtps_bitmap);
817 /* SekvenceNumber bitmapBase */
818 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
819 proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 8,
820 "bitmapBase: 0x%X%X",
821 sequenceNumber.high, sequenceNumber.low);
824 num_bits = get_guint32(tvb, offset, little_endian);
825 proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
830 if (num_bits+31 < num_bits)
831 num_longs = UINT_MAX; /* overflow */
833 num_longs = (num_bits+31)/32;
834 while (num_longs != 0)
836 if (next_submsg-offset < 4)
838 proto_tree_add_text(rtps_bitmap_tree, tvb, offset, next_submsg-offset,
839 "bitmap[%d]: < 4 bytes remain in message", i);
840 offset = next_submsg;
843 proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
844 "bitmap[%d]: 0x%08X",
845 i, get_guint32(tvb, offset, little_endian));
854 /* *********************************************************************** */
857 /* *********************************************************************** *
859 * dissect submessage: PAD *
861 * (this submessage has no meaning and it is always valid) *
862 * *********************************************************************** */
865 dissect_PAD(tvbuff_t *tvb, gint offset, guint8 flags,
866 int next_submsg_offset, proto_tree *rtps_submessage_tree)
868 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
869 tvb, offset, 1, flags);
872 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
873 tvb, offset, 2, next_submsg_offset);
875 next_submsg_offset += offset;
878 /* *********************************************************************** */
881 /* *********************************************************************** *
883 * dissect submessage: VAR *
885 * *********************************************************************** */
888 dissect_VAR(tvbuff_t *tvb, gint offset, guint8 flags, gboolean little_endian,
889 int next_submsg_offset, proto_tree *rtps_submessage_tree)
893 SequenceNumber writerSeqNumber;
895 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
896 tvb, offset, 1, flags);
900 if ((flags & FLAG_H) != 0)
902 if ((flags & FLAG_P) != 0)
904 if (next_submsg_offset < min_len)
906 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
907 tvb, offset, 2, next_submsg_offset,
908 "Octets to next header: %u (bogus, must be >= %u)",
909 next_submsg_offset, min_len);
912 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
913 tvb, offset, 2, next_submsg_offset);
915 next_submsg_offset += offset;
918 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
919 "Reader Object ID: %s ",
920 object_id_to_string(offset, tvb, buff));
924 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
925 "Writer Object ID: %s ",
926 object_id_to_string(offset, tvb, buff));
929 /* H flag |XXXX|HAPE| => masks with 00001000b = 8 */
930 if ((flags & FLAG_H) != 0)
933 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
935 host_id_to_string(offset,tvb,buff));
939 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
941 app_id_to_string(offset, tvb, buff));
946 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
948 object_id_to_string(offset, tvb, buff));
951 /* WriterSequence Number */
952 seq_nr_to_string(offset, little_endian, tvb, &writerSeqNumber);
953 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
954 "WriterSeqNumber: 0x%X%X",
955 writerSeqNumber.high, writerSeqNumber.low);
958 /* P flag |XXXX|HAPE| => masks with 00000010b = 2 */
959 if ((flags & FLAG_P) != 0)
961 get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
962 rtps_submessage_tree);
966 /* *********************************************************************** */
968 /* *********************************************************************** *
970 * get_ParameterSequence *
972 * *********************************************************************** */
976 get_parameter_sequence(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
977 gint next_submsg_offset, proto_tree *tree)
980 proto_tree *rtps_parameter_sequence_tree;
981 proto_tree *rtps_parameter_tree;
982 gint offset = *p_offset;
983 guint16 parameter, param_length;
985 SequenceNumber seqNumber;
986 char buff_tmp[MAX_PATHNAME];
990 ti = proto_tree_add_text(tree, tvb, offset, (next_submsg_offset - offset),
992 rtps_parameter_sequence_tree = proto_item_add_subtree(ti,
993 ett_rtps_parameter_sequence);
996 if (next_submsg_offset-offset < 2)
998 proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset,
999 next_submsg_offset-offset,
1000 "Parameter: < 2 bytes remain in message");
1001 offset = next_submsg_offset;
1004 parameter = get_guint16(tvb, offset, little_endian);
1005 ti = proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset, 2,
1007 val_to_str(parameter, parameter_id_vals,
1008 "Unknown parameter (0x%04X)"));
1009 rtps_parameter_tree = proto_item_add_subtree(ti, ett_rtps_parameter);
1010 proto_tree_add_uint(rtps_parameter_tree, hf_rtps_parameter_id,
1011 tvb, offset, 2, parameter);
1013 if (next_submsg_offset-offset < 2)
1015 proto_tree_add_text(rtps_parameter_tree, tvb, offset,
1016 next_submsg_offset-offset,
1017 "Parameter length: < 2 bytes remain in message");
1018 offset = next_submsg_offset;
1019 proto_item_set_end(ti, tvb, offset);
1022 param_length = get_guint16(tvb, offset, little_endian);
1023 proto_tree_add_uint(rtps_parameter_tree, hf_rtps_parameter_length,
1024 tvb, offset, 2, param_length);
1027 if (parameter == PID_SENTINEL) {
1028 proto_item_set_end(ti, tvb, offset);
1032 if (next_submsg_offset-offset < param_length)
1034 proto_tree_add_text(rtps_parameter_tree, tvb, offset,
1035 next_submsg_offset-offset,
1036 "Parameter value: < %u bytes remain in message",
1038 offset = next_submsg_offset;
1039 proto_item_set_end(ti, tvb, offset);
1042 proto_item_set_end(ti, tvb, offset + param_length);
1047 proto_item_append_text(ti, ": -");
1048 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1052 case PID_EXPIRATION_TIME:
1053 if (param_length < 8)
1055 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1056 "Bad parameter: length < 8");
1062 ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp);
1063 proto_item_append_text(ti, ": %s", ntp_time_str);
1064 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1065 "Expiration time: %s", ntp_time_str);
1069 case PID_PERSISTENCE:
1070 if (param_length < 8)
1072 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1073 "Bad parameter: length < 8");
1079 ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp);
1080 proto_item_append_text(ti, ": %s", ntp_time_str);
1081 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1082 "Persistence: %s", ntp_time_str);
1086 case PID_MINIMUM_SEPARATION:
1087 if (param_length < 8)
1089 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1090 "Bad parameter: length < 8");
1096 ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp);
1097 proto_item_append_text(ti, ": %s", ntp_time_str);
1098 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1099 "Minimum separation: %s", ntp_time_str);
1103 case PID_TOPIC: /* --- ?? funguje spravne ?? */
1104 str_length = tvb_strnlen(tvb, offset, param_length);
1105 if (str_length == -1)
1107 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1108 "Bad parameter: Terminating zero missing");
1114 str = tvb_format_text(tvb, offset, str_length);
1115 proto_item_append_text(ti, ": %s", str);
1116 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1122 if (param_length < 4)
1124 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1125 "Bad parameter: length < 4");
1131 strength = get_guint32(tvb, offset, little_endian);
1132 proto_item_append_text(ti, ": 0x%X", strength);
1133 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1134 "Strength: 0x%X", strength);
1138 case PID_TYPE_NAME: /* --- ?? funguje spravne ?? */
1139 str_length = tvb_strnlen(tvb, offset, param_length);
1140 if (str_length == -1)
1142 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1143 "Bad parameter: Terminating zero missing");
1149 str = tvb_format_text(tvb, offset, str_length);
1150 proto_item_append_text(ti, ": %s", str);
1151 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1152 "Type name: %s", str);
1156 case PID_TYPE_CHECKSUM:
1157 /* nacitam jako UNSIGNED - nemuze to byt i zaporne cislo?? */
1158 if (param_length < 4)
1160 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1161 "Bad parameter: length < 4");
1167 checksum = get_guint32(tvb, offset, little_endian);
1168 proto_item_append_text(ti, ": 0x%X", checksum);
1169 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1170 "Checksum: 0x%X", checksum);
1174 case RTPS_PID_TYPE2_NAME:
1175 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1179 case RTPS_PID_TYPE2_CHECKSUM:
1180 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1184 case PID_METATRAFFIC_MULTICAST_IPADDRESS:
1187 while (param_length >= 4)
1191 ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1192 proto_item_append_text(ti, "%c %s", sep, ip_string);
1193 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1194 "Address[%d]: %s", i, ip_string);
1198 param_length -= 4; /* decrement count */
1200 offset += param_length;
1203 case PID_APP_IPADDRESS:
1206 while (param_length >= 4)
1210 ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1211 proto_item_append_text(ti, "%c %s", sep, ip_string);
1212 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1213 "Address[%d]: %s", i, ip_string);
1217 param_length -= 4; /* decrement count */
1219 offset += param_length;
1222 case PID_METATRAFFIC_UNICAST_PORT:
1223 if (param_length < 4)
1225 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1226 "Bad parameter: length < 4");
1232 port_str = port_to_string(offset, tvb, little_endian,buff_tmp);
1233 proto_item_append_text(ti, ": %s", port_str);
1234 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1235 "Port: %s", port_str);
1239 case PID_USERDATA_UNICAST_PORT:
1240 if (param_length < 4)
1242 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1243 "Bad parameter: length < 4");
1249 port_str = port_to_string(offset, tvb, little_endian,buff_tmp);
1250 proto_item_append_text(ti, ": %s", port_str);
1251 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1252 "Port: %s", port_str);
1256 case PID_EXPECTS_ACK:
1257 if (param_length < 1)
1259 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1260 "Bad parameter: length < 1");
1264 if (tvb_get_guint8(tvb, offset) == 0)
1266 proto_item_append_text(ti, ": No");
1267 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1268 "ACK expected: No");
1272 proto_item_append_text(ti, ": Yes");
1273 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1274 "ACK expected: Yes");
1279 case PID_USERDATA_MULTICAST_IPADDRESS:
1282 while (param_length >= 4)
1286 ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1287 proto_item_append_text(ti, "%c %s", sep, ip_string);
1288 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1289 "Address[%d]: %s", i, ip_string);
1292 param_length -= 4; /* decrement count */
1294 offset += param_length;
1297 case PID_MANAGER_KEY:
1300 while (param_length >= 4)
1302 guint32 manager_key;
1304 manager_key = get_guint32(tvb, offset, little_endian);
1305 proto_item_append_text(ti, "%c 0x%X", sep, manager_key);
1306 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1307 "Key[%d]: 0x%X", i, manager_key);
1311 param_length -= 4; /* decrement count */
1313 offset += param_length;
1316 case PID_SEND_QUEUE_SIZE:
1317 if (param_length < 4)
1319 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1320 "Bad parameter: length < 4");
1324 guint32 send_queue_size;
1326 send_queue_size = get_guint32(tvb, offset, little_endian);
1327 proto_item_append_text(ti, ": %u", send_queue_size);
1328 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1329 "Send queue size: %u", send_queue_size);
1333 case PID_PROTOCOL_VERSION:
1334 if (param_length < 2)
1336 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1337 "Bad parameter: length < 2");
1341 char *protocol_version_str;
1343 protocol_version_str = protocol_version_to_string(offset, tvb, buff_tmp);
1344 proto_item_append_text(ti, ": %s", protocol_version_str);
1345 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1346 "Protocol version: %s", protocol_version_str);
1351 if (param_length < 2)
1353 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1354 "Bad parameter: length < 2");
1358 char *vendor_id_str;
1360 vendor_id_str = vendor_id_to_string(offset, tvb, buff_tmp);
1361 proto_item_append_text(ti, ": %s", vendor_id_str);
1362 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1363 "Vendor ID: %s", vendor_id_str);
1367 case PID_VARGAPPS_SEQUENCE_NUMBER_LAST:
1368 if (param_length < 8)
1370 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1371 "Bad parameter: length < 8");
1375 seq_nr_to_string(offset, little_endian, tvb, &seqNumber);
1376 proto_item_append_text(ti, ": 0x%X%X",
1377 seqNumber.high, seqNumber.low);
1378 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1379 "Sequence number: 0x%X%X",
1380 seqNumber.high, seqNumber.low);
1384 case PID_RECV_QUEUE_SIZE:
1385 if (param_length < 4)
1387 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1388 "Bad parameter: length < 4");
1392 guint32 recv_queue_size;
1394 recv_queue_size = get_guint32(tvb, offset, little_endian);
1395 proto_item_append_text(ti, ": %u", recv_queue_size);
1396 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1397 "Receive queue size: %u", recv_queue_size);
1401 case PID_RELIABILITY_OFFERED:
1402 if (param_length < 4)
1404 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1405 "Bad parameter: length < 4");
1409 guint32 reliability_offered;
1411 reliability_offered = get_guint32(tvb, offset, little_endian);
1412 proto_item_append_text(ti, ": 0x%X", reliability_offered);
1413 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1414 "Reliability offered: 0x%X", reliability_offered);
1418 case PID_RELIABILITY_REQUESTED:
1419 if (param_length < 4)
1421 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1422 "Bad parameter: length < 4");
1426 guint32 reliability_requested;
1428 reliability_requested = get_guint32(tvb, offset, little_endian);
1429 proto_item_append_text(ti, ": 0x%X", reliability_requested);
1430 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1431 "Reliability requested: 0x%X", reliability_requested);
1436 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1437 "Unknown parameter value");
1441 offset += param_length;
1447 /* *********************************************************************** */
1450 /* *********************************************************************** *
1452 * subdissector for submessage: ISSUE *
1454 * *********************************************************************** */
1455 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1457 dissect_ISSUE(tvbuff_t *tvb, gint offset, guint8 flags,
1458 gboolean little_endian, int next_submsg_offset,
1459 proto_tree *rtps_submessage_tree)
1463 SequenceNumber sequenceNumber; /* type struct */
1465 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1466 tvb, offset, 1, flags);
1470 if ((flags & FLAG_P) != 0)
1472 if (next_submsg_offset < min_len)
1474 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1475 tvb, offset, 2, next_submsg_offset,
1476 "Octets to next header: %u (bogus, must be >= %u)",
1477 next_submsg_offset, min_len);
1480 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1481 tvb, offset, 2, next_submsg_offset);
1483 next_submsg_offset += offset;
1485 /* Reader Object ID */
1486 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1487 "Reader Object ID: %s ",
1488 object_id_to_string(offset, tvb, buff));
1491 /* Writer Object ID */
1492 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1493 "Writer Object ID: %s ",
1494 object_id_to_string(offset, tvb, buff));
1497 /* Sequence Number */
1498 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1499 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1500 "firstSeqNumber: 0x%X%X",
1501 sequenceNumber.high, sequenceNumber.low);
1505 /* *********************************************************************** *
1506 * - for future extension of the protocol - in *
1507 * implementation of RTPS 1.0 can ignore the content *
1508 * *********************************************************************** */
1510 /* -- P flag |XXXX|HAPE| => masks with 00000010b = 2 */
1511 if ((flags & FLAG_P) != 0)
1513 get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
1514 rtps_submessage_tree);
1518 proto_tree_add_item(rtps_submessage_tree, hf_rtps_issue_data, tvb,
1519 offset, (next_submsg_offset - offset), FALSE);
1523 /* *********************************************************************** */
1526 /* *********************************************************************** *
1528 * subdissector for submessage: ACK *
1530 * *********************************************************************** */
1531 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1533 dissect_ACK(tvbuff_t *tvb, gint offset, guint8 flags,
1534 gboolean little_endian, int next_submsg_offset,
1535 proto_tree *rtps_submessage_tree)
1539 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1540 tvb, offset, 1, flags);
1543 if (next_submsg_offset < 20)
1545 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1546 tvb, offset, 2, next_submsg_offset,
1547 "Octets to next header: %u (bogus, must be >= 20)",
1548 next_submsg_offset);
1551 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1552 tvb, offset, 2, next_submsg_offset);
1554 next_submsg_offset += offset;
1556 /* Reader Object ID */
1557 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1558 "Reader Object ID: %s ",
1559 object_id_to_string(offset, tvb, buff));
1562 /* Writer Object ID */
1563 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1564 "Writer Object ID: %s ",
1565 object_id_to_string(offset, tvb, buff));
1568 get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree);
1572 /* *********************************************************************** */
1575 /* *********************************************************************** *
1577 * subdissector for submessage: HEARTBEAT *
1579 * *********************************************************************** */
1580 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1582 dissect_HEARTBEAT(tvbuff_t *tvb, gint offset, guint8 flags,
1583 gboolean little_endian, int next_submsg_offset,
1584 proto_tree *rtps_submessage_tree)
1587 SequenceNumber sequenceNumber; /* type struct */
1589 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1590 tvb, offset, 1, flags);
1593 if (next_submsg_offset < 24)
1595 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1596 tvb, offset, 2, next_submsg_offset,
1597 "Octets to next header: %u (bogus, must be >= 24)",
1598 next_submsg_offset);
1601 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1602 tvb, offset, 2, next_submsg_offset);
1604 next_submsg_offset += offset;
1606 /* Reader Object ID */
1607 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1608 "Reader Object ID: %s ",
1609 object_id_to_string(offset, tvb, buff));
1612 /* Writer Object ID */
1613 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1614 "Writer Object ID: %s ",
1615 object_id_to_string(offset, tvb, buff));
1618 /* firstSeqNumber */
1619 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1620 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1621 "firstSeqNumber: 0x%X%X",
1622 sequenceNumber.high, sequenceNumber.low);
1626 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1627 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1628 "lastSeqNumber: 0x%X%X",
1629 sequenceNumber.high, sequenceNumber.low);
1634 /* *********************************************************************** */
1637 /* *********************************************************************** *
1639 * subdissector for submessage: GAP *
1641 * *********************************************************************** */
1642 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1644 dissect_GAP(tvbuff_t *tvb, gint offset, guint8 flags,
1645 gboolean little_endian, int next_submsg_offset,
1646 proto_tree *rtps_submessage_tree)
1649 SequenceNumber sequenceNumber; /* type struct */
1651 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1652 tvb, offset, 1, flags);
1655 if (next_submsg_offset < 28)
1657 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1658 tvb, offset, 2, next_submsg_offset,
1659 "Octets to next header: %u (bogus, must be >= 28)",
1660 next_submsg_offset);
1663 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1664 tvb, offset, 2, next_submsg_offset);
1666 next_submsg_offset += offset;
1668 /* Reader Object ID */
1669 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1670 "Reader Object ID: %s ",
1671 object_id_to_string(offset, tvb, buff));
1674 /* Writer Object ID */
1675 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1676 "Writer Object ID: %s ",
1677 object_id_to_string(offset, tvb, buff));
1680 /* Sequence Number */
1681 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1682 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1683 "firstSeqNumber: 0x%X%X",
1684 sequenceNumber.high, sequenceNumber.low);
1687 get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree);
1691 /* *********************************************************************** */
1694 /* *********************************************************************** *
1696 * subdissector for submessage: INFO_TS *
1698 * *********************************************************************** */
1699 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1702 dissect_INFO_TS(tvbuff_t *tvb, gint offset, guint8 flags,
1703 gboolean little_endian, int next_submsg_offset,
1704 proto_tree *rtps_submessage_tree)
1708 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1709 tvb, offset, 1, flags);
1712 /* npTimestamp - valid if flag I = 1 *
1713 * |XXXX|XXIE| => masks with 00000010b = 2 */
1714 if ((flags & FLAG_I) != 0)
1716 if (next_submsg_offset < 8)
1718 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1719 tvb, offset, 2, next_submsg_offset,
1720 "Octets to next header: %u (bogus, must be >= 8)",
1721 next_submsg_offset);
1725 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1726 tvb, offset, 2, next_submsg_offset);
1728 next_submsg_offset += offset;
1730 /* npTimestamp - valid if flag I = 1 *
1731 * |XXXX|XXIE| => masks with 00000010b = 2 */
1732 if ((flags & FLAG_I) != 0)
1734 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1735 "ntpTimestamp: %s (sec)",
1736 get_NtpTime(offset, tvb, little_endian,buff));
1742 /* *********************************************************************** */
1745 /* *********************************************************************** *
1747 * subdissector for submessage: INFO_SRC *
1749 * *********************************************************************** */
1750 /* hotovo 12.01.04 JEN OTESTOVAT :] */
1752 dissect_INFO_SRC(tvbuff_t *tvb, gint offset, guint8 flags,
1753 gboolean little_endian, int next_submsg_offset,
1754 proto_tree *rtps_submessage_tree)
1758 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1759 tvb, offset, 1, flags);
1762 if (next_submsg_offset < 16)
1764 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1765 tvb, offset, 2, next_submsg_offset,
1766 "Octets to next header: %u (bogus, must be >= 16)",
1767 next_submsg_offset);
1770 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1771 tvb, offset, 2, next_submsg_offset);
1773 next_submsg_offset += offset;
1776 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1777 "appIP address: %s",
1778 IP_to_string(offset, tvb, little_endian,buff));
1781 /* Protocol Version */
1782 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
1783 "Protocol RTPS version %s -new",
1784 protocol_version_to_string(offset, tvb, buff));
1788 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
1789 "VendorId: %s -new",
1790 vendor_id_to_string(offset, tvb, buff));
1794 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1796 host_id_to_string(offset,tvb,buff));
1800 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1802 app_id_to_string(offset, tvb, buff));
1807 /* *********************************************************************** */
1810 /* *********************************************************************** *
1812 * subdissector for submessage: INFO_REPLY *
1814 * *********************************************************************** */
1815 /* hotovo 11.01.04 :] */
1817 dissect_INFO_REPLY(tvbuff_t *tvb, gint offset, guint8 flags,
1818 gboolean little_endian, int next_submsg_offset,
1819 proto_tree *rtps_submessage_tree)
1822 char buff_ip[10], buff_port[10];
1824 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1825 tvb, offset, 1, flags);
1828 /* 'multicastReplyAdress' and 'multicastReplyPort' are *
1829 * parts of submessage INFO REPLY which are available *
1830 * only when FLAG M=1 flags: XXXX XXME */
1832 if ((flags & FLAG_M) != 0)
1836 if (next_submsg_offset < min_len)
1838 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1839 tvb, offset, 2, next_submsg_offset,
1840 "Octets to next header: %u (bogus, must be >= %u)",
1841 next_submsg_offset, min_len);
1844 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1845 tvb, offset, 2, next_submsg_offset);
1847 next_submsg_offset += offset;
1849 /* Unicat Reply IPAddress */
1850 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1851 "Unicast Reply IP Adress: %s",
1852 IP_to_string(offset, tvb, little_endian,buff_ip));
1856 /* Unicast Reply Port */
1857 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1858 "Unicast Reply IP Port: %s",
1859 port_to_string(offset, tvb, little_endian,buff_port));
1863 /* 'multicastReplyAdress' and 'multicastReplyPort' are *
1864 * parts of submessage INFO REPLY which are available *
1865 * only when FLAG M=1 flags: XXXX XXME */
1867 if ((flags & FLAG_M) != 0)
1869 /* Multicast Reply IPAddress */
1870 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1871 "Multicast Reply IP Adress: %s",
1872 IP_to_string(offset, tvb, little_endian,buff_ip));
1875 /* Multicast Reply Port */
1876 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1877 "Multicast Reply IP Port: %s",
1878 port_to_string(offset, tvb, little_endian,buff_port));
1884 /* *********************************************************************** */
1887 /* *********************************************************************** *
1889 * subdissector for submessage: INFO_DST *
1891 * *********************************************************************** */
1892 /* HOTOVO 12.01.04 - JEN OTESOVAT :]*/
1894 dissect_INFO_DST(tvbuff_t *tvb, gint offset, guint8 flags,
1895 int next_submsg_offset,
1896 proto_tree *rtps_submessage_tree)
1900 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1901 tvb, offset, 1, flags);
1904 if (next_submsg_offset < 8)
1906 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1907 tvb, offset, 2, next_submsg_offset,
1908 "Octets to next header: %u (bogus, must be >= 8)",
1909 next_submsg_offset);
1912 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1913 tvb, offset, 2, next_submsg_offset);
1915 next_submsg_offset += offset;
1918 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1920 host_id_to_string(offset,tvb,buff));
1924 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1926 app_id_to_string(offset, tvb, buff));
1931 /* *********************************************************************** *
1933 * Register the protocol with Ethereal *
1935 * *********************************************************************** */
1937 void proto_register_rtps(void)
1939 static hf_register_info hf[] = {
1941 { &hf_rtps_submessage_id,
1942 { "Submessage Id", "rtps.submessage_id",
1943 FT_UINT8, BASE_HEX, VALS(submessage_id_vals), 0x0,
1944 "Submessage flags", HFILL }},
1946 { &hf_rtps_submessage_flags,
1947 { "Submessage flags", "rtps.submessage_flags",
1948 FT_UINT8, BASE_HEX, NULL, 0x0,
1949 "Submessage flags", HFILL }},
1951 { &hf_rtps_octets_to_next_header,
1952 { "Octets to next header", "rtps.octets_to_next_header",
1953 FT_UINT16, BASE_DEC, NULL, 0x0,
1954 "Octets to next header", HFILL }},
1956 { &hf_rtps_parameter_id,
1957 { "Parameter Id", "rtps.parameter_id",
1958 FT_UINT16, BASE_HEX, VALS(parameter_id_vals), 0x0,
1959 "Parameter Id", HFILL }},
1961 { &hf_rtps_parameter_length,
1962 { "Parameter Length", "rtps.parameter_length",
1963 FT_UINT16, BASE_DEC, NULL, 0x0,
1964 "Parameter Length", HFILL }},
1966 { &hf_rtps_issue_data,
1967 { "User Data", "rtps.issue_data",
1968 FT_BYTES, BASE_HEX, NULL, 0x0,
1969 "Issue Data", HFILL }},
1972 static gint *ett[] = {
1974 &ett_rtps_submessage,
1976 &ett_rtps_parameter_sequence,
1977 &ett_rtps_parameter,
1980 proto_rtps = proto_register_protocol("Real-Time Publish-Subscribe Wire Protocol",
1982 proto_register_field_array(proto_rtps, hf, array_length(hf));
1983 proto_register_subtree_array(ett, array_length(ett));
1989 proto_reg_handoff_rtps(void)
1991 heur_dissector_add("udp", dissect_rtps, proto_rtps);