* version: 2004/04/15 9:40:45
* dedication to Kj :]
*
- * $Id: packet-rtps.c,v 1.7 2004/04/19 08:19:48 guy Exp $
+ * $Id: packet-rtps.c,v 1.8 2004/04/19 20:20:49 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
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,
static void get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
gint next_submsg, proto_tree *tree);
-static char *get_parameter(gint offset, tvbuff_t *tvb, gboolean little_endian, char buff[],
- guint16 parameter, guint16 param_length);
+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);
{ 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 }
+};
+
/* *********************************************************************** */
else little_endian = FALSE;
next_submsg = get_guint16(tvb, offset + 2, little_endian);
- proto_item_set_end(ti, tvb, offset + 2 + next_submsg);
+ proto_item_set_len(ti, next_submsg);
switch (submessageId)
{
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;
-
- proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
- "numBits: 0x%X",
- get_guint32(tvb, offset, little_endian));
- 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, little_endian));
- offset +=4;
- ++i;
- } /* end while */
-
- *p_offset = offset;
+ /* 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_VAR(tvbuff_t *tvb, gint offset, guint8 flags, gboolean little_endian,
int next_submsg_offset, proto_tree *rtps_submessage_tree)
{
- char buff[200];
- SequenceNumber writerSeqNumber;
- guint16 parameter; /* sekvence parameter */
- guint16 param_length; /* length of sekvence parameter */
+ int min_len;
+ char buff[200];
+ SequenceNumber writerSeqNumber;
- proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
- tvb, offset, 1, flags);
- offset +=1;
+ 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;
+ min_len = 20;
+ if ((flags & FLAG_H) != 0)
+ min_len += 8;
+ if ((flags & FLAG_P) != 0)
+ min_len += 4;
+ if (next_submsg_offset < min_len)
+ {
+ proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
+ tvb, offset, 2, next_submsg_offset,
+ "Octets to next header: %u (bogus, must be >= %u)",
+ next_submsg_offset, min_len);
+ return;
+ }
+ proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
+ tvb, offset, 2, next_submsg_offset);
+ offset +=2;
+ next_submsg_offset += offset;
/* readerObjectId*/
- proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
- "Reader Object ID: %s ",
- object_id_to_string(offset, tvb, buff));
- offset +=4;
+ 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;
- /* writerObjectId*/
+ /* H flag |XXXX|HAPE| => masks with 00001000b = 8 */
+ if ((flags & FLAG_H) != 0)
+ {
+ /* HostId */
proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
- "Writer Object ID: %s ",
- object_id_to_string(offset, tvb, buff));
+ "Host ID: %s",
+ host_id_to_string(offset,tvb,buff));
offset+=4;
- /* H flag |XXXX|HAPE| => masks with 00001000b = 8 */
- if ((flags & FLAG_H) != 0)
- {
- /* HostId */
- proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
- "Host ID: %s",
- host_id_to_string(offset,tvb,buff));
- offset+=4;
-
- /* App Id */
- proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
- "App ID: %s",
- app_id_to_string(offset, tvb, buff));
- offset +=4;
- }
-
- /* Object Id */
- proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
- "Object ID: %s ",
- object_id_to_string(offset, tvb, buff));
- offset +=4;
-
- /* WriterSequence Number */
- seq_nr_to_string(offset, little_endian, tvb, &writerSeqNumber);
- proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
- "WriterSeqNumber: 0x%X%X",
- writerSeqNumber.high, writerSeqNumber.low);
- offset +=8;
-
-
- /* P flag |XXXX|HAPE| => masks with 00000010b = 2 */
- if ((flags & FLAG_P) != 0)
- {
- proto_tree_add_text(rtps_submessage_tree, tvb, offset,
- (next_submsg_offset - offset),
- "Parameters:");
- do
- {
- parameter = get_guint16(tvb, offset, little_endian); offset +=2;
- param_length = get_guint16(tvb, offset, little_endian); offset +=2;
-
- proto_tree_add_text(rtps_submessage_tree, tvb,offset, param_length,
- "%s", get_parameter(offset, tvb, little_endian, buff,
- parameter,param_length));
- offset += param_length;
-
- } while (offset < (next_submsg_offset -1));
+ /* App Id */
+ proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
+ "App ID: %s",
+ app_id_to_string(offset, tvb, buff));
+ offset +=4;
+ }
- } /* end if */
+ /* Object Id */
+ proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
+ "Object ID: %s ",
+ object_id_to_string(offset, tvb, buff));
+ offset +=4;
+ /* WriterSequence Number */
+ seq_nr_to_string(offset, little_endian, tvb, &writerSeqNumber);
+ proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
+ "WriterSeqNumber: 0x%X%X",
+ writerSeqNumber.high, writerSeqNumber.low);
+ offset +=8;
+ /* P flag |XXXX|HAPE| => masks with 00000010b = 2 */
+ if ((flags & FLAG_P) != 0)
+ {
+ get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
+ rtps_submessage_tree);
+ }
}
/* *********************************************************************** */
-
/* *********************************************************************** *
* *
- * get_Parameter *
+ * get_ParameterSequence *
* *
* *********************************************************************** */
-static char *
-get_parameter(gint offset, tvbuff_t *tvb, gboolean little_endian, char buff[],
- guint16 parameter, guint16 param_length)
-{
- char buff_tmp[MAX_PATHNAME];
- int i;
-
- SequenceNumber seqNumber;
- switch (parameter)
+static void
+get_parameter_sequence(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
+ gint next_submsg_offset, proto_tree *tree)
+{
+ proto_item *ti;
+ proto_tree *rtps_parameter_sequence_tree;
+ proto_tree *rtps_parameter_tree;
+ gint offset = *p_offset;
+ guint16 parameter, param_length;
+ gint str_length;
+ SequenceNumber seqNumber;
+ char buff_tmp[MAX_PATHNAME];
+ int i;
+
+ 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 (;;)
{
- case PID_PAD:
+ if (next_submsg_offset-offset < 2)
{
- sprintf(buff," PARAM_PID_PAD: -");
- return(buff);
+ 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;
}
-
- case PID_SENTINEL:
+ parameter = get_guint16(tvb, offset, little_endian);
+ ti = proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset, 2,
+ "Parameter: %s",
+ val_to_str(parameter, parameter_id_vals,
+ "Unknown (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)
{
- sprintf(buff," PARAM_PID_SENTINEL: -");
- return(buff);
+ 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;
}
- case PID_EXPIRATION_TIME:
+ if (next_submsg_offset-offset < param_length)
{
- sprintf(buff," PID_EXPIRATION_TIME: %s",
- get_NtpTime(offset, tvb, little_endian,buff_tmp));
- return(buff);
+ 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);
- case PID_PERSISTENCE:
+ switch (parameter)
{
- sprintf(buff," PID_PERSISTENCE: %s",
- get_NtpTime(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_PAD:
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_PAD: -");
+ break;
- case PID_MINIMUM_SEPARATION:
- {
- sprintf(buff," PID_MINIMUM_SEPARATION: %s",
- get_NtpTime(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_EXPIRATION_TIME:
+ if (param_length < 8)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_EXPIRATION_TIME: length < 8");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_EXPIRATION_TIME: %s",
+ get_NtpTime(offset, tvb, little_endian,buff_tmp));
+ }
+ break;
- case PID_TOPIC: /* --- ?? funguje spravne ?? */
- {
- for (i = 0; i < param_length; i++)
- {
- buff_tmp[i] = tvb_get_guint8(tvb,offset);
- offset++;
- }
+ case PID_PERSISTENCE:
+ if (param_length < 8)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_PERSISTENCE: length < 8");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_PERSISTENCE: %s",
+ get_NtpTime(offset, tvb, little_endian,buff_tmp));
+ }
+ break;
- sprintf(buff," PID_TOPIC: ");
- strcat(buff,buff_tmp);
- return(buff);
- }
+ case PID_MINIMUM_SEPARATION:
+ if (param_length < 8)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_MINIMUM_SEPARATION: length < 8");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_MINIMUM_SEPARATION: %s",
+ get_NtpTime(offset, tvb, little_endian,buff_tmp));
+ }
+ break;
- case PID_STRENGTH:
- {
- sprintf(buff," PID_STRENGTH: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ 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,
+ "PID_TOPIC: Terminating zero missing");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_TOPIC: %s",
+ tvb_format_text(tvb, offset, str_length));
+ }
+ break;
- 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_STRENGTH:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_MINIMUM_SEPARATION: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_STRENGTH: 0x%X",
+ get_guint32(tvb, offset, little_endian));
+ }
+ break;
- case PID_TYPE_CHECKSUM:
- {
- /* nacitam jako UNSIGNED - nemuze to byt i zaporne cislo?? */
- sprintf(buff," PID_TYPE_CHECKSUM: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ 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,
+ "PID_TYPE_NAME: Terminating zero missing");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_TYPE_NAME: %s",
+ tvb_format_text(tvb, offset, str_length));
+ }
+ 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,
+ "PID_MINIMUM_SEPARATION: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_TYPE_CHECKSUM: 0x%X",
+ get_guint32(tvb, offset, little_endian));
+ }
+ break;
- case RTPS_PID_TYPE2_NAME:
- {
- sprintf(buff," RTPS_PID_TYPE2_NAME:"); return(buff);
- }
+ case RTPS_PID_TYPE2_NAME:
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "RTPS_PID_TYPE2_NAME");
+ break;
+
+ case RTPS_PID_TYPE2_CHECKSUM:
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "RTPS_PID_TYPE2_CHECKSUM");
+ break;
- case RTPS_PID_TYPE2_CHECKSUM:
- {
- sprintf(buff," RTPS_PID_TYPE2_CHECKSUM:"); return(buff);
- }
+ case PID_METATRAFFIC_MULTICAST_IPADDRESS:
+ i = 0;
+ while (param_length >= 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_METATRAFFIC_MULTICAST_IPADDRESS[%d]: %s", i,
+ IP_to_string(offset, tvb, little_endian,buff_tmp));
+ ++i;
+ offset +=4;
+ }
+ offset += param_length;
+ break;
- case PID_METATRAFFIC_MULTICAST_IPADDRESS:
- {
- sprintf(buff," PID_METATRAFFIC_MULTICAST_IPADDRESS: %s",
- IP_to_string(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_APP_IPADDRESS:
+ i = 0;
+ while (param_length >= 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_APP_IPADDRESS[%d]: %s", i,
+ IP_to_string(offset, tvb, little_endian,buff_tmp));
+ ++i;
+ offset +=4;
+ }
+ offset += param_length;
+ break;
- case PID_APP_IPADDRESS:
- {
- sprintf(buff," PID_APP_IPADDRESS: %s",
- IP_to_string(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_METATRAFFIC_UNICAST_PORT:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_METATRAFFIC_UNICAST_PORT: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_METATRAFFIC_UNICAST_PORT: %s",
+ port_to_string(offset, tvb, little_endian,buff_tmp));
+ }
+ break;
- case PID_METATRAFFIC_UNICAST_PORT:
- {
- sprintf(buff," PID_METATRAFFIC_UNICAST_PORT: %s",
- port_to_string(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_USERDATA_UNICAST_PORT:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_USERDATA_UNICAST_PORT: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_USERDATA_UNICAST_PORT: %s",
+ port_to_string(offset, tvb, little_endian,buff_tmp));
+ }
+ break;
- case PID_USERDATA_UNICAST_PORT:
- {
- sprintf(buff," PID_USERDATA_UNICAST_PORT: %s",
- port_to_string(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_EXPECTS_ACK:
+ if (param_length < 1)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_USERDATA_UNICAST_PORT: length < 1");
+ }
+ else
+ {
+ if (tvb_get_guint8(tvb, offset) == 0)
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_EXPECTS_ACK: No");
+ else
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_EXPECTS_ACK: Yes");
+ }
+ break;
- 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:
+ i = 0;
+ while (param_length >= 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_USERDATA_MULTICAST_IPADDRESS[%d]: %s", i,
+ IP_to_string(offset, tvb, little_endian,buff_tmp));
+ ++i;
+ offset +=4;
+ }
+ offset += param_length;
+ break;
- case PID_USERDATA_MULTICAST_IPADDRESS:
- {
- sprintf(buff," PID_USERDATA_MULTICAST_IPADDRESS: %s",
- IP_to_string(offset, tvb, little_endian,buff_tmp));
- return(buff);
- }
+ case PID_MANAGER_KEY:
+ i = 0;
+ while (param_length >= 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_MANAGER_KEY[%d]: 0x%X", i,
+ get_guint32(tvb, offset, little_endian));
+ ++i;
+ offset +=4;
+ }
+ offset += param_length;
+ break;
- case PID_MANAGER_KEY:
- {
- sprintf(buff," PID_STRENGTH: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ case PID_SEND_QUEUE_SIZE:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_SEND_QUEUE_SIZE: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_SEND_QUEUE_SIZE: %u",
+ get_guint32(tvb, offset, little_endian));
+ }
+ break;
- case PID_SEND_QUEUE_SIZE:
- {
- sprintf(buff," PID_SEND_QUEUE_SIZE: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ case PID_PROTOCOL_VERSION:
+ if (param_length < 2)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_PROTOCOL_VERSION: length < 2");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_PROTOCOL_VERSION: %s",
+ protocol_version_to_string(offset, tvb, buff_tmp));
+ }
+ break;
- case PID_PROTOCOL_VERSION:
- {
- sprintf(buff," PID_PROTOCOL_VERSION: %s",
- protocol_version_to_string(offset, tvb, buff_tmp));
- return(buff);
- }
+ case PID_VENDOR_ID:
+ if (param_length < 2)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_VENDOR_ID: length < 2");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_VENDOR_ID: %s",
+ vendor_id_to_string(offset, tvb, buff_tmp));
+ }
+ break;
- 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:
+ if (param_length < 8)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_VARGAPPS_SEQUENCE_NUMBER_LAST: length < 8");
+ }
+ else
+ {
+ seq_nr_to_string(offset, little_endian, tvb, &seqNumber);
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_VARGAPPS_SEQUENCE_NUMBER_LAST: 0x%X%X",
+ seqNumber.high, seqNumber.low);
+ }
+ break;
- case PID_VARGAPPS_SEQUENCE_NUMBER_LAST:
- {
- seq_nr_to_string(offset, little_endian, tvb, &seqNumber);
- sprintf(buff," PID_VARGAPPS_SEQUENCE_NUMBER_LAST: 0x%X%X",
- seqNumber.high, seqNumber.low);
- return(buff);
- }
+ case PID_RECV_QUEUE_SIZE:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_RECV_QUEUE_SIZE: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_RECV_QUEUE_SIZE: %u",
+ get_guint32(tvb, offset, little_endian));
+ }
+ break;
- case PID_RECV_QUEUE_SIZE:
- {
- sprintf(buff," PID_RECV_QUEUE_SIZE: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ case PID_RELIABILITY_OFFERED:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_RELIABILITY_OFFERED: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_RELIABILITY_OFFERED: 0x%X",
+ get_guint32(tvb, offset, little_endian));
+ }
+ break;
- case PID_RELIABILITY_OFFERED:
- {
- sprintf(buff," PID_RELIABILITY_OFFERED: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ case PID_RELIABILITY_REQUESTED:
+ if (param_length < 4)
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_RELIABILITY_OFFERED: length < 4");
+ }
+ else
+ {
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "PID_RELIABILITY_REQUESTED: 0x%X",
+ get_guint32(tvb, offset, little_endian));
+ }
+ break;
- case PID_RELIABILITY_REQUESTED:
- {
- sprintf(buff," PID_RELIABILITY_REQUESTED: 0x%X",
- get_guint32(tvb, offset, little_endian));
- return(buff);
- }
+ default:
+ proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
+ "Unknown parameter value");
+ break;
+ } /* end switch */
- default:
- {
- sprintf(buff," :!: Unknown sequence parameter");
- return(buff);
+ offset += param_length;
+ if (parameter == PID_SENTINEL)
+ break;
}
- } /* end switch */
+ *p_offset = offset;
}
/* *********************************************************************** */
gboolean little_endian, int next_submsg_offset,
proto_tree *rtps_submessage_tree)
{
+ int min_len;
char buff[40];
SequenceNumber sequenceNumber; /* type struct */
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;
/* 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, little_endian, tvb, &sequenceNumber);
- proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
- "Parameters: 0x%X%X",
- sequenceNumber.high, sequenceNumber.low);
- offset += 8;
+ get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
+ rtps_submessage_tree);
}
/* Issue Data */
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;
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;
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;
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;
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;
gboolean little_endian, int next_submsg_offset,
proto_tree *rtps_submessage_tree)
{
+ int min_len;
char buff_ip[10], buff_port[10];
proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
tvb, offset, 1, flags);
offset +=1;
+ /* 'multicastReplyAdress' and 'multicastReplyPort' are *
+ * parts of submessage INFO REPLY which are available *
+ * only when FLAG M=1 flags: XXXX XXME */
+
+ if ((flags & FLAG_M) != 0)
+ min_len = 16;
+ else
+ min_len = 8;
+ if (next_submsg_offset < min_len)
+ {
+ proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
+ tvb, offset, 2, next_submsg_offset,
+ "Octets to next header: %u (bogus, must be >= %u)",
+ next_submsg_offset, min_len);
+ return;
+ }
proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
tvb, offset, 2, next_submsg_offset);
offset +=2;
offset +=4;
- /* 'multicastReplayAdress' and 'multicastReplayPort'are *
- * parts of submessage INFO REPLAY which are available *
+ /* 'multicastReplyAdress' and 'multicastReplyPort' are *
+ * parts of submessage INFO REPLY which are available *
* only when FLAG M=1 flags: XXXX XXME */
if ((flags & FLAG_M) != 0)
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;
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,
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,
&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",