wireshark/packet-rtps.c

1749 lines
57 KiB
C
Raw Normal View History

/* 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: packet-rtps.c,v 1.1 2004/04/17 21:43:32 guy Exp $
*
* 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"
/* Swap bytes in 16 bit value. */
#define bswap_16(x) \
((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
/* Swap bytes in 32 bit value. */
#define bswap_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
/* 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_flags = -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;
/* Functions declarations */
static void dissect_PAD(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_VAR(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_ISSUE(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_ACK(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_HEARTBEAT(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_GAP(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_INFO_TS(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_INFO_SRC(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_INFO_REPLY(tvbuff_t *tvb,gint offset,proto_tree *tree);
static void dissect_INFO_DST(tvbuff_t *tvb,gint offset,proto_tree *tree);
static guint16 get_guint16(tvbuff_t *tvb, gint offset, gint16 e_bit);
static guint32 get_guint32(tvbuff_t *tvb, gint offset, gint16 e_bit);
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,gint16 e_bit,char buff[]);
static char *port_to_string(gint offset,tvbuff_t *tvb,gint16 e_bit,char buff[]);
static char *get_NtpTime(gint offset,tvbuff_t *tvb,gint16 e_bit,char buff[]);
static void get_bitmap(tvbuff_t *tvb, gint *p_offset, gint16 e_bit,
guint16 next_submsg, proto_tree *tree);
static char *get_parameter(gint offset, tvbuff_t *tvb, gint16 e_bit, char buff[],
guint16 parameter, guint16 param_length);
static gint seq_nr_to_string( gint offset, gint16 e_bit, tvbuff_t *tvb,
SequenceNumber *p_seqNumber);
/* global variable - submessage ENDIAN */
static gint16 e_bit = -1;
/* *********************************************************************** */
/* *********************************************************************** *
* *
* 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 message_len = 0;
gint appKind = 0;
guint8 submessageId = 0;
int next_submsg = 0;
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. */
message_len = tvb_length(tvb);
/* --- making disition if protocol is RTPS protocol --- */
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);
/* test which ENDIAN computer uses (this is set in 'config.h')*/
/*
#if WORDS_BIGENDIAN
proto_tree_add_text(rtps_tree, tvb, offset, 1,
"WORDS_BIGENDIAN %d",
WORDS_BIGENDIAN);
#else
proto_tree_add_text(rtps_tree, tvb, offset, 1,
"WORDS_BIGENDIAN 0");
#endif
*/
/* 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;
do {
submessageId = tvb_get_guint8(tvb, offset);
//read value in littlendian format
next_submsg = tvb_get_guint8(tvb, (offset+2))+
tvb_get_guint8(tvb, (offset+3))*0x100;
#if WORDS_BIGENDIAN
bswap_16(next_submsg);
#endif
switch (submessageId)
{
case PAD:
if (tree)
dissect_PAD(tvb, offset, rtps_tree);
count_msg_type[0]++;
break;
case VAR:
if (tree)
dissect_VAR(tvb, offset, rtps_tree);
count_msg_type[1]++;
break;
case ISSUE:
if (tree)
dissect_ISSUE(tvb, offset, rtps_tree);
count_msg_type[2]++;
break;
case ACK:
if (tree)
dissect_ACK(tvb, offset, rtps_tree);
count_msg_type[3]++;
break;
case HEARTBEAT:
if (tree)
dissect_HEARTBEAT(tvb,offset, rtps_tree);
count_msg_type[4]++;
break;
case GAP:
if (tree)
dissect_GAP(tvb, offset, rtps_tree);
count_msg_type[5]++;
break;
case INFO_TS:
if (tree)
dissect_INFO_TS(tvb, offset, rtps_tree);
count_msg_type[6]++;
break;
case INFO_SRC:
if (tree)
dissect_INFO_SRC(tvb, offset, rtps_tree);
count_msg_type[7]++;
break;
case INFO_REPLY:
if (tree)
dissect_INFO_REPLY(tvb, offset, rtps_tree);
count_msg_type[8]++;
break;
case INFO_DST:
if (tree)
dissect_INFO_DST(tvb, offset, rtps_tree);
count_msg_type[9]++;
break;
default:
if (tree)
proto_tree_add_text(rtps_tree, tvb, offset, 1,
"Submessage Id: Vendor-specific (0x%02x)",
submessageId);
break;
}
/* next submessage's offset */
offset += next_submsg+4;
} while (offset<message_len);
/* --- 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, gint16 e_bit)
{
guint16 value = tvb_get_ntohs(tvb, offset);
/* get_ntohs() automaticaly convert data to BIG ENDIAN */
/* WORDS_BIGENDIAN = machine endianing
e_bit = message endianing */
#if WORDS_BIGENDIAN
if(!e_bit) value = bswap_16(value);
#else
if( e_bit) value = bswap_16(value);
#endif
return(value);
}
/* *********************************************************************** */
/* *********************************************************************** *
* *
* get 32 bit from the stream *
* *
* *********************************************************************** */
static guint32 get_guint32(tvbuff_t *tvb, gint offset, gint16 e_bit)
{
guint32 value = tvb_get_ntohl(tvb, offset);
/* get_ntohl() automaticaly convert data to BIG ENDIAN */
/* WORDS_BIGENDIAN = machine endianing
e_bit = message endianing */
#if WORDS_BIGENDIAN
if(!e_bit) value = bswap_32(value);
#else
if( e_bit) value = bswap_32(value);
#endif
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,gint16 e_bit,char buff[])
{
IPAddress ip;
guint8 a = 0, b = 0, c = 0, d = 0; /* IP Adress = a.b.c.d */
ip = get_guint32(tvb, offset, e_bit);
//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,gint16 e_bit,char buff[])
{
Port port = get_guint32(tvb, offset, e_bit);
//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,gint16 e_bit,char buff[])
{
NtpTime ntpTime;
float time;
//get_guint32() - reads + endian conversion
ntpTime.seconds = get_guint32(tvb, offset, e_bit);
ntpTime.fraction = get_guint32(tvb, (offset + 4), e_bit);
time = 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, gint16 e_bit, tvbuff_t *tvb,
SequenceNumber *p_seqNumber)
{
/* get_ntohl() automaticaly convert data to BIG ENDIAN */
p_seqNumber->high = tvb_get_ntohl(tvb, offset);
offset += 4;
p_seqNumber->low = tvb_get_ntohl(tvb, offset);
/* WORDS_BIGENDIAN = machine endianing
e_bit = message endianing */
#if WORDS_BIGENDIAN
if(!e_bit) { p_seqNumber->high = bswap_32(p_seqNumber->high);
p_seqNumber->low = bswap_32(p_seqNumber->low); }
#else
if( e_bit) { p_seqNumber->high = bswap_32(p_seqNumber->high);
p_seqNumber->low = bswap_32(p_seqNumber->low); }
#endif
return(1);
}
/* *********************************************************************** */
/* *********************************************************************** *
* *
* get_Bitmap *
* *
* *********************************************************************** */
static void
get_bitmap(tvbuff_t *tvb, gint *p_offset, gint16 e_bit, guint16 next_submsg,
proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_bitmap_tree;
gint i = 0;
gint offset = *p_offset;
guint32 bitmap = 0x0;
SequenceNumber sequenceNumber;
/* 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, e_bit, tvb, &sequenceNumber);
proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 8,
"bitmapBase: 0x%X%X",
sequenceNumber.high, sequenceNumber.low);
offset +=8;
proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
"numBits: 0x%X",
get_guint32(tvb, offset, e_bit));
offset += 4;
while (offset < (next_submsg -1))
{
proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
"bitmap[%d]: 0x%08X",
i, get_guint32(tvb, offset, e_bit));
offset +=4;
++i;
} /* 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, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
ti = proto_tree_add_text(tree, tvb, offset, 1,"Submessage Id: PAD");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset += 1;
/* -- if you want to see 'flags' in window - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
flags = tvb_get_guint8(tvb, offset);
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
offset += 1;
/* --if you want to see'Octets to Next Header'in window - uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree,hf_rtps_octets_to_next_header,
tvb, offset+2, 2, TRUE);
*/
}
/* *********************************************************************** */
/* *********************************************************************** *
* *
* dissect submessage: VAR *
* *
* *********************************************************************** */
static void
dissect_VAR(tvbuff_t *tvb, gint offset, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
gint next_submsg_offset = 0;
char buff[200];
SequenceNumber writerSeqNumber;
guint16 parameter; /* sekvence parameter */
guint16 param_length; /* length of sekvence parameter */
ti = proto_tree_add_text(tree, tvb, offset, 1, "Submessage Id: VAR ");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset += 1;
flags = tvb_get_guint8(tvb, offset);
/* -- if you want to see flags in window - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
next_submsg_offset = offset + 2 + get_guint16(tvb, offset, e_bit);
/* actual offset + long of the octetsToNextHeader =
* = 2 Bytes + octetsToNextHeader */
/* -- if you want to see Offset to Next Header - just uncomment -- */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* 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, e_bit, 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)
{
proto_tree_add_text(rtps_submessage_tree, tvb, offset,
(next_submsg_offset - offset),
"Parameters:");
do
{
parameter = get_guint16(tvb, offset, e_bit); offset +=2;
param_length = get_guint16(tvb, offset, e_bit); offset +=2;
proto_tree_add_text(rtps_submessage_tree, tvb,offset, param_length,
"%s", get_parameter(offset, tvb, e_bit, buff,
parameter,param_length));
offset += param_length;
} while (offset < (next_submsg_offset -1));
} // end if
}
/* *********************************************************************** */
/* *********************************************************************** *
* *
* get_Parameter *
* *
* *********************************************************************** */
static char *
get_parameter(gint offset, tvbuff_t *tvb, gint16 e_bit, char buff[],
guint16 parameter, guint16 param_length)
{
char buff_tmp[MAX_PATHNAME];
int i;
SequenceNumber seqNumber;
switch (parameter)
{
case PID_PAD:
{
sprintf(buff," PARAM_PID_PAD: -");
return(buff);
}
case PID_SENTINEL:
{
sprintf(buff," PARAM_PID_SENTINEL: -");
return(buff);
}
case PID_EXPIRATION_TIME:
{
sprintf(buff," PID_EXPIRATION_TIME: %s",
get_NtpTime(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_PERSISTENCE:
{
sprintf(buff," PID_PERSISTENCE: %s",
get_NtpTime(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_MINIMUM_SEPARATION:
{
sprintf(buff," PID_MINIMUM_SEPARATION: %s",
get_NtpTime(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_TOPIC: //--- ?? funguje spravne ??
{
for (i = 0; i < param_length; i++)
{
buff_tmp[i] = tvb_get_guint8(tvb,offset);
offset++;
}
sprintf(buff," PID_TOPIC: ");
strcat(buff,buff_tmp);
return(buff);
}
case PID_STRENGTH:
{
sprintf(buff," PID_STRENGTH: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
case PID_TYPE_NAME: //--- ?? funguje spravne ??
{
for (i = 0; i < param_length; i++)
{
buff_tmp[i] = tvb_get_guint8(tvb,offset);
offset++;
}
sprintf(buff," PID_TYPE_NAME:");
strcat(buff,buff_tmp);
return(buff);
}
case PID_TYPE_CHECKSUM:
{
// nacitam jako UNSIGNED - nemuze to byt i zaporne cislo??
sprintf(buff," PID_TYPE_CHECKSUM: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
case RTPS_PID_TYPE2_NAME:
{
sprintf(buff," RTPS_PID_TYPE2_NAME:"); return(buff);
}
case RTPS_PID_TYPE2_CHECKSUM:
{
sprintf(buff," RTPS_PID_TYPE2_CHECKSUM:"); return(buff);
}
case PID_METATRAFFIC_MULTICAST_IPADDRESS:
{
sprintf(buff," PID_METATRAFFIC_MULTICAST_IPADDRESS: %s",
IP_to_string(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_APP_IPADDRESS:
{
sprintf(buff," PID_APP_IPADDRESS: %s",
IP_to_string(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_METATRAFFIC_UNICAST_PORT:
{
sprintf(buff," PID_METATRAFFIC_UNICAST_PORT: %s",
port_to_string(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_USERDATA_UNICAST_PORT:
{
sprintf(buff," PID_USERDATA_UNICAST_PORT: %s",
port_to_string(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_EXPECTS_ACK:
{
if (tvb_get_guint8(tvb, offset) == 0)
{ sprintf(buff," PID_EXPECTS_ACK: No"); return(buff); }
else
{ sprintf(buff," PID_EXPECTS_ACK: Yes"); return(buff); }
}
case PID_USERDATA_MULTICAST_IPADDRESS:
{
sprintf(buff," PID_USERDATA_MULTICAST_IPADDRESS: %s",
IP_to_string(offset, tvb, e_bit,buff_tmp));
return(buff);
}
case PID_MANAGER_KEY:
{
sprintf(buff," PID_STRENGTH: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
case PID_SEND_QUEUE_SIZE:
{
sprintf(buff," PID_SEND_QUEUE_SIZE: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
case PID_PROTOCOL_VERSION:
{
sprintf(buff," PID_PROTOCOL_VERSION: %s",
protocol_version_to_string(offset, tvb, buff_tmp));
return(buff);
}
case PID_VENDOR_ID:
{
sprintf(buff," PID_VENDOR_ID: %s",
vendor_id_to_string(offset, tvb, buff_tmp));
return(buff);
}
case PID_VARGAPPS_SEQUENCE_NUMBER_LAST:
{
seq_nr_to_string(offset, e_bit, tvb, &seqNumber);
sprintf(buff," PID_VARGAPPS_SEQUENCE_NUMBER_LAST: 0x%X%X",
seqNumber.high, seqNumber.low);
return(buff);
}
case PID_RECV_QUEUE_SIZE:
{
sprintf(buff," PID_RECV_QUEUE_SIZE: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
case PID_RELIABILITY_OFFERED:
{
sprintf(buff," PID_RELIABILITY_OFFERED: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
case PID_RELIABILITY_REQUESTED:
{
sprintf(buff," PID_RELIABILITY_REQUESTED: 0x%X",
get_guint32(tvb, offset, e_bit));
return(buff);
}
default:
{
sprintf(buff," :!: Unknown sekvence parameter");
return(buff);
}
} // end switch
}
/* *********************************************************************** */
/* *********************************************************************** *
* *
* subdissector for submessage: ISSUE *
* *
* *********************************************************************** */
/* hotovo 12.01.04 - JEN OTESTOVAT :] */
static void
dissect_ISSUE(tvbuff_t *tvb, gint offset, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
gint next_submsg_offset = 0;
char buff[40];
SequenceNumber sequenceNumber; /* type struct */
ti = proto_tree_add_text(tree, tvb, offset,1,"Submessage Id: ISSUE");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
flags = tvb_get_guint8(tvb, offset);
/* -- if you want to see flags in window - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
next_submsg_offset = offset + 2 + get_guint16(tvb, offset, e_bit);
/* next_submsg_offset = actual offset + long of the octetsToNextHeader
* + octetsToNextHeader */
/* -- if you want to see Offset to Next Header - just uncomment -- */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* 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, e_bit, tvb, &sequenceNumber);
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
"firstSeqNumber: 0x%X%X",
sequenceNumber.high, sequenceNumber.low);
offset += 8;
/* Parameters */
/* *********************************************************************** *
* 'Parameters' - are saved in 64bites so I dissect it like a *
* 'Sequence Number' *
* - 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)
{
seq_nr_to_string(offset, e_bit, tvb, &sequenceNumber);
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
"Parameters: 0x%X%X",
sequenceNumber.high, sequenceNumber.low);
offset += 8;
}
/* 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, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
gint next_submsg_offset = 0;
char buff[40];
ti = proto_tree_add_text(tree, tvb, offset, 1,"Submessage Id: ACK");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
flags = tvb_get_guint8(tvb, offset);
/* -- if you want to see flags in window - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
next_submsg_offset = offset + 2 + get_guint16(tvb, offset, e_bit);
/* next_submsg_offset = actual offset + long of the octetsToNextHeader
* + octetsToNextHeader */
/* -- if you want to see Offset to Next Header - just uncomment -- */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* 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,e_bit,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, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
guint8 flags = 0;
char buff[40];
SequenceNumber sequenceNumber; /* type struct */
ti = proto_tree_add_text(tree, tvb, offset,1,"Submessage Id: HEARTBEAT");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
/* -- if you want to see Submessage's Flags - just uncomment */
/* proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE); */
flags = tvb_get_guint8(tvb, offset);
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
/* -- if you want to see Offset to Next Header - just uncomment -- */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 1,
"Octets_to_next_header: 0x%X",
get_guint16(tvb, offset, e_bit));
*/
offset +=2;
/* 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, e_bit, 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, e_bit, 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, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
gint next_submsg_offset = 0;
char buff[40];
SequenceNumber sequenceNumber; /* type struct */
ti = proto_tree_add_text(tree, tvb, offset, 1,"Submessage Id: GAP");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
flags = tvb_get_guint8(tvb, offset);
/* -- if you want to see flags in window - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
next_submsg_offset = offset + 2 + get_guint16(tvb, offset, e_bit);
/* next_submsg_offset = actual offset + long of the octetsToNextHeader
* + octetsToNextHeader */
/* -- if you want to see Offset to Next Header - just uncomment -- */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* 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, e_bit, 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,e_bit,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, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
char buff[10];
ti = proto_tree_add_text(tree, tvb, offset,1,"Submessage Id: INFO_TS");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
flags = tvb_get_guint8(tvb, offset);
/* Flags -- if you want to see - just uncomment -- */ /*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
/* Offset to Next Header -- if you want to see - just uncomment */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* 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, e_bit,buff));
offset +=8;
}
}
/* *********************************************************************** */
/* *********************************************************************** *
* *
* subdissector for submessage: INFO_SRC *
* *
* *********************************************************************** */
/* hotovo 12.01.04 JEN OTESTOVAT :] */
static void
dissect_INFO_SRC(tvbuff_t *tvb, gint offset, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
char buff[200];
ti = proto_tree_add_text(tree,tvb,offset,1,"Submessage Id: INFO_SRC");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
flags = tvb_get_guint8(tvb, offset);
/* Flags -- if you want to see - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
/* Offset to Next Header -- if you want to see - just uncomment */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* IPAddress */
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
"appIP address: %s",
IP_to_string(offset, tvb, e_bit,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, proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
char buff_ip[10], buff_port[10];
ti = proto_tree_add_text(tree,tvb,offset,1,"Submessage Id: INFO_REPLY");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset +=1;
flags = tvb_get_guint8(tvb, offset);
/* Flags -- if you want to see - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
/* Offset to Next Header -- if you want to see - just uncomment */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
offset +=2;
/* Unicat Reply IPAddress */
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
"Unicast Reply IP Adress: %s",
IP_to_string(offset, tvb, e_bit,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, e_bit,buff_port));
offset +=4;
/* 'multicastReplayAdress' and 'multicastReplayPort'are *
* parts of submessage INFO REPLAY 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, e_bit,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, e_bit,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,proto_tree *tree)
{
proto_item *ti;
proto_tree *rtps_submessage_tree;
gint flags = 0;
char buff[200];
ti = proto_tree_add_text(tree, tvb, offset,1,"Submessage Id: INFO_DST");
rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
offset+=1;
flags = tvb_get_guint8(tvb, offset);
/* Flags -- if you want to see - just uncomment -- */
/*
proto_tree_add_item(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, FALSE);
*/
offset +=1;
/* E flag |XXXX|HAPE| => masks with 000000001b = 1 */
if ((flags & FLAG_E) != 0) e_bit = LITTLE_ENDIAN;
else e_bit = BIG_ENDIAN;
/* Offset to Next Header -- if you want to see - just uncomment */
/*
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
"Octets_to_next_header + offset (NEW): 0x%X",
next_submsg_offset);
*/
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;
}
/* *********************************************************************** *
* *
* Register the protocol with Ethereal *
* *
* *********************************************************************** */
void proto_register_rtps(void)
{
static hf_register_info hf[] = {
{ &hf_rtps_submessage_flags,
{ "Submessage flags", "rtps.submessage_flags",
FT_BYTES, BASE_HEX, NULL, 0x0,
"Submessage flags", 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,
};
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);
}