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
15 * $Id: packet-rtps.c,v 1.9 2004/04/19 22:41:19 guy Exp $
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);
1199 offset += param_length;
1202 case PID_APP_IPADDRESS:
1205 while (param_length >= 4)
1209 ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1210 proto_item_append_text(ti, "%c %s", sep, ip_string);
1211 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1212 "Address[%d]: %s", i, ip_string);
1217 offset += param_length;
1220 case PID_METATRAFFIC_UNICAST_PORT:
1221 if (param_length < 4)
1223 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1224 "Bad parameter: length < 4");
1230 port_str = port_to_string(offset, tvb, little_endian,buff_tmp);
1231 proto_item_append_text(ti, ": %s", port_str);
1232 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1233 "Port: %s", port_str);
1237 case PID_USERDATA_UNICAST_PORT:
1238 if (param_length < 4)
1240 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1241 "Bad parameter: length < 4");
1247 port_str = port_to_string(offset, tvb, little_endian,buff_tmp);
1248 proto_item_append_text(ti, ": %s", port_str);
1249 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1250 "Port: %s", port_str);
1254 case PID_EXPECTS_ACK:
1255 if (param_length < 1)
1257 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1258 "Bad parameter: length < 1");
1262 if (tvb_get_guint8(tvb, offset) == 0)
1264 proto_item_append_text(ti, ": No");
1265 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1266 "ACK expected: No");
1270 proto_item_append_text(ti, ": Yes");
1271 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1272 "ACK expected: Yes");
1277 case PID_USERDATA_MULTICAST_IPADDRESS:
1280 while (param_length >= 4)
1284 ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1285 proto_item_append_text(ti, "%c %s", sep, ip_string);
1286 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1287 "Address[%d]: %s", i, ip_string);
1291 offset += param_length;
1294 case PID_MANAGER_KEY:
1297 while (param_length >= 4)
1299 guint32 manager_key;
1301 manager_key = get_guint32(tvb, offset, little_endian);
1302 proto_item_append_text(ti, "%c 0x%X", sep, manager_key);
1303 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1304 "Key[%d]: 0x%X", i, manager_key);
1309 offset += param_length;
1312 case PID_SEND_QUEUE_SIZE:
1313 if (param_length < 4)
1315 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1316 "Bad parameter: length < 4");
1320 guint32 send_queue_size;
1322 send_queue_size = get_guint32(tvb, offset, little_endian);
1323 proto_item_append_text(ti, ": %u", send_queue_size);
1324 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1325 "Send queue size: %u", send_queue_size);
1329 case PID_PROTOCOL_VERSION:
1330 if (param_length < 2)
1332 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1333 "Bad parameter: length < 2");
1337 char *protocol_version_str;
1339 protocol_version_str = protocol_version_to_string(offset, tvb, buff_tmp);
1340 proto_item_append_text(ti, ": %s", protocol_version_str);
1341 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1342 "Protocol version: %s", protocol_version_str);
1347 if (param_length < 2)
1349 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1350 "Bad parameter: length < 2");
1354 char *vendor_id_str;
1356 vendor_id_str = vendor_id_to_string(offset, tvb, buff_tmp);
1357 proto_item_append_text(ti, ": %s", vendor_id_str);
1358 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1359 "Vendor ID: %s", vendor_id_str);
1363 case PID_VARGAPPS_SEQUENCE_NUMBER_LAST:
1364 if (param_length < 8)
1366 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1367 "Bad parameter: length < 8");
1371 seq_nr_to_string(offset, little_endian, tvb, &seqNumber);
1372 proto_item_append_text(ti, ": 0x%X%X",
1373 seqNumber.high, seqNumber.low);
1374 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1375 "Sequence number: 0x%X%X",
1376 seqNumber.high, seqNumber.low);
1380 case PID_RECV_QUEUE_SIZE:
1381 if (param_length < 4)
1383 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1384 "Bad parameter: length < 4");
1388 guint32 recv_queue_size;
1390 recv_queue_size = get_guint32(tvb, offset, little_endian);
1391 proto_item_append_text(ti, ": %u", recv_queue_size);
1392 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1393 "Receive queue size: %u", recv_queue_size);
1397 case PID_RELIABILITY_OFFERED:
1398 if (param_length < 4)
1400 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1401 "Bad parameter: length < 4");
1405 guint32 reliability_offered;
1407 reliability_offered = get_guint32(tvb, offset, little_endian);
1408 proto_item_append_text(ti, ": 0x%X", reliability_offered);
1409 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1410 "Reliability offered: 0x%X", reliability_offered);
1414 case PID_RELIABILITY_REQUESTED:
1415 if (param_length < 4)
1417 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1418 "Bad parameter: length < 4");
1422 guint32 reliability_requested;
1424 reliability_requested = get_guint32(tvb, offset, little_endian);
1425 proto_item_append_text(ti, ": 0x%X", reliability_requested);
1426 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1427 "Reliability requested: 0x%X", reliability_requested);
1432 proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1433 "Unknown parameter value");
1437 offset += param_length;
1443 /* *********************************************************************** */
1446 /* *********************************************************************** *
1448 * subdissector for submessage: ISSUE *
1450 * *********************************************************************** */
1451 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1453 dissect_ISSUE(tvbuff_t *tvb, gint offset, guint8 flags,
1454 gboolean little_endian, int next_submsg_offset,
1455 proto_tree *rtps_submessage_tree)
1459 SequenceNumber sequenceNumber; /* type struct */
1461 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1462 tvb, offset, 1, flags);
1466 if ((flags & FLAG_P) != 0)
1468 if (next_submsg_offset < min_len)
1470 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1471 tvb, offset, 2, next_submsg_offset,
1472 "Octets to next header: %u (bogus, must be >= %u)",
1473 next_submsg_offset, min_len);
1476 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1477 tvb, offset, 2, next_submsg_offset);
1479 next_submsg_offset += offset;
1481 /* Reader Object ID */
1482 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1483 "Reader Object ID: %s ",
1484 object_id_to_string(offset, tvb, buff));
1487 /* Writer Object ID */
1488 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1489 "Writer Object ID: %s ",
1490 object_id_to_string(offset, tvb, buff));
1493 /* Sequence Number */
1494 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1495 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1496 "firstSeqNumber: 0x%X%X",
1497 sequenceNumber.high, sequenceNumber.low);
1501 /* *********************************************************************** *
1502 * - for future extension of the protocol - in *
1503 * implementation of RTPS 1.0 can ignore the content *
1504 * *********************************************************************** */
1506 /* -- P flag |XXXX|HAPE| => masks with 00000010b = 2 */
1507 if ((flags & FLAG_P) != 0)
1509 get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
1510 rtps_submessage_tree);
1514 proto_tree_add_item(rtps_submessage_tree, hf_rtps_issue_data, tvb,
1515 offset, (next_submsg_offset - offset), FALSE);
1519 /* *********************************************************************** */
1522 /* *********************************************************************** *
1524 * subdissector for submessage: ACK *
1526 * *********************************************************************** */
1527 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1529 dissect_ACK(tvbuff_t *tvb, gint offset, guint8 flags,
1530 gboolean little_endian, int next_submsg_offset,
1531 proto_tree *rtps_submessage_tree)
1535 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1536 tvb, offset, 1, flags);
1539 if (next_submsg_offset < 20)
1541 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1542 tvb, offset, 2, next_submsg_offset,
1543 "Octets to next header: %u (bogus, must be >= 20)",
1544 next_submsg_offset);
1547 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1548 tvb, offset, 2, next_submsg_offset);
1550 next_submsg_offset += offset;
1552 /* Reader Object ID */
1553 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1554 "Reader Object ID: %s ",
1555 object_id_to_string(offset, tvb, buff));
1558 /* Writer Object ID */
1559 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1560 "Writer Object ID: %s ",
1561 object_id_to_string(offset, tvb, buff));
1564 get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree);
1568 /* *********************************************************************** */
1571 /* *********************************************************************** *
1573 * subdissector for submessage: HEARTBEAT *
1575 * *********************************************************************** */
1576 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1578 dissect_HEARTBEAT(tvbuff_t *tvb, gint offset, guint8 flags,
1579 gboolean little_endian, int next_submsg_offset,
1580 proto_tree *rtps_submessage_tree)
1583 SequenceNumber sequenceNumber; /* type struct */
1585 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1586 tvb, offset, 1, flags);
1589 if (next_submsg_offset < 24)
1591 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1592 tvb, offset, 2, next_submsg_offset,
1593 "Octets to next header: %u (bogus, must be >= 24)",
1594 next_submsg_offset);
1597 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1598 tvb, offset, 2, next_submsg_offset);
1600 next_submsg_offset += offset;
1602 /* Reader Object ID */
1603 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1604 "Reader Object ID: %s ",
1605 object_id_to_string(offset, tvb, buff));
1608 /* Writer Object ID */
1609 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1610 "Writer Object ID: %s ",
1611 object_id_to_string(offset, tvb, buff));
1614 /* firstSeqNumber */
1615 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1616 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1617 "firstSeqNumber: 0x%X%X",
1618 sequenceNumber.high, sequenceNumber.low);
1622 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1623 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1624 "lastSeqNumber: 0x%X%X",
1625 sequenceNumber.high, sequenceNumber.low);
1630 /* *********************************************************************** */
1633 /* *********************************************************************** *
1635 * subdissector for submessage: GAP *
1637 * *********************************************************************** */
1638 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1640 dissect_GAP(tvbuff_t *tvb, gint offset, guint8 flags,
1641 gboolean little_endian, int next_submsg_offset,
1642 proto_tree *rtps_submessage_tree)
1645 SequenceNumber sequenceNumber; /* type struct */
1647 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1648 tvb, offset, 1, flags);
1651 if (next_submsg_offset < 28)
1653 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1654 tvb, offset, 2, next_submsg_offset,
1655 "Octets to next header: %u (bogus, must be >= 28)",
1656 next_submsg_offset);
1659 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1660 tvb, offset, 2, next_submsg_offset);
1662 next_submsg_offset += offset;
1664 /* Reader Object ID */
1665 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1666 "Reader Object ID: %s ",
1667 object_id_to_string(offset, tvb, buff));
1670 /* Writer Object ID */
1671 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1672 "Writer Object ID: %s ",
1673 object_id_to_string(offset, tvb, buff));
1676 /* Sequence Number */
1677 seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1678 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1679 "firstSeqNumber: 0x%X%X",
1680 sequenceNumber.high, sequenceNumber.low);
1683 get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree);
1687 /* *********************************************************************** */
1690 /* *********************************************************************** *
1692 * subdissector for submessage: INFO_TS *
1694 * *********************************************************************** */
1695 /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1698 dissect_INFO_TS(tvbuff_t *tvb, gint offset, guint8 flags,
1699 gboolean little_endian, int next_submsg_offset,
1700 proto_tree *rtps_submessage_tree)
1704 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1705 tvb, offset, 1, flags);
1708 /* npTimestamp - valid if flag I = 1 *
1709 * |XXXX|XXIE| => masks with 00000010b = 2 */
1710 if ((flags & FLAG_I) != 0)
1712 if (next_submsg_offset < 8)
1714 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1715 tvb, offset, 2, next_submsg_offset,
1716 "Octets to next header: %u (bogus, must be >= 8)",
1717 next_submsg_offset);
1721 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1722 tvb, offset, 2, next_submsg_offset);
1724 next_submsg_offset += offset;
1726 /* npTimestamp - valid if flag I = 1 *
1727 * |XXXX|XXIE| => masks with 00000010b = 2 */
1728 if ((flags & FLAG_I) != 0)
1730 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1731 "ntpTimestamp: %s (sec)",
1732 get_NtpTime(offset, tvb, little_endian,buff));
1738 /* *********************************************************************** */
1741 /* *********************************************************************** *
1743 * subdissector for submessage: INFO_SRC *
1745 * *********************************************************************** */
1746 /* hotovo 12.01.04 JEN OTESTOVAT :] */
1748 dissect_INFO_SRC(tvbuff_t *tvb, gint offset, guint8 flags,
1749 gboolean little_endian, int next_submsg_offset,
1750 proto_tree *rtps_submessage_tree)
1754 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1755 tvb, offset, 1, flags);
1758 if (next_submsg_offset < 16)
1760 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1761 tvb, offset, 2, next_submsg_offset,
1762 "Octets to next header: %u (bogus, must be >= 16)",
1763 next_submsg_offset);
1766 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1767 tvb, offset, 2, next_submsg_offset);
1769 next_submsg_offset += offset;
1772 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1773 "appIP address: %s",
1774 IP_to_string(offset, tvb, little_endian,buff));
1777 /* Protocol Version */
1778 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
1779 "Protocol RTPS version %s -new",
1780 protocol_version_to_string(offset, tvb, buff));
1784 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
1785 "VendorId: %s -new",
1786 vendor_id_to_string(offset, tvb, buff));
1790 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1792 host_id_to_string(offset,tvb,buff));
1796 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1798 app_id_to_string(offset, tvb, buff));
1803 /* *********************************************************************** */
1806 /* *********************************************************************** *
1808 * subdissector for submessage: INFO_REPLY *
1810 * *********************************************************************** */
1811 /* hotovo 11.01.04 :] */
1813 dissect_INFO_REPLY(tvbuff_t *tvb, gint offset, guint8 flags,
1814 gboolean little_endian, int next_submsg_offset,
1815 proto_tree *rtps_submessage_tree)
1818 char buff_ip[10], buff_port[10];
1820 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1821 tvb, offset, 1, flags);
1824 /* 'multicastReplyAdress' and 'multicastReplyPort' are *
1825 * parts of submessage INFO REPLY which are available *
1826 * only when FLAG M=1 flags: XXXX XXME */
1828 if ((flags & FLAG_M) != 0)
1832 if (next_submsg_offset < min_len)
1834 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1835 tvb, offset, 2, next_submsg_offset,
1836 "Octets to next header: %u (bogus, must be >= %u)",
1837 next_submsg_offset, min_len);
1840 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1841 tvb, offset, 2, next_submsg_offset);
1843 next_submsg_offset += offset;
1845 /* Unicat Reply IPAddress */
1846 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1847 "Unicast Reply IP Adress: %s",
1848 IP_to_string(offset, tvb, little_endian,buff_ip));
1852 /* Unicast Reply Port */
1853 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1854 "Unicast Reply IP Port: %s",
1855 port_to_string(offset, tvb, little_endian,buff_port));
1859 /* 'multicastReplyAdress' and 'multicastReplyPort' are *
1860 * parts of submessage INFO REPLY which are available *
1861 * only when FLAG M=1 flags: XXXX XXME */
1863 if ((flags & FLAG_M) != 0)
1865 /* Multicast Reply IPAddress */
1866 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1867 "Multicast Reply IP Adress: %s",
1868 IP_to_string(offset, tvb, little_endian,buff_ip));
1871 /* Multicast Reply Port */
1872 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1873 "Multicast Reply IP Port: %s",
1874 port_to_string(offset, tvb, little_endian,buff_port));
1880 /* *********************************************************************** */
1883 /* *********************************************************************** *
1885 * subdissector for submessage: INFO_DST *
1887 * *********************************************************************** */
1888 /* HOTOVO 12.01.04 - JEN OTESOVAT :]*/
1890 dissect_INFO_DST(tvbuff_t *tvb, gint offset, guint8 flags,
1891 int next_submsg_offset,
1892 proto_tree *rtps_submessage_tree)
1896 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1897 tvb, offset, 1, flags);
1900 if (next_submsg_offset < 8)
1902 proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1903 tvb, offset, 2, next_submsg_offset,
1904 "Octets to next header: %u (bogus, must be >= 8)",
1905 next_submsg_offset);
1908 proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1909 tvb, offset, 2, next_submsg_offset);
1911 next_submsg_offset += offset;
1914 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1916 host_id_to_string(offset,tvb,buff));
1920 proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1922 app_id_to_string(offset, tvb, buff));
1927 /* *********************************************************************** *
1929 * Register the protocol with Ethereal *
1931 * *********************************************************************** */
1933 void proto_register_rtps(void)
1935 static hf_register_info hf[] = {
1937 { &hf_rtps_submessage_id,
1938 { "Submessage Id", "rtps.submessage_id",
1939 FT_UINT8, BASE_HEX, VALS(submessage_id_vals), 0x0,
1940 "Submessage flags", HFILL }},
1942 { &hf_rtps_submessage_flags,
1943 { "Submessage flags", "rtps.submessage_flags",
1944 FT_UINT8, BASE_HEX, NULL, 0x0,
1945 "Submessage flags", HFILL }},
1947 { &hf_rtps_octets_to_next_header,
1948 { "Octets to next header", "rtps.octets_to_next_header",
1949 FT_UINT16, BASE_DEC, NULL, 0x0,
1950 "Octets to next header", HFILL }},
1952 { &hf_rtps_parameter_id,
1953 { "Parameter Id", "rtps.parameter_id",
1954 FT_UINT16, BASE_HEX, VALS(parameter_id_vals), 0x0,
1955 "Parameter Id", HFILL }},
1957 { &hf_rtps_parameter_length,
1958 { "Parameter Length", "rtps.parameter_length",
1959 FT_UINT16, BASE_DEC, NULL, 0x0,
1960 "Parameter Length", HFILL }},
1962 { &hf_rtps_issue_data,
1963 { "User Data", "rtps.issue_data",
1964 FT_BYTES, BASE_HEX, NULL, 0x0,
1965 "Issue Data", HFILL }},
1968 static gint *ett[] = {
1970 &ett_rtps_submessage,
1972 &ett_rtps_parameter_sequence,
1973 &ett_rtps_parameter,
1976 proto_rtps = proto_register_protocol("Real-Time Publish-Subscribe Wire Protocol",
1978 proto_register_field_array(proto_rtps, hf, array_length(hf));
1979 proto_register_subtree_array(ett, array_length(ett));
1985 proto_reg_handoff_rtps(void)
1987 heur_dissector_add("udp", dissect_rtps, proto_rtps);