diff options
Diffstat (limited to 'epan/dissectors/packet-rtps.c')
-rw-r--r-- | epan/dissectors/packet-rtps.c | 1993 |
1 files changed, 1993 insertions, 0 deletions
diff --git a/epan/dissectors/packet-rtps.c b/epan/dissectors/packet-rtps.c new file mode 100644 index 0000000000..6adcf73806 --- /dev/null +++ b/epan/dissectors/packet-rtps.c @@ -0,0 +1,1993 @@ +/* packet-rtps.c + * Routines for Real-Time Publish-Subscribe Protocol (RTPS) dissection + * + * Copyright 2003, LUKAS POKORNY <maskis@seznam.cz> + * PETR SMOLIK <petr.smolik@wo.cz> + * ZDENEK SEBEK <sebek@fel.cvut.cz> + * + * Czech Technical University in Prague + * Faculty of Electrical Engineering <www.fel.cvut.cz> + * Department of Control Engineering <dce.felk.cvut.cz> + * + * version: 2004/04/15 9:40:45 + * dedication to Kj :] + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * Copied from packet-udp.c, packet-tftp.c, packet-x25.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * *********************************************************************** */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <epan/packet.h> +#include <epan/resolv.h> +#include <epan/conversation.h> + + +/* *********************************************************************** * + RTPS protocol was developed by Real Time Innovation, Inc. + + Protocol specifikation and documenation you can find on these addresses: + + http://www.rti.com/ + + http://www.rti.com/products/ndds/literature.html + + http://www.schneider-electric.com.au/Products/Automation/TF_RealTime/ + /technical%20library/specifications/WireProtocolExternal.pdf + + + * *********************************************************************** */ + + + +/* redefine types because of definitions in 'packet-rtps.h' */ +/* +#define u_int8_t guint8 +#define int8_t gint8 + +#define u_int16_t guint16 +#define int16_t gint16 + +#define u_int32_t guint32 +#define int32_t gint32 +*/ + +#include "packet-rtps.h" + +/* number of APP_KIND byte in packet header */ +#define APP_KIND_BYTE 15 + + +/* definitions of flags */ +#define FLAG_E 0x01 +#define FLAG_F 0x02 +#define FLAG_I 0x02 +#define FLAG_M 0x02 +#define FLAG_P 0x02 +#define FLAG_A 0x04 +#define FLAG_H 0x08 + + +/* submessageId's ranges */ +#define SUBMSG_ID_MIN PAD +#define SUBMSG_ID_MAX INFO_DST + +/* Vendor specific submessageId's ranges */ +#define VENDOR_SUBMSG_ID_MIN 0x80 +#define VENDOR_SUBMSG_ID_MAX 0xff + +/* *********************************************************************** */ + + +/* initialize the protocol and registered fields */ +static int proto_rtps = -1; +static int hf_rtps_submessage_id = -1; +static int hf_rtps_submessage_flags = -1; +static int hf_rtps_octets_to_next_header = -1; +static int hf_rtps_parameter_id = -1; +static int hf_rtps_parameter_length = -1; +static int hf_rtps_issue_data = -1; + +/* Initialize the subtree pointers */ +static gint ett_rtps = -1; +static gint ett_rtps_submessage = -1; +static gint ett_rtps_bitmap = -1; +static gint ett_rtps_parameter_sequence = -1; +static gint ett_rtps_parameter = -1; + +/* Functions declarations */ +static void dissect_PAD(tvbuff_t *tvb,gint offset,guint8 flags, + int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_VAR(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_ISSUE(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_ACK(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_HEARTBEAT(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_GAP(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_INFO_TS(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_INFO_SRC(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_INFO_REPLY(tvbuff_t *tvb,gint offset,guint8 flags, + gboolean little_endian,int next_submsg_offset, + proto_tree *rtps_submessage_tree); +static void dissect_INFO_DST(tvbuff_t *tvb,gint offset,guint8 flags, + int next_submsg_offset, + proto_tree *rtps_submessage_tree); + +static guint16 get_guint16(tvbuff_t *tvb, gint offset, gboolean little_endian); +static guint32 get_guint32(tvbuff_t *tvb, gint offset, gboolean little_endian); + +static char *protocol_version_to_string(gint offset,tvbuff_t *tvb,char *buff); +static char *vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff); + +static char *host_id_to_string(gint offset,tvbuff_t *tvb, char buff[]); +static char *app_id_to_string(gint offset,tvbuff_t *tvb,char buff[]); +static char *object_id_to_string(gint offset, tvbuff_t *tvb, char buff[]); + +static char *IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]); +static char *port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]); +static char *get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]); + +static void get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian, + gint next_submsg, proto_tree *tree); + +static void get_parameter_sequence(tvbuff_t *tvb, gint *p_offset, + gboolean little_endian, + gint next_submsg_offset, proto_tree *tree); + +static gint seq_nr_to_string( gint offset, gboolean little_endian, tvbuff_t *tvb, + SequenceNumber *p_seqNumber); + +static const value_string submessage_id_vals[] = { + { PAD, "PAD" }, + { VAR, "VAR" }, + { ISSUE, "ISSUE" }, + { ACK, "ACK" }, + { HEARTBEAT, "HEARTBEAT" }, + { GAP, "GAP" }, + { INFO_TS, "INFO_TS" }, + { INFO_SRC, "INFO_SRC" }, + { INFO_REPLY, "INFO_REPLY" }, + { INFO_DST, "INFO_DST" }, + { APP_QUIT, "APP_QUIT" }, + { 0, NULL } +}; + +static const value_string parameter_id_vals[] = { + { PID_PAD, "PID_PAD" }, + { PID_SENTINEL, "PID_SENTINEL" }, + { PID_EXPIRATION_TIME, "PID_EXPIRATION_TIME" }, + { PID_PERSISTENCE, "PID_PERSISTENCE" }, + { PID_MINIMUM_SEPARATION, "PID_MINIMUM_SEPARATION" }, + { PID_TOPIC, "PID_TOPIC" }, + { PID_STRENGTH, "PID_STRENGTH" }, + { PID_TYPE_NAME, "PID_TYPE_NAME" }, + { PID_TYPE_CHECKSUM, "PID_TYPE_CHECKSUM" }, + { RTPS_PID_TYPE2_NAME, "RTPS_PID_TYPE2_NAME" }, + { RTPS_PID_TYPE2_CHECKSUM, "RTPS_PID_TYPE2_CHECKSUM" }, + { PID_METATRAFFIC_MULTICAST_IPADDRESS, "PID_METATRAFFIC_MULTICAST_IPADDRESS" }, + { PID_APP_IPADDRESS, "PID_APP_IPADDRESS" }, + { PID_METATRAFFIC_UNICAST_PORT, "PID_METATRAFFIC_UNICAST_PORT" }, + { PID_USERDATA_UNICAST_PORT, "PID_USERDATA_UNICAST_PORT" }, + { PID_IS_RELIABLE, "PID_IS_RELIABLE" }, + { PID_EXPECTS_ACK, "PID_EXPECTS_ACK" }, + { PID_USERDATA_MULTICAST_IPADDRESS, "PID_USERDATA_MULTICAST_IPADDRESS" }, + { PID_MANAGER_KEY, "PID_MANAGER_KEY" }, + { PID_SEND_QUEUE_SIZE, "PID_SEND_QUEUE_SIZE" }, + { PID_RELIABILITY_ENABLED, "PID_RELIABILITY_ENABLED" }, + { PID_PROTOCOL_VERSION, "PID_PROTOCOL_VERSION" }, + { PID_VENDOR_ID, "PID_VENDOR_ID" }, + { PID_VARGAPPS_SEQUENCE_NUMBER_LAST, "PID_VARGAPPS_SEQUENCE_NUMBER_LAST" }, + { PID_RECV_QUEUE_SIZE, "PID_RECV_QUEUE_SIZE" }, + { PID_RELIABILITY_OFFERED, "PID_RELIABILITY_OFFERED" }, + { PID_RELIABILITY_REQUESTED, "PID_RELIABILITY_REQUESTED" }, + { 0, NULL } +}; + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * Code to actually dissect the packets * + * * + * *********************************************************************** */ + +static gboolean +dissect_rtps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti; + proto_tree *rtps_tree=NULL; + gint offset = 0; + gint appKind; + proto_tree *rtps_submessage_tree; + guint8 submessageId; + guint8 flags; + gboolean little_endian; + int next_submsg; + int count_msg_type[11]; + char buff[200], buff_tmp[30];/* buffers */ + + /* offset is the byte offset of 'tvb' at which the new tvbuff + should start. The first byte is the 0th byte. */ + + /* --- making disition if protocol is RTPS protocol --- */ + if (!tvb_bytes_exist(tvb, offset, 4)) return FALSE; + if (tvb_get_guint8(tvb,offset++) != 'R') return FALSE; + if (tvb_get_guint8(tvb,offset++) != 'T') return FALSE; + if (tvb_get_guint8(tvb,offset++) != 'P') return FALSE; + if (tvb_get_guint8(tvb,offset++) != 'S') return FALSE; + + /* --- Make entries in Protocol column ---*/ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPS"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + memset(count_msg_type, 0, sizeof(count_msg_type)); + + if (tree) { + + /* create display subtree for the protocol */ + ti = proto_tree_add_item(tree, proto_rtps, tvb, 0, -1, FALSE); + rtps_tree = proto_item_add_subtree(ti, ett_rtps); + + /* Protocol Version */ + proto_tree_add_text(rtps_tree, tvb, offset, 2, + "Protocol RTPS, version %s", + protocol_version_to_string(offset, tvb, buff)); + offset +=2; + + /* Vendor Id */ + proto_tree_add_text(rtps_tree, tvb, offset, 2, + "VendorId: %s", + vendor_id_to_string(offset, tvb, buff)); + offset +=2; + + /* Host Id */ + proto_tree_add_text(rtps_tree, tvb, offset, 4, + "HostId: %s", + host_id_to_string(offset,tvb,buff)); + offset +=4; + + /* App Id */ + proto_tree_add_text(rtps_tree, tvb, offset, 4, + "App ID: %s", + app_id_to_string(offset, tvb, buff)); + + } + + /* offset behind RTPS's Header */ + offset=16; + + while (tvb_reported_length_remaining(tvb, offset) > 0) { + submessageId = tvb_get_guint8(tvb, offset); + if (submessageId & 0x80) { + ti = proto_tree_add_text(tree, tvb, offset, -1, "Submessage: %s", + val_to_str(submessageId, submessage_id_vals, + "Vendor-specific (0x%02X)")); + } else { + ti = proto_tree_add_text(tree, tvb, offset, -1, "Submessage: %s", + val_to_str(submessageId, submessage_id_vals, + "Unknown (0x%02X)")); + } + rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage); + if (submessageId & 0x80) { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_submessage_id, + tvb, offset, 1, submessageId, + "Submessage Id: Vendor-specific (0x%02x)", + submessageId); + } else { + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_id, + tvb, offset, 1, submessageId); + } + + flags = tvb_get_guint8(tvb, offset + 1); + /* E flag |XXXX|HAPE| => masks with 000000001b = 1 */ + if ((flags & FLAG_E) != 0) little_endian = TRUE; + else little_endian = FALSE; + + next_submsg = get_guint16(tvb, offset + 2, little_endian); + proto_item_set_len(ti, next_submsg); + + switch (submessageId) + { + case PAD: + if (tree) + dissect_PAD(tvb, offset + 1, flags, next_submsg, + rtps_submessage_tree); + count_msg_type[0]++; + break; + case VAR: + if (tree) + dissect_VAR(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[1]++; + break; + case ISSUE: + if (tree) + dissect_ISSUE(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[2]++; + break; + case ACK: + if (tree) + dissect_ACK(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[3]++; + break; + case HEARTBEAT: + if (tree) + dissect_HEARTBEAT(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[4]++; + break; + case GAP: + if (tree) + dissect_GAP(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[5]++; + break; + case INFO_TS: + if (tree) + dissect_INFO_TS(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[6]++; + break; + case INFO_SRC: + if (tree) + dissect_INFO_SRC(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[7]++; + break; + case INFO_REPLY: + if (tree) + dissect_INFO_REPLY(tvb, offset + 1, flags, little_endian, next_submsg, + rtps_submessage_tree); + count_msg_type[8]++; + break; + case INFO_DST: + if (tree) + dissect_INFO_DST(tvb, offset + 1, flags, next_submsg, + rtps_submessage_tree); + count_msg_type[9]++; + break; + default: + if (tree) { + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset + 1, 1, flags); + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset + 2, 2, next_submsg); + } + break; + } + + /* next submessage's offset */ + offset += next_submsg+4; + + } + + /* --- and Info column on summary display ---*/ + + if (check_col(pinfo->cinfo, COL_INFO)) + { + appKind = tvb_get_guint8(tvb, APP_KIND_BYTE); + + if (appKind == MANAGEDAPPLICATION ) {sprintf(buff,"App: ");} + if (appKind == MANAGER) {sprintf(buff,"Man: ");} + if (appKind == AID_UNKNOWN) {sprintf(buff,"Unknown:");} + + if (appKind != MANAGEDAPPLICATION && appKind != MANAGER && + appKind != AID_UNKNOWN) {sprintf(buff,"ERROR in APP type");} + + /* -- counts of submessages - for Information Frame */ + if (count_msg_type[0]>0) { + sprintf(buff_tmp,"PAD(%d) ",count_msg_type[0]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[1]>0) { + sprintf(buff_tmp,"VAR(%d) ",count_msg_type[1]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[2]>0) { + sprintf(buff_tmp,"ISSUE(%d) ",count_msg_type[2]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[3]>0) { + sprintf(buff_tmp,"ACK(%d) ",count_msg_type[3]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[4]>0) { + sprintf(buff_tmp,"HEARTBEAT(%d) ",count_msg_type[4]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[5]>0) { + sprintf(buff_tmp,"GAP(%d) ",count_msg_type[5]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[6]>0) { + sprintf(buff_tmp,"INFO_TS(%d) ",count_msg_type[6]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[7]>0) { + sprintf(buff_tmp, "INFO_SRC(%d) ",count_msg_type[7]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[8]>0) { + sprintf(buff_tmp,"INFO_REPLY(%d) ",count_msg_type[8]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[9]>0) { + sprintf(buff_tmp,"INFO_DST(%d) ",count_msg_type[9]); + strcat(buff,buff_tmp); + } + + if (count_msg_type[10]>0) { + sprintf(buff_tmp,"vendor specific(%d) ",count_msg_type[10]); + strcat(buff,buff_tmp); + } + + col_add_fstr(pinfo->cinfo, COL_INFO, buff); + + } + + + return TRUE; + +} /* end dissect_rtps(...) */ + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get 16 bit from the stream * + * * + * *********************************************************************** */ + +static guint16 get_guint16(tvbuff_t *tvb, gint offset, gboolean little_endian) +{ + guint16 value; + + if (little_endian) + value = tvb_get_letohs(tvb, offset); + else + value = tvb_get_ntohs(tvb, offset); + + return(value); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get 32 bit from the stream * + * * + * *********************************************************************** */ + +static guint32 get_guint32(tvbuff_t *tvb, gint offset, gboolean little_endian) +{ + guint32 value; + + if (little_endian) + value = tvb_get_letohl(tvb, offset); + else + value = tvb_get_ntohl(tvb, offset); + + return(value); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get Protocol version * + * * + * *********************************************************************** */ + +static char * +protocol_version_to_string(gint offset,tvbuff_t *tvb,char *buff) +{ + guint8 major, minor; + + /* protocol verzion = major.minor */ + major = tvb_get_guint8(tvb, offset); + minor = tvb_get_guint8(tvb, (offset+1)); + + sprintf(buff,"%d.%d", major, minor); + return(buff); + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get Vendor Id * + * * + * *********************************************************************** */ + +static char * +vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff) +{ + guint8 major, minor; + VendorId vendorId_rti; + + VENDOR_ID_RTI(vendorId_rti); + + major = tvb_get_guint8(tvb, offset); + minor = tvb_get_guint8(tvb, (offset+1)); + + if (major == vendorId_rti.major && + minor == vendorId_rti.minor) + { sprintf(buff,"Real-Time Innovations,Inc.,CA,USA"); + return(buff); } + + sprintf(buff,"Vendor unknown"); + return(buff); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get IP Address * + * * + * *********************************************************************** */ + +static char * +IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]) +{ + IPAddress ip; + guint8 a = 0, b = 0, c = 0, d = 0; /* IP Adresss = a.b.c.d */ + + ip = get_guint32(tvb, offset, little_endian); + /* get_guint32() - reads + endian conversion */ + a = (ip >> 24); + b = (ip >> 16) & 0xff; + c = (ip >> 8) & 0xff; + d = ip & 0xff; + + sprintf(buff,"%d.%d.%d.%d", a, b, c, d); + return(buff); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get Port * + * * + * *********************************************************************** */ + +static char * +port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]) +{ + Port port = get_guint32(tvb, offset, little_endian); + /* get_guint32() - reads + endian conversion */ + + if (port == PORT_INVALID) + sprintf(buff,"PORT_INVALID"); + else + sprintf(buff,"0x%X",port); + + return(buff); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get NTP Time * + * * + * *********************************************************************** */ + +static char * +get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]) +{ + NtpTime ntpTime; + float time; + + /* get_guint32() - reads + endian conversion */ + ntpTime.seconds = get_guint32(tvb, offset, little_endian); + ntpTime.fraction = get_guint32(tvb, (offset + 4), little_endian); + time = (float) ntpTime.seconds + (ntpTime.fraction / 2^(32)); + + sprintf(buff,"%f", time); + return(buff); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get Host Id * + * * + * *********************************************************************** */ + +static char * +host_id_to_string(gint offset,tvbuff_t *tvb, char buff[]) +{ + guint32 hostId = tvb_get_ntohl(tvb, offset); + /* get_ntohl() automaticaly convert data to BIG ENDIAN */ + + sprintf(buff,"0x%X", hostId); + return(buff); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get AppID * + * * + * *********************************************************************** */ + +static char * +app_id_to_string(gint offset,tvbuff_t *tvb,char buff[]) +{ + guint32 appId = tvb_get_ntohl(tvb, offset); + /* get_ntohl() automaticaly convert data to BIG ENDIAN */ + + /* Instance Id */ + guint32 instanceId = (appId >> 8); + /* applicatin Kind */ + guint8 appKind = (appId & 0xff); + + if (appKind == MANAGEDAPPLICATION) + { + sprintf(buff,"Managed App, InstanceId: 0x%X",instanceId); + return(buff); + } + + if (appKind == MANAGER) + { + sprintf(buff,"Manager, InstanceId: 0x%X",instanceId); + return(buff); + } + + sprintf(buff,"Unknown"); + return(buff); + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get Object_Id (32 bit) * + * * + * *********************************************************************** */ + +static char * +object_id_to_string(gint offset, tvbuff_t *tvb, char buff[]) +{ + guint32 objectId = tvb_get_ntohl(tvb, offset); + /* get_ntohl() automaticaly convert data to BIG ENDIAN */ + + if (objectId == OID_UNKNOWN) { sprintf(buff,"Unknown ObjectId"); + return(buff);} + if (objectId == OID_APP) { sprintf(buff,"applicationSelf"); + return(buff);} + if (objectId == OID_WRITE_APPSELF){ sprintf(buff,"writerApplicationSelf"); + return(buff);} + if (objectId == OID_WRITE_APP) { sprintf(buff,"writerApplications"); + return(buff);} + if (objectId == OID_READ_APP) { sprintf(buff,"readerApplications"); + return(buff);} + if (objectId == OID_WRITE_MGR) { sprintf(buff,"writerManagers"); + return(buff);} + if (objectId == OID_READ_MGR) { sprintf(buff,"readerManagers "); + return(buff);} + if (objectId == OID_WRITE_PUBL) { sprintf(buff,"writerPublications"); + return(buff);} + if (objectId == OID_READ_PUBL) { sprintf(buff,"readerPublications"); + return(buff);} + if (objectId == OID_WRITE_SUBS) { sprintf(buff,"writerSubscriptions"); + return(buff);} + if (objectId == OID_READ_SUBS) { sprintf(buff,"readerSubscriptions"); + return(buff);} + + /* nothing from the possibilites above */ + sprintf(buff,"instanceId: 0x%X, objKind: 0x%X", + (objectId >> 8),(objectId & 0xff)); + return(buff); + +/* for the future +//Kind +#define OID_APPLICATION 0x01 +#define OID_CSTWRITER 0x02 +#define OID_PUBLICATION 0x03 +#define OID_SUBSCRIPTION 0x04 +#define OID_CSTREADER 0x07 +// +#define OID_USEROBJ 0x00 +#define OID_RESUSEROBJ 0x40 +#define OID_METAOBJ 0x80 +#define OID_RESMETAOBJ 0xC0 +*/ +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get Sequence Number (64 bit) * + * * + * *********************************************************************** */ + +static gint +seq_nr_to_string(gint offset, gboolean little_endian, tvbuff_t *tvb, + SequenceNumber *p_seqNumber) +{ + p_seqNumber->high = get_guint32(tvb, offset, little_endian); + p_seqNumber->low = get_guint32(tvb, offset + 4, little_endian); + + return(1); +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * get_Bitmap * + * * + * *********************************************************************** */ + +static void +get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian, + gint next_submsg, proto_tree *tree) +{ + proto_item *ti; + proto_tree *rtps_bitmap_tree; + gint i = 0; + gint offset = *p_offset; + SequenceNumber sequenceNumber; + guint32 num_bits; + guint num_longs; + + /* making subtree for the bitmap */ + ti = proto_tree_add_text(tree,tvb,offset,(next_submsg-offset),"Bitmap"); + rtps_bitmap_tree = proto_item_add_subtree(ti, ett_rtps_bitmap); + + /* SekvenceNumber bitmapBase */ + seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber); + proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 8, + "bitmapBase: 0x%X%X", + sequenceNumber.high, sequenceNumber.low); + offset +=8; + + num_bits = get_guint32(tvb, offset, little_endian); + proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4, + "numBits: %u", + num_bits); + offset += 4; + + if (num_bits+31 < num_bits) + num_longs = UINT_MAX; /* overflow */ + else + num_longs = (num_bits+31)/32; + while (num_longs != 0) + { + if (next_submsg-offset < 4) + { + proto_tree_add_text(rtps_bitmap_tree, tvb, offset, next_submsg-offset, + "bitmap[%d]: < 4 bytes remain in message", i); + offset = next_submsg; + break; + } + proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4, + "bitmap[%d]: 0x%08X", + i, get_guint32(tvb, offset, little_endian)); + offset +=4; + ++i; + --num_longs; + } /* end while */ + + *p_offset = offset; +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * dissect submessage: PAD * + * * + * (this submessage has no meaning and it is always valid) * + * *********************************************************************** */ + +static void +dissect_PAD(tvbuff_t *tvb, gint offset, guint8 flags, + int next_submsg_offset, proto_tree *rtps_submessage_tree) +{ + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset += 1; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * dissect submessage: VAR * + * * + * *********************************************************************** */ + +static void +dissect_VAR(tvbuff_t *tvb, gint offset, guint8 flags, gboolean little_endian, + int next_submsg_offset, proto_tree *rtps_submessage_tree) +{ + int min_len; + char buff[200]; + SequenceNumber writerSeqNumber; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + min_len = 20; + if ((flags & FLAG_H) != 0) + min_len += 8; + if ((flags & FLAG_P) != 0) + min_len += 4; + if (next_submsg_offset < min_len) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= %u)", + next_submsg_offset, min_len); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* readerObjectId*/ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Reader Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* writerObjectId*/ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Writer Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset+=4; + + /* H flag |XXXX|HAPE| => masks with 00001000b = 8 */ + if ((flags & FLAG_H) != 0) + { + /* HostId */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Host ID: %s", + host_id_to_string(offset,tvb,buff)); + offset+=4; + + /* App Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "App ID: %s", + app_id_to_string(offset, tvb, buff)); + offset +=4; + } + + /* Object Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* WriterSequence Number */ + seq_nr_to_string(offset, little_endian, tvb, &writerSeqNumber); + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8, + "WriterSeqNumber: 0x%X%X", + writerSeqNumber.high, writerSeqNumber.low); + offset +=8; + + /* P flag |XXXX|HAPE| => masks with 00000010b = 2 */ + if ((flags & FLAG_P) != 0) + { + get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset, + rtps_submessage_tree); + } +} + +/* *********************************************************************** */ + +/* *********************************************************************** * + * * + * get_ParameterSequence * + * * + * *********************************************************************** */ + + +static void +get_parameter_sequence(tvbuff_t *tvb, gint *p_offset, gboolean little_endian, + gint next_submsg_offset, proto_tree *tree) +{ + proto_item *ti; + proto_tree *rtps_parameter_sequence_tree; + proto_tree *rtps_parameter_tree; + gint offset = *p_offset; + guint16 parameter, param_length; + gint str_length; + SequenceNumber seqNumber; + char buff_tmp[MAX_PATHNAME]; + int i; + char sep; + + ti = proto_tree_add_text(tree, tvb, offset, (next_submsg_offset - offset), + "Parameters:"); + rtps_parameter_sequence_tree = proto_item_add_subtree(ti, + ett_rtps_parameter_sequence); + for (;;) + { + if (next_submsg_offset-offset < 2) + { + proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset, + next_submsg_offset-offset, + "Parameter: < 2 bytes remain in message"); + offset = next_submsg_offset; + break; + } + parameter = get_guint16(tvb, offset, little_endian); + ti = proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset, 2, + "%s", + val_to_str(parameter, parameter_id_vals, + "Unknown parameter (0x%04X)")); + rtps_parameter_tree = proto_item_add_subtree(ti, ett_rtps_parameter); + proto_tree_add_uint(rtps_parameter_tree, hf_rtps_parameter_id, + tvb, offset, 2, parameter); + offset +=2; + if (next_submsg_offset-offset < 2) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, + next_submsg_offset-offset, + "Parameter length: < 2 bytes remain in message"); + offset = next_submsg_offset; + proto_item_set_end(ti, tvb, offset); + break; + } + param_length = get_guint16(tvb, offset, little_endian); + proto_tree_add_uint(rtps_parameter_tree, hf_rtps_parameter_length, + tvb, offset, 2, param_length); + offset +=2; + + if (parameter == PID_SENTINEL) { + proto_item_set_end(ti, tvb, offset); + break; + } + + if (next_submsg_offset-offset < param_length) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, + next_submsg_offset-offset, + "Parameter value: < %u bytes remain in message", + param_length); + offset = next_submsg_offset; + proto_item_set_end(ti, tvb, offset); + break; + } + proto_item_set_end(ti, tvb, offset + param_length); + + switch (parameter) + { + case PID_PAD: + proto_item_append_text(ti, ": -"); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Padding"); + break; + + case PID_EXPIRATION_TIME: + if (param_length < 8) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 8"); + } + else + { + char *ntp_time_str; + + ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, ": %s", ntp_time_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Expiration time: %s", ntp_time_str); + } + break; + + case PID_PERSISTENCE: + if (param_length < 8) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 8"); + } + else + { + char *ntp_time_str; + + ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, ": %s", ntp_time_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Persistence: %s", ntp_time_str); + } + break; + + case PID_MINIMUM_SEPARATION: + if (param_length < 8) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 8"); + } + else + { + char *ntp_time_str; + + ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, ": %s", ntp_time_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Minimum separation: %s", ntp_time_str); + } + break; + + case PID_TOPIC: /* --- ?? funguje spravne ?? */ + str_length = tvb_strnlen(tvb, offset, param_length); + if (str_length == -1) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: Terminating zero missing"); + } + else + { + char *str; + + str = tvb_format_text(tvb, offset, str_length); + proto_item_append_text(ti, ": %s", str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Topic: %s", str); + } + break; + + case PID_STRENGTH: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + guint32 strength; + + strength = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, ": 0x%X", strength); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Strength: 0x%X", strength); + } + break; + + case PID_TYPE_NAME: /* --- ?? funguje spravne ?? */ + str_length = tvb_strnlen(tvb, offset, param_length); + if (str_length == -1) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: Terminating zero missing"); + } + else + { + char *str; + + str = tvb_format_text(tvb, offset, str_length); + proto_item_append_text(ti, ": %s", str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Type name: %s", str); + } + break; + + case PID_TYPE_CHECKSUM: + /* nacitam jako UNSIGNED - nemuze to byt i zaporne cislo?? */ + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + guint32 checksum; + + checksum = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, ": 0x%X", checksum); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Checksum: 0x%X", checksum); + } + break; + + case RTPS_PID_TYPE2_NAME: + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Parameter data"); + break; + + case RTPS_PID_TYPE2_CHECKSUM: + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Parameter data"); + break; + + case PID_METATRAFFIC_MULTICAST_IPADDRESS: + i = 0; + sep = ':'; + while (param_length >= 4) + { + char *ip_string; + + ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, "%c %s", sep, ip_string); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Address[%d]: %s", i, ip_string); + ++i; + offset +=4; + sep = ','; + param_length -= 4; /* decrement count */ + } + offset += param_length; + break; + + case PID_APP_IPADDRESS: + i = 0; + sep = ':'; + while (param_length >= 4) + { + char *ip_string; + + ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, "%c %s", sep, ip_string); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Address[%d]: %s", i, ip_string); + ++i; + offset +=4; + sep = ','; + param_length -= 4; /* decrement count */ + } + offset += param_length; + break; + + case PID_METATRAFFIC_UNICAST_PORT: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + char *port_str; + + port_str = port_to_string(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, ": %s", port_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Port: %s", port_str); + } + break; + + case PID_USERDATA_UNICAST_PORT: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + char *port_str; + + port_str = port_to_string(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, ": %s", port_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Port: %s", port_str); + } + break; + + case PID_EXPECTS_ACK: + if (param_length < 1) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 1"); + } + else + { + if (tvb_get_guint8(tvb, offset) == 0) + { + proto_item_append_text(ti, ": No"); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "ACK expected: No"); + } + else + { + proto_item_append_text(ti, ": Yes"); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "ACK expected: Yes"); + } + } + break; + + case PID_USERDATA_MULTICAST_IPADDRESS: + i = 0; + sep = ':'; + while (param_length >= 4) + { + char *ip_string; + + ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp); + proto_item_append_text(ti, "%c %s", sep, ip_string); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Address[%d]: %s", i, ip_string); + ++i; + offset +=4; + param_length -= 4; /* decrement count */ + } + offset += param_length; + break; + + case PID_MANAGER_KEY: + i = 0; + sep = ':'; + while (param_length >= 4) + { + guint32 manager_key; + + manager_key = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, "%c 0x%X", sep, manager_key); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Key[%d]: 0x%X", i, manager_key); + ++i; + offset +=4; + sep = ','; + param_length -= 4; /* decrement count */ + } + offset += param_length; + break; + + case PID_SEND_QUEUE_SIZE: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + guint32 send_queue_size; + + send_queue_size = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, ": %u", send_queue_size); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Send queue size: %u", send_queue_size); + } + break; + + case PID_PROTOCOL_VERSION: + if (param_length < 2) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 2"); + } + else + { + char *protocol_version_str; + + protocol_version_str = protocol_version_to_string(offset, tvb, buff_tmp); + proto_item_append_text(ti, ": %s", protocol_version_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Protocol version: %s", protocol_version_str); + } + break; + + case PID_VENDOR_ID: + if (param_length < 2) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 2"); + } + else + { + char *vendor_id_str; + + vendor_id_str = vendor_id_to_string(offset, tvb, buff_tmp); + proto_item_append_text(ti, ": %s", vendor_id_str); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Vendor ID: %s", vendor_id_str); + } + break; + + case PID_VARGAPPS_SEQUENCE_NUMBER_LAST: + if (param_length < 8) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 8"); + } + else + { + seq_nr_to_string(offset, little_endian, tvb, &seqNumber); + proto_item_append_text(ti, ": 0x%X%X", + seqNumber.high, seqNumber.low); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Sequence number: 0x%X%X", + seqNumber.high, seqNumber.low); + } + break; + + case PID_RECV_QUEUE_SIZE: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + guint32 recv_queue_size; + + recv_queue_size = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, ": %u", recv_queue_size); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Receive queue size: %u", recv_queue_size); + } + break; + + case PID_RELIABILITY_OFFERED: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + guint32 reliability_offered; + + reliability_offered = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, ": 0x%X", reliability_offered); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Reliability offered: 0x%X", reliability_offered); + } + break; + + case PID_RELIABILITY_REQUESTED: + if (param_length < 4) + { + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Bad parameter: length < 4"); + } + else + { + guint32 reliability_requested; + + reliability_requested = get_guint32(tvb, offset, little_endian); + proto_item_append_text(ti, ": 0x%X", reliability_requested); + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Reliability requested: 0x%X", reliability_requested); + } + break; + + default: + proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, + "Unknown parameter value"); + break; + } /* end switch */ + + offset += param_length; + } + + *p_offset = offset; +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: ISSUE * + * * + * *********************************************************************** */ + /* hotovo 12.01.04 - JEN OTESTOVAT :] */ +static void +dissect_ISSUE(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + int min_len; + char buff[40]; + SequenceNumber sequenceNumber; /* type struct */ + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + min_len = 16; + if ((flags & FLAG_P) != 0) + min_len += 4; + if (next_submsg_offset < min_len) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= %u)", + next_submsg_offset, min_len); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* Reader Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Reader Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* Writer Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Writer Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* Sequence Number */ + seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber); + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8, + "firstSeqNumber: 0x%X%X", + sequenceNumber.high, sequenceNumber.low); + offset += 8; + + /* Parameters */ +/* *********************************************************************** * + * - for future extension of the protocol - in * + * implementation of RTPS 1.0 can ignore the content * + * *********************************************************************** */ + + /* -- P flag |XXXX|HAPE| => masks with 00000010b = 2 */ + if ((flags & FLAG_P) != 0) + { + get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset, + rtps_submessage_tree); + } + + /* Issue Data */ + proto_tree_add_item(rtps_submessage_tree, hf_rtps_issue_data, tvb, + offset, (next_submsg_offset - offset), FALSE); + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: ACK * + * * + * *********************************************************************** */ + /* hotovo 12.01.04 - JEN OTESTOVAT :] */ +static void +dissect_ACK(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + char buff[40]; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + if (next_submsg_offset < 20) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= 20)", + next_submsg_offset); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* Reader Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Reader Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* Writer Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Writer Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree); + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: HEARTBEAT * + * * + * *********************************************************************** */ + /* hotovo 12.01.04 - JEN OTESTOVAT :] */ +static void +dissect_HEARTBEAT(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + char buff[40]; + SequenceNumber sequenceNumber; /* type struct */ + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + if (next_submsg_offset < 24) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= 24)", + next_submsg_offset); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* Reader Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Reader Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* Writer Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Writer Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* firstSeqNumber */ + seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber); + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8, + "firstSeqNumber: 0x%X%X", + sequenceNumber.high, sequenceNumber.low); + offset +=8; + + /* lastSeqNumber */ + seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber); + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8, + "lastSeqNumber: 0x%X%X", + sequenceNumber.high, sequenceNumber.low); + offset +=8; + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: GAP * + * * + * *********************************************************************** */ + /* hotovo 12.01.04 - JEN OTESTOVAT :] */ +static void +dissect_GAP(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + char buff[40]; + SequenceNumber sequenceNumber; /* type struct */ + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + if (next_submsg_offset < 28) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= 28)", + next_submsg_offset); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* Reader Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Reader Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* Writer Object ID */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Writer Object ID: %s ", + object_id_to_string(offset, tvb, buff)); + offset +=4; + + /* Sequence Number */ + seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber); + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8, + "firstSeqNumber: 0x%X%X", + sequenceNumber.high, sequenceNumber.low); + offset +=8; + + get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree); + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: INFO_TS * + * * + * *********************************************************************** */ + /* hotovo 12.01.04 - JEN OTESTOVAT :] */ + +static void +dissect_INFO_TS(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + char buff[10]; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + /* npTimestamp - valid if flag I = 1 * + * |XXXX|XXIE| => masks with 00000010b = 2 */ + if ((flags & FLAG_I) != 0) + { + if (next_submsg_offset < 8) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= 8)", + next_submsg_offset); + return; + } + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* npTimestamp - valid if flag I = 1 * + * |XXXX|XXIE| => masks with 00000010b = 2 */ + if ((flags & FLAG_I) != 0) + { + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8, + "ntpTimestamp: %s (sec)", + get_NtpTime(offset, tvb, little_endian,buff)); + offset +=8; + } + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: INFO_SRC * + * * + * *********************************************************************** */ +/* hotovo 12.01.04 JEN OTESTOVAT :] */ +static void +dissect_INFO_SRC(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + char buff[200]; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + if (next_submsg_offset < 16) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= 16)", + next_submsg_offset); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* IPAddress */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "appIP address: %s", + IP_to_string(offset, tvb, little_endian,buff)); + offset +=4; + + /* Protocol Version */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2, + "Protocol RTPS version %s -new", + protocol_version_to_string(offset, tvb, buff)); + offset +=2; + + /* Vendor Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2, + "VendorId: %s -new", + vendor_id_to_string(offset, tvb, buff)); + offset +=2; + + /* Host Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Host ID: %s", + host_id_to_string(offset,tvb,buff)); + offset+=4; + + /* App Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "App ID: %s-new", + app_id_to_string(offset, tvb, buff)); + offset +=4; + +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: INFO_REPLY * + * * + * *********************************************************************** */ + /* hotovo 11.01.04 :] */ +static void +dissect_INFO_REPLY(tvbuff_t *tvb, gint offset, guint8 flags, + gboolean little_endian, int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + int min_len; + char buff_ip[10], buff_port[10]; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + /* 'multicastReplyAdress' and 'multicastReplyPort' are * + * parts of submessage INFO REPLY which are available * + * only when FLAG M=1 flags: XXXX XXME */ + + if ((flags & FLAG_M) != 0) + min_len = 16; + else + min_len = 8; + if (next_submsg_offset < min_len) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= %u)", + next_submsg_offset, min_len); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* Unicat Reply IPAddress */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Unicast Reply IP Adress: %s", + IP_to_string(offset, tvb, little_endian,buff_ip)); + offset +=4; + + + /* Unicast Reply Port */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Unicast Reply IP Port: %s", + port_to_string(offset, tvb, little_endian,buff_port)); + offset +=4; + + + /* 'multicastReplyAdress' and 'multicastReplyPort' are * + * parts of submessage INFO REPLY which are available * + * only when FLAG M=1 flags: XXXX XXME */ + + if ((flags & FLAG_M) != 0) + { + /* Multicast Reply IPAddress */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Multicast Reply IP Adress: %s", + IP_to_string(offset, tvb, little_endian,buff_ip)); + offset +=4; + + /* Multicast Reply Port */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Multicast Reply IP Port: %s", + port_to_string(offset, tvb, little_endian,buff_port)); + offset +=4; + + } +} + +/* *********************************************************************** */ + + +/* *********************************************************************** * + * * + * subdissector for submessage: INFO_DST * + * * + * *********************************************************************** */ + /* HOTOVO 12.01.04 - JEN OTESOVAT :]*/ +static void +dissect_INFO_DST(tvbuff_t *tvb, gint offset, guint8 flags, + int next_submsg_offset, + proto_tree *rtps_submessage_tree) +{ + char buff[200]; + + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags, + tvb, offset, 1, flags); + offset +=1; + + if (next_submsg_offset < 8) + { + proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset, + "Octets to next header: %u (bogus, must be >= 8)", + next_submsg_offset); + return; + } + proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header, + tvb, offset, 2, next_submsg_offset); + offset +=2; + next_submsg_offset += offset; + + /* Host Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "Host ID: %s", + host_id_to_string(offset,tvb,buff)); + offset+=4; + + /* App Id */ + proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4, + "App ID: %s-new", + app_id_to_string(offset, tvb, buff)); + offset +=4; + +} + +/* *********************************************************************** * + * * + * Register the protocol with Ethereal * + * * + * *********************************************************************** */ + +void proto_register_rtps(void) +{ + static hf_register_info hf[] = { + + { &hf_rtps_submessage_id, + { "Submessage Id", "rtps.submessage_id", + FT_UINT8, BASE_HEX, VALS(submessage_id_vals), 0x0, + "Submessage flags", HFILL }}, + + { &hf_rtps_submessage_flags, + { "Submessage flags", "rtps.submessage_flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + "Submessage flags", HFILL }}, + + { &hf_rtps_octets_to_next_header, + { "Octets to next header", "rtps.octets_to_next_header", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Octets to next header", HFILL }}, + + { &hf_rtps_parameter_id, + { "Parameter Id", "rtps.parameter_id", + FT_UINT16, BASE_HEX, VALS(parameter_id_vals), 0x0, + "Parameter Id", HFILL }}, + + { &hf_rtps_parameter_length, + { "Parameter Length", "rtps.parameter_length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Parameter Length", HFILL }}, + + { &hf_rtps_issue_data, + { "User Data", "rtps.issue_data", + FT_BYTES, BASE_HEX, NULL, 0x0, + "Issue Data", HFILL }}, + }; + + static gint *ett[] = { + &ett_rtps, + &ett_rtps_submessage, + &ett_rtps_bitmap, + &ett_rtps_parameter_sequence, + &ett_rtps_parameter, + }; + + proto_rtps = proto_register_protocol("Real-Time Publish-Subscribe Wire Protocol", + "RTPS", "rtps"); + proto_register_field_array(proto_rtps, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + +} + + +void +proto_reg_handoff_rtps(void) +{ + heur_dissector_add("udp", dissect_rtps, proto_rtps); +} + |