feab79e328
svn path=/trunk/; revision=18196
2006 lines
71 KiB
C
2006 lines
71 KiB
C
/* 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$
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* 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
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <glib.h>
|
|
#include <epan/packet.h>
|
|
#include <epan/addr_resolv.h>
|
|
#include <epan/conversation.h>
|
|
#include <epan/emem.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,int buff_len);
|
|
static char *vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff, int buff_len);
|
|
|
|
static char *host_id_to_string(gint offset,tvbuff_t *tvb, char *buff, int buff_len);
|
|
static char *app_id_to_string(gint offset,tvbuff_t *tvb,char *buff,int buff_len);
|
|
static char *object_id_to_string(gint offset, tvbuff_t *tvb, char *buff, int buff_len);
|
|
|
|
static char *IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char *buff, int buff_len);
|
|
static char *port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char *buff, int buff_len);
|
|
static char *get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char *buff, int buff_len);
|
|
|
|
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;
|
|
int buff_len;
|
|
|
|
buff=ep_alloc(200);
|
|
buff[0]=0;
|
|
/* 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, 200));
|
|
offset +=2;
|
|
|
|
/* Vendor Id */
|
|
proto_tree_add_text(rtps_tree, tvb, offset, 2,
|
|
"VendorId: %s",
|
|
vendor_id_to_string(offset, tvb, buff, 200));
|
|
offset +=2;
|
|
|
|
/* Host Id */
|
|
proto_tree_add_text(rtps_tree, tvb, offset, 4,
|
|
"HostId: %s",
|
|
host_id_to_string(offset, tvb, buff, 200));
|
|
offset +=4;
|
|
|
|
/* App Id */
|
|
proto_tree_add_text(rtps_tree, tvb, offset, 4,
|
|
"App ID: %s",
|
|
app_id_to_string(offset, tvb, buff, 200));
|
|
|
|
}
|
|
|
|
/* 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 ) {g_snprintf(buff, 200, "App: ");}
|
|
if (appKind == MANAGER) {g_snprintf(buff, 200, "Man: ");}
|
|
if (appKind == AID_UNKNOWN) {g_snprintf(buff, 200, "Unknown:");}
|
|
|
|
if (appKind != MANAGEDAPPLICATION && appKind != MANAGER &&
|
|
appKind != AID_UNKNOWN) {g_snprintf(buff, 200, "ERROR in APP type");}
|
|
|
|
/* -- counts of submessages - for Information Frame */
|
|
if (count_msg_type[0]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "PAD(%d) ",count_msg_type[0]);
|
|
}
|
|
|
|
if (count_msg_type[1]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "VAR(%d) ",count_msg_type[1]);
|
|
}
|
|
|
|
if (count_msg_type[2]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "ISSUE(%d) ",count_msg_type[2]);
|
|
}
|
|
|
|
if (count_msg_type[3]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "ACK(%d) ",count_msg_type[3]);
|
|
}
|
|
|
|
if (count_msg_type[4]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "HEARTBEAT(%d) ",count_msg_type[4]);
|
|
}
|
|
|
|
if (count_msg_type[5]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "GAP(%d) ",count_msg_type[5]);
|
|
}
|
|
|
|
if (count_msg_type[6]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "INFO_TS(%d) ",count_msg_type[6]);
|
|
}
|
|
|
|
if (count_msg_type[7]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "INFO_SRC(%d) ",count_msg_type[7]);
|
|
}
|
|
|
|
if (count_msg_type[8]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "INFO_REPLY(%d) ",count_msg_type[8]);
|
|
}
|
|
|
|
if (count_msg_type[9]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "INFO_DST(%d) ",count_msg_type[9]);
|
|
}
|
|
|
|
if (count_msg_type[10]>0) {
|
|
buff_len=strlen(buff);
|
|
g_snprintf(buff+buff_len, 200-buff_len, "vendor specific(%d) ",count_msg_type[10]);
|
|
}
|
|
|
|
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, int buff_len)
|
|
{
|
|
guint8 major, minor;
|
|
|
|
/* protocol verzion = major.minor */
|
|
major = tvb_get_guint8(tvb, offset);
|
|
minor = tvb_get_guint8(tvb, (offset+1));
|
|
|
|
g_snprintf(buff, buff_len, "%d.%d", major, minor);
|
|
return(buff);
|
|
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* get Vendor Id *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
static char *
|
|
vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff, int buff_len)
|
|
{
|
|
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)
|
|
{ g_snprintf(buff, buff_len, "Real-Time Innovations,Inc.,CA,USA");
|
|
return(buff); }
|
|
|
|
g_snprintf(buff, buff_len, "Vendor unknown");
|
|
return(buff);
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* get IP Address *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
static char *
|
|
IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char *buff, int buff_len)
|
|
{
|
|
IPAddress ip;
|
|
guint8 a = 0, b = 0, c = 0, d = 0; /* IP Address = 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;
|
|
|
|
g_snprintf(buff, buff_len, "%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, int buff_len)
|
|
{
|
|
Port port = get_guint32(tvb, offset, little_endian);
|
|
/* get_guint32() - reads + endian conversion */
|
|
|
|
if (port == PORT_INVALID)
|
|
g_snprintf(buff, buff_len, "PORT_INVALID");
|
|
else
|
|
g_snprintf(buff, buff_len, "0x%X",port);
|
|
|
|
return(buff);
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* get NTP Time *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
static char *
|
|
get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char *buff, int buff_len)
|
|
{
|
|
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));
|
|
|
|
g_snprintf(buff, buff_len, "%f", time);
|
|
return(buff);
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* get Host Id *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
static char *
|
|
host_id_to_string(gint offset,tvbuff_t *tvb, char *buff, int buff_len)
|
|
{
|
|
guint32 hostId = tvb_get_ntohl(tvb, offset);
|
|
/* get_ntohl() automaticaly convert data to BIG ENDIAN */
|
|
|
|
g_snprintf(buff, buff_len, "0x%X", hostId);
|
|
return(buff);
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* get AppID *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
static char *
|
|
app_id_to_string(gint offset,tvbuff_t *tvb,char *buff, int buff_len)
|
|
{
|
|
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)
|
|
{
|
|
g_snprintf(buff, buff_len, "Managed App, InstanceId: 0x%X",instanceId);
|
|
return(buff);
|
|
}
|
|
|
|
if (appKind == MANAGER)
|
|
{
|
|
g_snprintf(buff, buff_len, "Manager, InstanceId: 0x%X",instanceId);
|
|
return(buff);
|
|
}
|
|
|
|
g_snprintf(buff, buff_len, "Unknown");
|
|
return(buff);
|
|
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* get Object_Id (32 bit) *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
static char *
|
|
object_id_to_string(gint offset, tvbuff_t *tvb, char *buff, int buff_len)
|
|
{
|
|
guint32 objectId = tvb_get_ntohl(tvb, offset);
|
|
/* get_ntohl() automaticaly convert data to BIG ENDIAN */
|
|
|
|
if (objectId == OID_UNKNOWN) { g_snprintf(buff, buff_len, "Unknown ObjectId");
|
|
return(buff);}
|
|
if (objectId == OID_APP) { g_snprintf(buff, buff_len, "applicationSelf");
|
|
return(buff);}
|
|
if (objectId == OID_WRITE_APPSELF){ g_snprintf(buff, buff_len, "writerApplicationSelf");
|
|
return(buff);}
|
|
if (objectId == OID_WRITE_APP) { g_snprintf(buff, buff_len, "writerApplications");
|
|
return(buff);}
|
|
if (objectId == OID_READ_APP) { g_snprintf(buff, buff_len, "readerApplications");
|
|
return(buff);}
|
|
if (objectId == OID_WRITE_MGR) { g_snprintf(buff, buff_len, "writerManagers");
|
|
return(buff);}
|
|
if (objectId == OID_READ_MGR) { g_snprintf(buff, buff_len, "readerManagers ");
|
|
return(buff);}
|
|
if (objectId == OID_WRITE_PUBL) { g_snprintf(buff, buff_len, "writerPublications");
|
|
return(buff);}
|
|
if (objectId == OID_READ_PUBL) { g_snprintf(buff, buff_len, "readerPublications");
|
|
return(buff);}
|
|
if (objectId == OID_WRITE_SUBS) { g_snprintf(buff, buff_len, "writerSubscriptions");
|
|
return(buff);}
|
|
if (objectId == OID_READ_SUBS) { g_snprintf(buff, buff_len, "readerSubscriptions");
|
|
return(buff);}
|
|
|
|
/* nothing from the possibilites above */
|
|
g_snprintf(buff, buff_len, "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;
|
|
SequenceNumber writerSeqNumber;
|
|
|
|
buff=ep_alloc(200);
|
|
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, 200));
|
|
offset +=4;
|
|
|
|
/* writerObjectId*/
|
|
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
|
|
"Writer Object ID: %s ",
|
|
object_id_to_string(offset, tvb, buff, 200));
|
|
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, 200));
|
|
offset+=4;
|
|
|
|
/* App Id */
|
|
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
|
|
"App ID: %s",
|
|
app_id_to_string(offset, tvb, buff, 200));
|
|
offset +=4;
|
|
}
|
|
|
|
/* Object Id */
|
|
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
|
|
"Object ID: %s ",
|
|
object_id_to_string(offset, tvb, buff, 200));
|
|
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;
|
|
int i;
|
|
char sep;
|
|
|
|
buff_tmp=ep_alloc(MAX_PATHNAME);
|
|
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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, MAX_PATHNAME);
|
|
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;
|
|
SequenceNumber sequenceNumber; /* type struct */
|
|
|
|
buff=ep_alloc(40);
|
|
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, 40));
|
|
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, 40));
|
|
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;
|
|
|
|
buff=ep_alloc(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, 40));
|
|
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, 40));
|
|
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;
|
|
SequenceNumber sequenceNumber; /* type struct */
|
|
|
|
buff=ep_alloc(40);
|
|
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, 40));
|
|
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, 40));
|
|
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;
|
|
SequenceNumber sequenceNumber; /* type struct */
|
|
|
|
buff=ep_alloc(40);
|
|
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, 40));
|
|
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, 40));
|
|
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;
|
|
|
|
buff=ep_alloc(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, 10));
|
|
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;
|
|
|
|
buff=ep_alloc(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, 200));
|
|
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, 200));
|
|
offset +=2;
|
|
|
|
/* Vendor Id */
|
|
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
|
|
"VendorId: %s -new",
|
|
vendor_id_to_string(offset, tvb, buff, 200));
|
|
offset +=2;
|
|
|
|
/* Host Id */
|
|
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
|
|
"Host ID: %s",
|
|
host_id_to_string(offset, tvb, buff, 200));
|
|
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, 200));
|
|
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, *buff_port;
|
|
|
|
buff_port=ep_alloc(10);
|
|
buff_ip=ep_alloc(200);
|
|
proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
|
|
tvb, offset, 1, flags);
|
|
offset +=1;
|
|
|
|
/* 'multicastReplyAddress' 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 Address: %s",
|
|
IP_to_string(offset, tvb, little_endian, buff_ip, 200));
|
|
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, 10));
|
|
offset +=4;
|
|
|
|
|
|
/* 'multicastReplyAddress' 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 Address: %s",
|
|
IP_to_string(offset, tvb, little_endian, buff_ip, 200));
|
|
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, 10));
|
|
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;
|
|
|
|
buff=ep_alloc(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, 200));
|
|
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, 200));
|
|
offset +=4;
|
|
|
|
}
|
|
|
|
/* *********************************************************************** *
|
|
* *
|
|
* Register the protocol with Wireshark *
|
|
* *
|
|
* *********************************************************************** */
|
|
|
|
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);
|
|
}
|
|
|