diff options
-rw-r--r-- | epan/dissectors/packet-rtps.c | 1869 | ||||
-rw-r--r-- | epan/dissectors/packet-rtps.h | 77 |
2 files changed, 1665 insertions, 281 deletions
diff --git a/epan/dissectors/packet-rtps.c b/epan/dissectors/packet-rtps.c index 9167ef0fed..a12dfb49b8 100644 --- a/epan/dissectors/packet-rtps.c +++ b/epan/dissectors/packet-rtps.c @@ -3,14 +3,15 @@ * * Routines for Real-Time Publish-Subscribe Protocol (RTPS) dissection * - * Copyright 2005, Fabrizio Bertocci <fabrizio@rti.com> + * (c) 2005-2014 Copyright, Real-Time Innovations, Inc. * Real-Time Innovations, Inc. - * 385 Moffett Park Drive + * 232 East Java Drive * Sunnyvale, CA 94089 * * 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> @@ -62,6 +63,12 @@ void proto_register_rtps(void); void proto_reg_handoff_rtps(void); +#define MAX_GUID_PREFIX_SIZE (128) +#define MAX_GUID_SIZE (160) +#define MAX_VENDOR_ID_SIZE (128) +#define MAX_PARAM_SIZE (256) +#define MAX_NTP_TIME_SIZE (128) + static const char * const SM_EXTRA_RPLUS = "(r+)"; static const char * const SM_EXTRA_RMINUS = "(r-)"; static const char * const SM_EXTRA_WPLUS = "(w+)"; @@ -149,7 +156,7 @@ static int hf_rtps_resource_limit_max_samples_per_instances = -1; static int hf_rtps_filter_bitmap = -1; static int hf_rtps_type_checksum = -1; static int hf_rtps_queue_size = -1; -static int hf_rtps_acknack_counter = -1; +static int hf_rtps_acknack_count = -1; static int hf_rtps_durability_service_history_kind = -1; static int hf_rtps_durability_service_history_depth = -1; static int hf_rtps_durability_service_max_samples = -1; @@ -226,6 +233,34 @@ static int hf_rtps_param_builtin_endpoint_set = -1; static int hf_rtps_param_plugin_promiscuity_kind = -1; static int hf_rtps_param_service_kind = -1; +static int hf_rtps_param_ntpt_sec = -1; +static int hf_rtps_param_ntpt_fraction = -1; +static int hf_rtps_transportInfo_classId = -1; +static int hf_rtps_transportInfo_messageSizeMax = -1; +static int hf_rtps_param_app_ack_count = -1; +static int hf_rtps_param_app_ack_virtual_writer_count = -1; +static int hf_rtps_param_app_ack_conf_virtual_writer_count = -1; +static int hf_rtps_param_app_ack_conf_count = -1; +static int hf_rtps_param_app_ack_interval_payload_length = -1; +static int hf_rtps_param_app_ack_interval_flags = -1; +static int hf_rtps_param_app_ack_interval_count = -1; +static int hf_rtps_param_app_ack_octets_to_next_virtual_writer = -1; +static int hf_rtps_expects_virtual_heartbeat = -1; +static int hf_rtps_direct_communication = -1; +static int hf_rtps_param_peer_host_epoch = -1; +static int hf_rtps_virtual_heartbeat_count = -1; +static int hf_rtps_virtual_heartbeat_num_virtual_guids = -1; +static int hf_rtps_virtual_heartbeat_num_writers = -1; +static int hf_rtps_param_extended_parameter = -1; +static int hf_rtps_param_extended_pid_length = -1; +static int hf_rtps_param_type_consistency_kind = -1; +static int hf_rtps_parameter_data = -1; +static int hf_rtps_param_product_version_major = -1; +static int hf_rtps_param_product_version_minor = -1; +static int hf_rtps_param_product_version_release = -1; +static int hf_rtps_param_product_version_release_as_char = -1; +static int hf_rtps_param_product_version_revision = -1; +static int hf_rtps_param_acknowledgment_kind = -1; /* Subtree identifiers */ static gint ett_rtps = -1; @@ -258,6 +293,17 @@ static gint ett_rtps_part_message_data = -1; static gint ett_rtps_sample_info_list = -1; static gint ett_rtps_sample_info = -1; static gint ett_rtps_sample_batch_list = -1; +static gint ett_rtps_locator_filter_locator = -1; +static gint ett_rtps_writer_heartbeat_virtual_list = -1; +static gint ett_rtps_writer_heartbeat_virtual = -1; +static gint ett_rtps_virtual_guid_heartbeat_virtual_list = -1; +static gint ett_rtps_virtual_guid_heartbeat_virtual = -1; +static gint ett_rtps_app_ack_virtual_writer_interval_list = -1; +static gint ett_rtps_app_ack_virtual_writer_interval = -1; +static gint ett_rtps_transport_info = -1; +static gint ett_rtps_app_ack_virtual_writer_list = -1; +static gint ett_rtps_app_ack_virtual_writer = -1; +static gint ett_rtps_product_version = -1; static expert_field ei_rtps_sm_octets_to_next_header_error = EI_INIT; static expert_field ei_rtps_port_invalid = EI_INIT; @@ -269,6 +315,7 @@ static expert_field ei_rtps_locator_port = EI_INIT; static expert_field ei_rtps_more_samples_available = EI_INIT; static expert_field ei_rtps_parameter_not_decoded = EI_INIT; static expert_field ei_rtps_sm_octets_to_next_header_not_zero = EI_INIT; +static expert_field ei_rtps_unsupported_non_builtin_param_seq = EI_INIT; /***************************************************************************/ /* Preferences */ @@ -298,6 +345,7 @@ static const value_string vendor_vals[] = { static const value_string entity_id_vals[] = { { ENTITYID_UNKNOWN, "ENTITYID_UNKNOWN" }, + { ENTITYID_PARTICIPANT, "ENTITYID_PARTICIPANT" }, { ENTITYID_BUILTIN_TOPIC_WRITER, "ENTITYID_BUILTIN_TOPIC_WRITER" }, { ENTITYID_BUILTIN_TOPIC_READER, "ENTITYID_BUILTIN_TOPIC_READER" }, { ENTITYID_BUILTIN_PUBLICATIONS_WRITER, "ENTITYID_BUILTIN_PUBLICATIONS_WRITER" }, @@ -306,6 +354,8 @@ static const value_string entity_id_vals[] = { { ENTITYID_BUILTIN_SUBSCRIPTIONS_READER, "ENTITYID_BUILTIN_SUBSCRIPTIONS_READER" }, { ENTITYID_BUILTIN_SDP_PARTICIPANT_WRITER, "ENTITYID_BUILTIN_SDP_PARTICIPANT_WRITER" }, { ENTITYID_BUILTIN_SDP_PARTICIPANT_READER, "ENTITYID_BUILTIN_SDP_PARTICIPANT_READER" }, + { ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER, "ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER" }, + { ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER, "ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER" }, /* Deprecated Items */ { ENTITYID_APPLICATIONS_WRITER, "writerApplications [DEPRECATED]" }, @@ -397,6 +447,9 @@ static const value_string submessage_id_valsv2[] = { { SUBMESSAGE_ACKNACK_SESSION, "ACKNACK_SESSION" }, { SUBMESSAGE_HEARTBEAT_SESSION, "HEARTBEAT_SESSION" }, { SUBMESSAGE_RTPS_DATA_SESSION, "DATA_SESSION" }, + { SUBMESSAGE_APP_ACK, "APP_ACK" }, + { SUBMESSAGE_APP_ACK_CONF, "APP_ACK_CONF" }, + { SUBMESSAGE_HEARTBEAT_VIRTUAL, "HEARTBEAT_VIRTUAL" }, /* Deprecated submessages */ { SUBMESSAGE_DATA, "DATA_deprecated" }, { SUBMESSAGE_NOKEY_DATA, "NOKEY_DATA_deprecated" }, @@ -566,6 +619,7 @@ static const value_string parameter_id_v2_vals[] = { { PID_ENTITY_NAME, "PID_ENTITY_NAME" }, { PID_KEY_HASH, "PID_KEY_HASH" }, { PID_STATUS_INFO, "PID_STATUS_INFO" }, + { PID_TYPE_CONSISTENCY, "PID_TYPE_CONSISTENCY" }, /* Vendor specific: RTI */ { PID_PRODUCT_VERSION, "PID_PRODUCT_VERSION" }, @@ -575,6 +629,15 @@ static const value_string parameter_id_v2_vals[] = { { PID_TYPECODE_RTPS2, "PID_TYPECODE" }, { PID_DISABLE_POSITIVE_ACKS, "PID_DISABLE_POSITIVE_ACKS" }, { PID_LOCATOR_FILTER_LIST, "PID_LOCATOR_FILTER_LIST" }, + { PID_ROLE_NAME, "PID_ROLE_NAME"}, + { PID_ACK_KIND, "PID_ACK_KIND" }, + { PID_PEER_HOST_EPOCH, "PID_PEER_HOST_EPOCH" }, + { PID_TRANSPORT_INFO_LIST, "PID_TRANSPORT_INFO_LIST" }, + { PID_DIRECT_COMMUNICATION, "PID_DIRECT_COMMUNICATION" }, + { PID_EXTENDED, "PID_EXTENDED" }, + { PID_TYPE_OBJECT, "PID_TYPE_OBJECT" }, + { PID_EXPECTS_VIRTUAL_HB, "PID_EXPECTS_VIRTUAL_HB" }, + { PID_DOMAIN_ID, "PID_DOMAIN_ID" }, /* The following PID are deprecated */ { PID_DEADLINE_OFFERED, "PID_DEADLINE_OFFERED [deprecated]" }, @@ -672,6 +735,40 @@ static const value_string participant_message_data_kind [] = { { 0, NULL } }; +/* Vendor specific: RTI */ +static const value_string type_consistency_kind_vals[] = { + { DISALLOW_TYPE_COERCION, "DISALLOW_TYPE_COERCION" }, + { ALLOW_TYPE_COERCION, "ALLOW_TYPE_COERCION" }, + { 0, NULL } +}; + +/* Vendor specific: RTI */ +static const value_string acknowledgement_kind_vals[] = { + { PROTOCOL_ACKNOWLEDGMENT, "PROTOCOL_ACKNOWLEDGMENT" }, + { APPLICATION_AUTO_ACKNOWLEDGMENT, "APPLICATION_AUTO_ACKNOWLEDGMENT" }, + { APPLICATION_ORDERED_ACKNOWLEDGMENT, "APPLICATION_ORDERED_ACKNOWLEDGMENT" }, + { APPLICATION_EXPLICIT_ACKNOWLEDGMENT, "APPLICATION_EXPLICIT_ACKNOWLEDGMENT" }, + { 0, NULL } +}; + +/* Vendor specific: RTI */ +static const value_string ndds_transport_class_id_vals[] = { + { NDDS_TRANSPORT_CLASSID_ANY, "ANY" }, + { NDDS_TRANSPORT_CLASSID_UDPv4, "UDPv4" }, + { NDDS_TRANSPORT_CLASSID_SHMEM, "SHMEM" }, + { NDDS_TRANSPORT_CLASSID_INTRA, "INTRA" }, + { NDDS_TRANSPORT_CLASSID_UDPv6, "UDPv6" }, + { NDDS_TRANSPORT_CLASSID_DTLS, "DTLS" }, + { NDDS_TRANSPORT_CLASSID_WAN, "WAN" }, + { NDDS_TRANSPORT_CLASSID_TCPV4_LAN, "TCPv4_LAN" }, + { NDDS_TRANSPORT_CLASSID_TCPV4_WAN, "TCPv4_WAN" }, + { NDDS_TRANSPORT_CLASSID_TLSV4_LAN, "TLSv4_LAN" }, + { NDDS_TRANSPORT_CLASSID_TLSV4_WAN, "TLSv4_WAN" }, + { NDDS_TRANSPORT_CLASSID_PCIE, "PCIE" }, + { NDDS_TRANSPORT_CLASSID_ITP, "ITP" }, + { 0, NULL } +}; + /* Flag Decoding defintions ***********************************************/ struct Flag_definition { const char letter; @@ -910,6 +1007,63 @@ static const struct Flag_definition INFO_REPLY_FLAGS[] = { }; +/* Vendor specific: RTI */ +static const struct Flag_definition APP_ACK_FLAGS[] = { + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 7 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 6 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 5 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 4 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 3 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 2 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 1 */ + { 'E', "Endianness bit" } /* Bit 0 */ +}; +/* Vendor specific: RTI */ +static const struct Flag_definition APP_ACK_CONF_FLAGS[] = { + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 7 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 6 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 5 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 4 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 3 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 2 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 1 */ + { 'E', "Endianness bit" } /* Bit 0 */ +}; +/* Vendor specific: RTI */ +static const struct Flag_definition HEARTBEAT_VIRTUAL_FLAGS[] = { + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 7 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 6 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 5 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 4 */ + { 'N', "No virtual GUIDs flag" }, /* Bit 3 */ + { 'W', "Multiple writers flag" }, /* Bit 2 */ + { 'V', "Multiple virtual GUIDs flag" }, /* Bit 1 */ + { 'E', "Endianness bit" } /* Bit 0 */ +}; +/* Vendor specific: RTI */ +static const struct Flag_definition DATA_FRAG_FLAGS[] = { + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 7 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 6 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 5 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 4 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 3 */ + { 'H', "Hash key flag" }, /* Bit 2 */ + { 'Q', "Inline QoS" }, /* Bit 1 */ + { 'E', "Endianness bit" } /* Bit 0 */ +}; +/* Vendor specific: RTI */ +static const struct Flag_definition NACK_FLAGS[] = { + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 7 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 6 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 5 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 4 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 3 */ + { RESERVEDFLAG_CHAR, RESERVEDFLAG_STRING }, /* Bit 2 */ + { 'F', "Final flag" }, /* Bit 1 */ + { 'E', "Endianness bit" } /* Bit 0 */ +}; + + /***************************************************************************/ /* Inline macros */ @@ -1452,6 +1606,31 @@ guint64 rtps_util_add_seq_number(proto_tree *tree, /* ------------------------------------------------------------------------- */ +/* Vendor specific: RTI + * Insert in the protocol tree the next 8 bytes interpreted as TransportInfo + */ +void rtps_util_add_transport_info(proto_tree *tree, + tvbuff_t * tvb, + gint offset, + int little_endian, + int transport_index) + { + gint32 classId = NEXT_guint32(tvb, offset, little_endian); + + if (tree) { + proto_tree *xport_info_tree; + + xport_info_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8, ett_rtps_transport_info, NULL, + "transportInfo %d: %s", transport_index,val_to_str(classId, ndds_transport_class_id_vals, "unknown")); + + proto_tree_add_item(xport_info_tree, hf_rtps_transportInfo_classId, tvb, + offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + proto_tree_add_item(xport_info_tree, hf_rtps_transportInfo_messageSizeMax, tvb, + offset+4, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + } +} + +/* ------------------------------------------------------------------------- */ /* Insert in the protocol tree the next 8 bytes interpreted as NtpTime */ void rtps_util_add_ntp_time(proto_tree *tree, @@ -1466,6 +1645,46 @@ void rtps_util_add_ntp_time(proto_tree *tree, } /* ------------------------------------------------------------------------- */ +/* Insert in the protocol tree the next 8 bytes interpreted as NtpTime +*/ +void rtps_util_add_ntp_time_sec_and_fraction(proto_tree *tree, + tvbuff_t * tvb, + gint offset, + gboolean little_endian, + int hf_time _U_) { + + guint8 tempBuffer[MAX_NTP_TIME_SIZE]; + gdouble absolute; + gint32 sec; + guint32 frac; + + if (tree) { + proto_tree *time_tree; + + sec = NEXT_guint32(tvb, offset, little_endian); + frac = NEXT_guint32(tvb, offset+4, little_endian); + + if ((sec == 0x7fffffff) && (frac == 0xffffffff)) { + g_strlcpy(tempBuffer, "INFINITE", MAX_NTP_TIME_SIZE); + } else if ((sec == 0) && (frac == 0)) { + g_strlcpy(tempBuffer, "0 sec", MAX_NTP_TIME_SIZE); + } else { + absolute = (gdouble)sec + (gdouble)frac / ((gdouble)(0x80000000) * 2.0); + g_snprintf(tempBuffer, MAX_NTP_TIME_SIZE, + "%f sec (%ds + 0x%08x)", absolute, sec, frac); + } + + time_tree = proto_tree_add_subtree_format(tree, tvb, offset, 8, + ett_rtps_ntp_time, NULL, "%s: %s", "lease_duration", tempBuffer); + + proto_tree_add_item(time_tree, hf_rtps_param_ntpt_sec, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + proto_tree_add_item(time_tree, hf_rtps_param_ntpt_fraction, tvb, offset+4, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + } +} + +/* ------------------------------------------------------------------------- */ /* Insert in the protocol tree the next data interpreted as a String * Returns the new offset (after reading the string) */ @@ -1519,7 +1738,7 @@ void rtps_util_add_durability_service_qos(proto_tree *tree, subtree = proto_tree_add_subtree(tree, tvb, offset, 28, ett_rtps_durability_service, NULL, "PID_DURABILITY_SERVICE"); - rtps_util_add_ntp_time(subtree, tvb, offset, little_endian, hf_rtps_durability_service_cleanup_delay); + rtps_util_add_ntp_time_sec_and_fraction(subtree, tvb, offset, little_endian, hf_rtps_durability_service_cleanup_delay); proto_tree_add_item(subtree, hf_rtps_durability_service_history_kind, tvb, offset+8, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_rtps_durability_service_history_depth, tvb, offset+12, 4, @@ -1544,7 +1763,46 @@ void rtps_util_add_liveliness_qos(proto_tree *tree, tvbuff_t * tvb, gint offset, proto_tree_add_item(subtree, hf_rtps_liveliness_kind, tvb, offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); - rtps_util_add_ntp_time(subtree, tvb, offset+4, little_endian, hf_rtps_liveliness_lease_duration); + rtps_util_add_ntp_time_sec_and_fraction(subtree, tvb, offset+4, little_endian, hf_rtps_liveliness_lease_duration); +} + +/* ------------------------------------------------------------------------- */ +/* Insert in the protocol tree the next bytes interpreted as Liveliness + * QoS Policy structure. + */ +void rtps_util_add_product_version(proto_tree *tree, tvbuff_t * tvb, gint offset) { + + proto_tree *subtree; + guint8 major, minor, release, revision; + + major = tvb_get_guint8(tvb, offset); + minor = tvb_get_guint8(tvb, offset+1); + release = tvb_get_guint8(tvb, offset+2); + revision = tvb_get_guint8(tvb, offset+3); + + if (major < 5 && revision == 0) { + subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_rtps_product_version, NULL, + "Product version: %d.%d%c", major, minor, release); + } else if (major < 5 && revision > 0) { + subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_rtps_product_version, NULL, + "Product version: %d.%d%c rev%d", major, minor, release, revision); + } else { + subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4, ett_rtps_product_version, NULL, + "Product version: %d.%d.%d.%d", major, minor, release, revision); + } + proto_tree_add_item(subtree, hf_rtps_param_product_version_major, + tvb, offset, 1, ENC_NA); + proto_tree_add_item(subtree, hf_rtps_param_product_version_minor, + tvb, offset+1, 1, ENC_NA); + if (major < 5) { /* If major revision is smaller than 5, release interpreted as char */ + proto_tree_add_item(subtree, hf_rtps_param_product_version_release_as_char, + tvb, offset+2, 1, ENC_ASCII|ENC_NA); + } else { + proto_tree_add_item(subtree, hf_rtps_param_product_version_release, + tvb, offset+2, 1, ENC_NA); + } + proto_tree_add_item(subtree, hf_rtps_param_product_version_revision, + tvb, offset+3, 1, ENC_NA); } /* ------------------------------------------------------------------------- */ @@ -1958,6 +2216,24 @@ static gint rtps_util_add_typecode(proto_tree *tree, tvbuff_t * tvb, gint offset if (tk_id == RTI_CDR_TK_ENUM) { typecode_name = "enum"; + } else if (tk_id == RTI_CDR_TK_VALUE_PARAM) { + /* guint16 type_modifier; */ + /* guint32 baseTypeCodeKind; */ + guint32 baseTypeCodeLength; + + /* Need to read the type modifier and the base type code */ + typecode_name = "<sparse type>"; + SHORT_ALIGN(offset); + /* type_modifier = */ NEXT_guint16(tvb, offset, little_endian); + offset += 2; + + LONG_ALIGN(offset); + /* baseTypeCodeKind = */ NEXT_guint32(tvb, offset, little_endian); + offset += 4; + + baseTypeCodeLength = NEXT_guint32(tvb, offset, little_endian); + offset += 4; + offset += baseTypeCodeLength; } else { typecode_name = "struct"; } @@ -2136,11 +2412,13 @@ static gint rtps_util_add_typecode(proto_tree *tree, tvbuff_t * tvb, gint offset * Foreach member: (it's just like a struct) * */ + case RTI_CDR_TK_VALUE_PARAM: case RTI_CDR_TK_VALUE: { /* Not fully dissected for now */ /* Pad-align */ guint32 value_name_len; gint8 * value_name; + const char * type_id_name = "valuetype"; LONG_ALIGN(offset); /* Get structure name length */ @@ -2151,7 +2429,10 @@ static gint rtps_util_add_typecode(proto_tree *tree, tvbuff_t * tvb, gint offset value_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, value_name_len, ENC_ASCII); offset += value_name_len; - g_snprintf(type_name, 40, "valuetype %s", value_name); + if (tk_id == RTI_CDR_TK_VALUE_PARAM) { + type_id_name = "valueparam"; + } + g_snprintf(type_name, 40, "%s '%s'", type_id_name, value_name); break; } } /* switch(tk_id) */ @@ -2482,6 +2763,398 @@ static void rtps_util_decode_flags_16bit(proto_tree * tree, tvbuff_t *tvb, gint break; \ } +static gboolean dissect_parameter_sequence_rti(proto_tree *rtps_parameter_tree, packet_info *pinfo, tvbuff_t *tvb, + proto_item* parameter_item, proto_item* param_len_item, gint offset, + gboolean little_endian, int param_length, + guint16 parameter) { + + switch(parameter) { + + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_DEFAULT_MULTICAST_LOCATOR | 0x0018 | + * +---------------+---------------+---------------+---------------+ + * | long kind | + * +---------------+---------------+---------------+---------------+ + * | long port | + * +---------------+---------------+---------------+---------------+ + * | ipv6addr[0] | ipv6addr[1] | ipv6addr[2] | ipv6addr[3] | + * +---------------+---------------+---------------+---------------+ + * | ipv6addr[4] | ipv6addr[5] | ipv6addr[6] | ipv6addr[7] | + * +---------------+---------------+---------------+---------------+ + * | ipv6addr[8] | ipv6addr[9] | ipv6addr[10] | ipv6addr[11] | + * +---------------+---------------+---------------+---------------+ + * | ipv6addr[12] | ipv6addr[13] | ipv6addr[14] | ipv6addr[15] | + * +---------------+---------------+---------------+---------------+ + */ + case PID_DEFAULT_MULTICAST_LOCATOR: { + ENSURE_LENGTH(24); + rtps_util_add_locator_t(rtps_parameter_tree, pinfo, tvb, offset, little_endian, "locator"); + + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_TRANSPORT_INFO_LIST | length | + * +---------------+---------------+---------------+---------------+ + * | unsigned long Seq.Length | + * +---------------+---------------+---------------+---------------+ + * | ... | + * | TransportInfo 1 | + * | ... | + * +---------------+---------------+---------------+---------------+ + * | ... | + * | TransportInfo 2 | + * | ... | + * +---------------+---------------+---------------+---------------+ + * | ... | + * | TransportInfo n | + * | ... | + * +---------------+---------------+---------------+---------------+ + * + * IDL: + * struct TRANSPORT_INFO { + * long classid; + * long messageSizeMax; + * }; + * + * struct TRANSPORT_INFO_LIST { + * Sequence<TRANSPORT_INFO> TransportInfoList; + * }; + * + */ + + case PID_TRANSPORT_INFO_LIST: { + + ENSURE_LENGTH(4); + { + int i; + guint32 temp_offset; + guint32 seq_size = NEXT_guint32(tvb, offset, little_endian); + if (seq_size > 0) { + temp_offset = offset+4; /* move to first transportInfo */ + i = 1; + while(seq_size-- > 0) { + rtps_util_add_transport_info( + rtps_parameter_tree, + tvb, + temp_offset, + little_endian, + i); + temp_offset += 8; + ++i; + } + } + } + break; + } + + + case PID_DIRECT_COMMUNICATION: { + proto_tree_add_item(rtps_parameter_tree, hf_rtps_direct_communication, tvb, offset, 1, ENC_NA ); + break; + } + + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_TYPE_CONSISTENCY_KIND | length | + * +---------------+---------------+---------------+---------------+ + * | unsigned short value | = = u n u s e d = = = = = = | + * +---------------+---------------+---------------+---------------+ + */ + case PID_TYPE_CONSISTENCY: { + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_type_consistency_kind, tvb, offset, 2, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + + + /* ================================================================== + * Here are all the deprecated items. + */ + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_PRODUCT_VERSION | length | + * +---------------+---------------+---------------+---------------+ + * | uint8 major | uint8 minor | uint8 release |uint8 revision | + * +---------------+---------------+---------------+---------------+ + */ + case PID_PRODUCT_VERSION: { + ENSURE_LENGTH(4); + rtps_util_add_product_version(rtps_parameter_tree, tvb, offset); + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_PLUGIN_PROMISCUITY_KIND | length | + * +---------------+---------------+---------------+---------------+ + * | short value | | + * +---------------+---------------+---------------+---------------+ + */ + case PID_PLUGIN_PROMISCUITY_KIND: { + ENSURE_LENGTH(4); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_plugin_promiscuity_kind, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_ENTITY_VIRTUAL_GUID | length | + * +---------------+---------------+---------------+---------------+ + * | | + * +- -+ + * | octet[12] guidPrefix | + * +- -+ + * | | + * +---------------+---------------+---------------+---------------+ + * | octet[4] entityId | + * +---------------+---------------+---------------+---------------+ + */ + + case PID_ENTITY_VIRTUAL_GUID: { + ENSURE_LENGTH(16); + rtps_util_add_guid_prefix_v2(rtps_parameter_tree, tvb, offset, + hf_rtps_sm_guid_prefix, hf_rtps_sm_host_id, hf_rtps_sm_app_id, + hf_rtps_sm_counter, "virtualGUIDPrefix"); + rtps_util_add_entity_id(rtps_parameter_tree, tvb, offset+12, + hf_rtps_sm_entity_id, hf_rtps_sm_entity_id_key, hf_rtps_sm_entity_id_kind, + ett_rtps_entity, "virtualGUIDSuffix", NULL); + break; + } + + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_SERVICE_KIND | length | + * +---------------+---------------+---------------+---------------+ + * | long value | + * +---------------+---------------+---------------+---------------+ + */ + case PID_SERVICE_KIND: { + ENSURE_LENGTH(4); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_service_kind, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + + + case PID_ROLE_NAME: { + rtps_util_add_string(rtps_parameter_tree, tvb, offset, hf_rtps_param_entity_name, little_endian); + break; + } + + + case PID_ACK_KIND: { + ENSURE_LENGTH(4); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_acknowledgment_kind, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_PEER_HOST_EPOCH | length | + * +---------------+---------------+---------------+---------------+ + * | unsigned long epoch | + * +---------------+---------------+---------------+---------------+ + */ + case PID_PEER_HOST_EPOCH: { + ENSURE_LENGTH(4); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_peer_host_epoch, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_DOMAIN_ID | length | + * +---------------+---------------+---------------+---------------+ + * | long domain_id | + * +---------------+---------------+---------------+---------------+ + */ + case PID_DOMAIN_ID: { + ENSURE_LENGTH(4); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_domain_id, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + + case PID_EXTENDED: { + ENSURE_LENGTH(8); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_extended_parameter, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_extended_pid_length, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + break; + } + + case PID_TYPE_OBJECT: { + /* Typeobject dissection may be added in the future */ + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_TYPECODE_RTPS2 | length | + * +---------------+---------------+---------------+---------------+ + * | | + * + Type code description + + * | | + * +---------------+---------------+---------------+---------------+ + */ + case PID_TYPECODE: + case PID_TYPECODE_RTPS2: { + rtps_util_add_typecode(rtps_parameter_tree, + tvb, + offset, + little_endian, + 0, /* indent level */ + 0, /* isPointer */ + -1, /* bitfield */ + 0, /* isKey */ + offset, + NULL, /* name */ + -1, /* not a seq field */ + NULL, /* not an array */ + 0); /* ndds 4.0 hack: init to false */ + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_DISABLE_POSITIVE_ACKS | length | + * +---------------+---------------+---------------+---------------+ + * | boolean value | = = = = = = = = u n u s e d = = = = = = = = | + * +---------------+---------------+---------------+---------------+ + */ + case PID_DISABLE_POSITIVE_ACKS: { + ENSURE_LENGTH(1); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_disable_positive_ack, tvb, offset, 1, ENC_NA ); + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_EXPECTS_VIRTUAL_HB | length | + * +---------------+---------------+---------------+---------------+ + * | boolean value | = = = = = = = = u n u s e d = = = = = = = = | + * +---------------+---------------+---------------+---------------+ + */ + case PID_EXPECTS_VIRTUAL_HB: { + ENSURE_LENGTH(1); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_expects_virtual_heartbeat, tvb, offset, 1, ENC_NA ); + break; + } + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_LOCATOR_FILTER_LIST | length | + * +---------------+---------------+---------------+---------------+ + * | unsigned long number_of_channels | + * +---------------+---------------+---------------+---------------+ + * | | + * ~ String filter_name ~ + * | | + * +---------------+---------------+---------------+---------------+ + * | | + * ~ LocatorList ~ <----------+ + * | | Repeat | + * +---------------+---------------+---------------+---------------+ For each| + * | | Channel | + * ~ String filter_expression ~ | + * | | | + * +---------------+---------------+---------------+---------------+ <----------+ + */ + case PID_LOCATOR_FILTER_LIST: { + guint32 number_of_channels, ch; + proto_tree *channel_tree; + proto_item *ti_channel; + char temp_buff[20]; + gint old_offset; + guint32 off = offset; + + ENSURE_LENGTH(4); + number_of_channels = NEXT_guint32(tvb, off, little_endian); + proto_item_append_text( parameter_item, " (%d channels)", number_of_channels ); + proto_tree_add_int(rtps_parameter_tree, hf_rtps_locator_filter_list_num_channels, tvb, off, 4, number_of_channels ); + off += 4; + + if (number_of_channels == 0) { + /* Do not dissect the rest */ + break; + } + + /* filter name */ + off = rtps_util_add_string(rtps_parameter_tree, tvb, off, hf_rtps_locator_filter_list_filter_name, little_endian); + + /* Foreach channel... */ + for (ch = 0; ch < number_of_channels; ++ch) { + g_snprintf(temp_buff, 20, "Channel[%u]", ch); + old_offset = off; + channel_tree = proto_tree_add_subtree_format(rtps_parameter_tree, tvb, off, 0, ett_rtps_locator_filter_channel, &ti_channel, "Channel[%u]", ch); + + off = rtps_util_add_locator_list(channel_tree, pinfo, tvb, off, temp_buff, little_endian); + /* Filter expression */ + off = rtps_util_add_string(rtps_parameter_tree, tvb, off, hf_rtps_locator_filter_list_filter_exp, little_endian); + + /* Now we know the length of the channel data, set the length */ + proto_item_set_len(ti_channel, (off - old_offset)); + } /* End of for each channel */ + break; + }/* End of case PID_LOCATOR_FILTER_LIST */ + + default: { + return FALSE; + } + }/* End of switch for parameters for vendor RTI */ + return TRUE; +} + +static gboolean dissect_parameter_sequence_toc(proto_tree *rtps_parameter_tree, packet_info *pinfo _U_, + tvbuff_t *tvb, proto_item *parameter_item _U_, proto_item *param_len_item _U_, gint offset, + gboolean little_endian, int param_length _U_, + guint16 parameter) { + + switch(parameter) { + + /* 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PID_TYPECODE_RTPS2 | length | + * +---------------+---------------+---------------+---------------+ + * | | + * + Type code description + + * | | + * +---------------+---------------+---------------+---------------+ + */ + case PID_TYPECODE_RTPS2: { + rtps_util_add_typecode(rtps_parameter_tree, + tvb, + offset, + little_endian, + 0, /* indent level */ + 0, /* isPointer */ + -1, /* bitfield */ + 0, /* isKey */ + offset, + NULL, /* name */ + 0, /* not a seq field */ + NULL, /* not an array */ + 0); /* ndds 4.0 hack: init to false */ + break; + } + + default: + return FALSE; + } + return TRUE; +} + static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, packet_info *pinfo, tvbuff_t *tvb, proto_item* parameter_item, proto_item* param_len_item, gint offset, gboolean little_endian, int size, int param_length, @@ -2501,7 +3174,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p */ case PID_PARTICIPANT_LEASE_DURATION: ENSURE_LENGTH(8); - rtps_util_add_ntp_time(rtps_parameter_tree, tvb, offset, little_endian, + rtps_util_add_ntp_time_sec_and_fraction(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_participant_lease_duration); break; @@ -2517,7 +3190,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p */ case PID_TIME_BASED_FILTER: ENSURE_LENGTH(8); - rtps_util_add_ntp_time(rtps_parameter_tree, tvb, offset, little_endian, + rtps_util_add_ntp_time_sec_and_fraction(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_time_based_filter_minimum_separation); break; @@ -2627,7 +3300,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p */ case PID_VENDOR_ID: ENSURE_LENGTH(2); - rtps_util_add_vendor_id(NULL, tvb, offset); + rtps_util_add_vendor_id(rtps_parameter_tree, tvb, offset); break; /* 0...2...........7...............15.............23...............31 @@ -2753,7 +3426,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p case PID_DEADLINE_OFFERED: /* Deprecated */ case PID_DEADLINE: ENSURE_LENGTH(8); - rtps_util_add_ntp_time(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_deadline_period); + rtps_util_add_ntp_time_sec_and_fraction(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_deadline_period); break; /* 0...2...........7...............15.............23...............31 @@ -2782,7 +3455,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p case PID_LATENCY_BUDGET_OFFERED: case PID_LATENCY_BUDGET: ENSURE_LENGTH(8); - rtps_util_add_ntp_time(rtps_parameter_tree, tvb, offset, + rtps_util_add_ntp_time_sec_and_fraction(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_latency_budget_duration); break; @@ -2818,7 +3491,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p */ case PID_LIFESPAN: ENSURE_LENGTH(8); - rtps_util_add_ntp_time(rtps_parameter_tree, tvb, offset, little_endian, + rtps_util_add_ntp_time_sec_and_fraction(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_lifespan_duration); break; @@ -3357,7 +4030,7 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p case PID_PERSISTENCE: ENSURE_LENGTH(8); - rtps_util_add_ntp_time(rtps_parameter_tree, tvb, offset, little_endian, + rtps_util_add_ntp_time_sec_and_fraction(rtps_parameter_tree, tvb, offset, little_endian, hf_rtps_persistence); break; @@ -3422,7 +4095,8 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p case PID_PAD: if (param_length > 0) { - proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, "parameterData"); + proto_tree_add_item(rtps_parameter_tree, hf_rtps_parameter_data, tvb, + offset, param_length, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); } break; @@ -3434,9 +4108,9 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p } static gboolean dissect_parameter_sequence_v2(proto_tree *rtps_parameter_tree, packet_info *pinfo, tvbuff_t *tvb, - proto_item* parameter_item, proto_item* param_len_item, gint offset, - gboolean little_endian, int param_length, - guint16 parameter, guint32 *pStatusInfo, guint16 vendor_id) { + proto_item *parameter_item _U_, proto_item* param_len_item, + gint offset, gboolean little_endian, int param_length, + guint16 parameter, guint32 *pStatusInfo, guint16 vendor_id _U_) { proto_item *ti; switch(parameter) { @@ -3449,10 +4123,10 @@ static gboolean dissect_parameter_sequence_v2(proto_tree *rtps_parameter_tree, p */ case PID_STATUS_INFO: ENSURE_LENGTH(4); - proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_status_info, tvb, offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); - + /* PID_STATUS_INFO is always coded in network byte order (big endian) */ + proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_status_info, tvb, offset, 4, ENC_BIG_ENDIAN); if (pStatusInfo != NULL) { - *pStatusInfo = NEXT_guint32(tvb, offset, little_endian); + *pStatusInfo = NEXT_guint32(tvb, offset, ENC_BIG_ENDIAN); } break; @@ -3670,211 +4344,8 @@ static gboolean dissect_parameter_sequence_v2(proto_tree *rtps_parameter_tree, p break; default: - /* The following PIDS are vendor-specific */ - if (vendor_id == RTPS_VENDOR_RTI_DDS) { - switch(parameter) { - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_PRODUCT_VERSION | length | - * +---------------+---------------+---------------+---------------+ - * | uint8 major | uint8 minor | N O T U S E D | - * +---------------+---------------+---------------+---------------+ - */ - case PID_PRODUCT_VERSION: { - guint8 major, minor, release, revision; - - ENSURE_LENGTH(4); - major = tvb_get_guint8(tvb, offset); - minor = tvb_get_guint8(tvb, offset+1); - release = tvb_get_guint8(tvb, offset+2); - revision = tvb_get_guint8(tvb, offset+3); - proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, - "productVersion: %d.%d%c rev%d", - major, minor, release, revision); - break; - } - - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_PLUGIN_PROMISCUITY_KIND | length | - * +---------------+---------------+---------------+---------------+ - * | short value | | - * +---------------+---------------+---------------+---------------+ - */ - case PID_PLUGIN_PROMISCUITY_KIND: - ENSURE_LENGTH(4); - proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_plugin_promiscuity_kind, tvb, offset, 4, - little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); - break; - - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_ENTITY_VIRTUAL_GUID | length | - * +---------------+---------------+---------------+---------------+ - * | | - * +- -+ - * | octet[12] guidPrefix | - * +- -+ - * | | - * +---------------+---------------+---------------+---------------+ - * | octet[4] entityId | - * +---------------+---------------+---------------+---------------+ - */ - case PID_ENTITY_VIRTUAL_GUID: - ENSURE_LENGTH(16); - rtps_util_add_guid_prefix_v2(rtps_parameter_tree, tvb, offset, - hf_rtps_sm_guid_prefix, hf_rtps_sm_host_id, hf_rtps_sm_app_id, - hf_rtps_sm_counter, "virtualGUIDPrefix"); - rtps_util_add_entity_id(rtps_parameter_tree, tvb, offset+12, - hf_rtps_sm_entity_id, hf_rtps_sm_entity_id_key, hf_rtps_sm_entity_id_kind, - ett_rtps_entity, "virtualGUIDSuffix", NULL); - break; - - - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_SERVICE_KIND | length | - * +---------------+---------------+---------------+---------------+ - * | long value | - * +---------------+---------------+---------------+---------------+ - */ - case PID_SERVICE_KIND: - ENSURE_LENGTH(4); - proto_tree_add_item(rtps_parameter_tree, hf_rtps_param_service_kind, tvb, offset, 4, - little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); - break; - - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_TYPECODE_RTPS2 | length | - * +---------------+---------------+---------------+---------------+ - * | | - * + Type code description + - * | | - * +---------------+---------------+---------------+---------------+ - */ - case PID_TYPECODE_RTPS2: - rtps_util_add_typecode(rtps_parameter_tree, - tvb, - offset, - little_endian, - 0, /* indent level */ - 0, /* isPointer */ - -1, /* bitfield */ - 0, /* isKey */ - offset, - NULL, /* name */ - 0, /* not a seq field */ - NULL, /* not an array */ - 0); /* ndds 4.0 hack: init to false */ - break; - - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_DISABLE_POSITIVE_ACKS | length | - * +---------------+---------------+---------------+---------------+ - * | boolean value | = = = = = = = = u n u s e d = = = = = = = = | - * +---------------+---------------+---------------+---------------+ - */ - case PID_DISABLE_POSITIVE_ACKS: - ENSURE_LENGTH(1); - proto_tree_add_item(rtps_parameter_tree, hf_rtps_disable_positive_ack, tvb, offset, 1, ENC_NA ); - break; - - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_LOCATOR_FILTER_LIST | length | - * +---------------+---------------+---------------+---------------+ - * | unsigned long number_of_channels | - * +---------------+---------------+---------------+---------------+ - * | | - * ~ String filter_name ~ - * | | - * +---------------+---------------+---------------+---------------+ - * | | - * ~ LocatorList ~ <----------+ - * | | Repeat | - * +---------------+---------------+---------------+---------------+ For each| - * | | Channel | - * ~ String filter_expression ~ | - * | | | - * +---------------+---------------+---------------+---------------+ <----------+ - */ - case PID_LOCATOR_FILTER_LIST: { - guint32 number_of_channels, ch; - proto_tree *channel_tree; - proto_item *ti_channel; - char temp_buff[20]; - gint old_offset; - guint32 off = offset; - - ENSURE_LENGTH(4); - number_of_channels = NEXT_guint32(tvb, off, little_endian); - proto_item_append_text( parameter_item, " (%d channels)", number_of_channels ); - proto_tree_add_int(rtps_parameter_tree, hf_rtps_locator_filter_list_num_channels, tvb, off, 4, number_of_channels ); - off += 4; - - if (number_of_channels == 0) { - /* Do not dissect the rest */ - break; - } - - /* filter name */ - off = rtps_util_add_string(rtps_parameter_tree, tvb, off, hf_rtps_locator_filter_list_filter_name, little_endian); - - /* Foreach channel... */ - for (ch = 0; ch < number_of_channels; ++ch) { - g_snprintf(temp_buff, 20, "Channel[%u]", ch); - old_offset = off; - channel_tree = proto_tree_add_subtree_format(rtps_parameter_tree, tvb, off, 0, - ett_rtps_locator_filter_channel, &ti_channel, "Channel[%u]", ch); - - off = rtps_util_add_locator_list(channel_tree, pinfo, tvb, off, temp_buff, little_endian); - /* Filter expression */ - off = rtps_util_add_string(rtps_parameter_tree, tvb, off, hf_rtps_locator_filter_list_filter_exp, little_endian); - - /* Now we know the length of the channel data, set the length */ - proto_item_set_len(ti_channel, (off - old_offset)); - } /* End of for each channel */ - break; - } /* End of case PID_LOCATOR_FILTER_LIST */ - - } /* End of switch for parameters for vendor RTI */ - } /* End of branch vendor RTI */ - else if (vendor_id == RTPS_VENDOR_TOC) { - switch(parameter) { - /* 0...2...........7...............15.............23...............31 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PID_TYPECODE_RTPS2 | length | - * +---------------+---------------+---------------+---------------+ - * | | - * + Type code description + - * | | - * +---------------+---------------+---------------+---------------+ - */ - case PID_TYPECODE_RTPS2: - rtps_util_add_typecode(rtps_parameter_tree, - tvb, - offset, - little_endian, - 0, /* indent level */ - 0, /* isPointer */ - -1, /* bitfield */ - 0, /* isKey */ - offset, - NULL, /* name */ - 0, /* not a seq field */ - NULL, /* not an array */ - 0); /* ndds 4.0 hack: init to false */ - break; - default: - break; - } /* End of switch for parameters for vendor TOC */ - } else { /* End of branch vendor TOC */ return FALSE; - } - break; - } + } /* End of switch(parameter) */ return TRUE; } @@ -3883,10 +4354,12 @@ static gboolean dissect_parameter_sequence_v2(proto_tree *rtps_parameter_tree, p static gint dissect_parameter_sequence(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, gboolean little_endian, int size, const char * label, guint16 version, guint32 *pStatusInfo, guint16 vendor_id) { + proto_item *ti, *param_item, *param_len_item = NULL; proto_tree *rtps_parameter_sequence_tree, *rtps_parameter_tree; guint16 parameter, param_length; gint original_offset = offset; + gboolean dissect_return_value = FALSE; rtps_parameter_sequence_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_rtps_parameter_sequence, &ti, "%s:", label); @@ -3938,19 +4411,39 @@ static gint dissect_parameter_sequence(proto_tree *tree, packet_info *pinfo, tvb /* Sets the end of this item (now we know it!) */ proto_item_set_len(param_item, param_length+4); - if (!dissect_parameter_sequence_v1(rtps_parameter_tree, pinfo, tvb, param_item, param_len_item, - offset, little_endian, size, param_length, parameter, version)) { - if ((version < 0x0200) || - !dissect_parameter_sequence_v2(rtps_parameter_tree, pinfo, tvb, param_item, param_len_item, - offset, little_endian, param_length, parameter, - pStatusInfo, vendor_id)) { - if (param_length > 0) { - proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length, - "parameterData"); - } - } + /* This way, we can include vendor specific dissections without modifying the main ones */ + switch (vendor_id) { + case RTPS_VENDOR_RTI_DDS: { + dissect_return_value = dissect_parameter_sequence_rti(rtps_parameter_tree, pinfo, tvb, + param_item, param_len_item, offset, + little_endian, param_length, parameter); + break; + } + case RTPS_VENDOR_TOC: { + dissect_return_value = dissect_parameter_sequence_toc(rtps_parameter_tree, pinfo, tvb, + param_item, param_len_item, offset, + little_endian, param_length, parameter); + break; + } + default: { + + } } + if (!dissect_return_value) { + if (!dissect_parameter_sequence_v1(rtps_parameter_tree, pinfo, tvb, param_item, param_len_item, + offset, little_endian, size, param_length, parameter, version)) { + if ((version < 0x0200) || + !dissect_parameter_sequence_v2(rtps_parameter_tree, pinfo, tvb, param_item, param_len_item, + offset, little_endian, param_length, parameter, + pStatusInfo, vendor_id)) { + if (param_length > 0) { + proto_tree_add_item(rtps_parameter_tree, hf_rtps_parameter_data, tvb, + offset, param_length, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + } + } + } + } offset += param_length; } return offset; @@ -3971,13 +4464,147 @@ gboolean rtps_is_ping(tvbuff_t *tvb, packet_info *pinfo, gint offset) } /* *********************************************************************** */ +/* * A P P_ A C K_ C O N F * */ +/* *********************************************************************** */ +static void dissect_APP_ACK_CONF(tvbuff_t *tvb, + packet_info *pinfo _U_, + gint offset, + guint8 flags, + gboolean little_endian, + int octets_to_next_header, + proto_tree *tree, + proto_item *item) + { + /* + * 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | APP_ACK_CONF |X|X|X|X|X|X|X|E| octetsToNextHeader | + * +---------------+---------------+---------------+---------------+ + * | EntityId readerEntityId | + * +---------------+---------------+---------------+---------------+ + * | EntityId writerEntityId | + * +---------------+---------------+---------------+---------------+ + * + unsigned long virtualWriterCount + + * +---------------+---------------+---------------+---------------+ + * | GuidPrefix virtualWriterGuidPrefix | + * +---------------+---------------+---------------+---------------+ + * EntityId virtualWriterObjectId + * + * (after last interval) unsigned long virtualWriterEpoch + * + */ + gint original_offset; /* Offset to the readerEntityId */ + guint32 virtual_writer_count; + proto_item *octet_item; + rtps_util_decode_flags(tree, tvb, offset + 1, flags, APP_ACK_CONF_FLAGS); + + octet_item = proto_tree_add_item(tree, hf_rtps_sm_octets_to_next_header, tvb, + offset + 2, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + original_offset = offset; + + if (octets_to_next_header < 20) { + expert_add_info_format(pinfo, octet_item, &ei_rtps_sm_octets_to_next_header_error, "(Error: should be >= %u)", 20); + return; + } + + /* readerEntityId */ + rtps_util_add_entity_id(tree, + tvb, + offset, + hf_rtps_sm_rdentity_id, + hf_rtps_sm_rdentity_id_key, + hf_rtps_sm_rdentity_id_kind, + ett_rtps_rdentity, + "readerEntityId", + NULL); + offset += 4; + + /* writerEntityId */ + rtps_util_add_entity_id(tree, + tvb, + offset, + hf_rtps_sm_wrentity_id, + hf_rtps_sm_wrentity_id_key, + hf_rtps_sm_wrentity_id_kind, + ett_rtps_wrentity, + "writerEntityId", + NULL); + offset += 4; + + + /* virtualWriterCount */ + virtual_writer_count = NEXT_guint32(tvb, offset, little_endian); + proto_tree_add_item(tree, hf_rtps_param_app_ack_conf_virtual_writer_count, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + + { + /* Deserialize Virtual Writers */ + proto_tree * sil_tree_writer_list = NULL; + proto_tree * sil_tree_writer = NULL; + + guint32 current_writer_index = 0; + + /** Writer list **/ + + sil_tree_writer_list = proto_tree_add_subtree_format(tree, tvb, offset, -1, + ett_rtps_app_ack_virtual_writer_list, NULL, "Virtual Writer List"); + + current_writer_index = 0; + + while (current_writer_index < virtual_writer_count) { + sil_tree_writer = proto_tree_add_subtree_format(sil_tree_writer_list, tvb, offset, -1, + ett_rtps_app_ack_virtual_writer, NULL, "virtualWriter[%d]", current_writer_index); + + /* Virtual Writer Guid */ + rtps_util_add_guid_prefix_v2(sil_tree_writer, tvb, offset, + hf_rtps_sm_guid_prefix, hf_rtps_sm_host_id, hf_rtps_sm_app_id, + hf_rtps_sm_counter, "virtualGUIDPrefix"); + + rtps_util_add_entity_id(sil_tree_writer, tvb, offset+12, + hf_rtps_sm_entity_id, hf_rtps_sm_entity_id_key, hf_rtps_sm_entity_id_kind, + ett_rtps_entity, "virtualGUIDSuffix", NULL); + + offset += 16; + + /* Counter */ + proto_tree_add_item(tree, hf_rtps_param_app_ack_conf_count, tvb, offset, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + + current_writer_index++; + + } /* virtual_writer_count */ + } + + + if (offset < original_offset + octets_to_next_header) + { + /* In this case there must be something wrong in the bitmap: there + * are some extra bytes that we don't know how to decode + */ + expert_add_info_format(pinfo, item, &ei_rtps_extra_bytes, "Don't know how to decode those extra bytes: %d", octets_to_next_header - offset); + } + else if (offset > original_offset + octets_to_next_header) + { + /* Decoding the bitmap went over the end of this submessage. + * Enter an item in the protocol tree that spans over the entire + * submessage. + */ + expert_add_info(pinfo, item, &ei_rtps_missing_bytes); + } +} + + +/* *********************************************************************** */ /* * Serialized data dissector * */ /* *********************************************************************** */ /* Note: the encapsulation header is ALWAYS big endian, then the encapsulation * type specified the type of endianess of the payload. */ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, - int size, const char * label, guint16 vendor_id) { + int size, const char * label, guint16 vendor_id, gboolean is_discovery_data) { proto_item * ti; proto_tree * rtps_parameter_sequence_tree; guint16 encapsulation_id; @@ -3987,7 +4614,7 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff rtps_parameter_sequence_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_rtps_serialized_data, &ti, label); /* Encapsulation ID */ - encapsulation_id = NEXT_guint16(tvb, offset, FALSE); /* Always big endian */ + encapsulation_id = NEXT_guint16(tvb, offset, ENC_BIG_ENDIAN); /* Always big endian */ proto_tree_add_uint(rtps_parameter_sequence_tree, hf_rtps_param_serialize_encap_kind, tvb, offset, 2, encapsulation_id); offset += 2; @@ -4012,13 +4639,228 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff case ENCAPSULATION_PL_CDR_LE: case ENCAPSULATION_PL_CDR_BE: - dissect_parameter_sequence(rtps_parameter_sequence_tree, pinfo, tvb, offset, + if (is_discovery_data) { + dissect_parameter_sequence(rtps_parameter_sequence_tree, pinfo, tvb, offset, encapsulation_little_endian, size, label, 0x0200, NULL, vendor_id); + } else { + expert_add_info(pinfo, ti, &ei_rtps_unsupported_non_builtin_param_seq); + } break; default: - proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset, - size, "%s", label); + proto_tree_add_item(rtps_parameter_sequence_tree, hf_rtps_data_serialize_data, tvb, + offset, size, encapsulation_little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + } +} + +/* *********************************************************************** */ +/* * A P P_ A C K * */ +/* *********************************************************************** */ +static void dissect_APP_ACK(tvbuff_t *tvb, + packet_info *pinfo, + gint offset, + guint8 flags, + gboolean little_endian, + int octets_to_next_header, + proto_tree *tree, + guint16 vendor_id, + proto_item *item) + { + /* + * 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | APP_ACK |X|X|X|X|X|X|X|E| octetsToNextHeader | + * +---------------+---------------+---------------+---------------+ + * | EntityId readerEntityId | + * +---------------+---------------+---------------+---------------+ + * | EntityId writerEntityId | + * +---------------+---------------+---------------+---------------+ + * + unsigned long virtualWriterCount + + * +---------------+---------------+---------------+---------------+ + * | GuidPrefix virtualWriterGuidPrefix | + * +---------------+---------------+---------------+---------------+ + * EntityId virtualWriterObjectId + * unsigned short intervalCount | unsigned short bytesToNextVirtualWriter + * + * SequenceNumber intervalFirstSn + * SequenceNumber intervalLastSn + * unsigned short intervalFlags | unsigned short payloadLength + * + * (after last interval) unsigned long virtualWriterEpoch + * + */ + gint original_offset; /* Offset to the readerEntityId */ + guint32 virtual_writer_count; + guint32 wid; /* Writer EntityID */ + proto_item *octet_item; + rtps_util_decode_flags(tree, tvb, offset + 1, flags, APP_ACK_FLAGS); + + octet_item = proto_tree_add_item(tree, hf_rtps_sm_octets_to_next_header, tvb, + offset + 2, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + + if (octets_to_next_header < 56) { + expert_add_info_format(pinfo, octet_item, &ei_rtps_sm_octets_to_next_header_error, "(Error: should be >= %u)", 56); + return; + } + + offset += 4; + original_offset = offset; + + /* readerEntityId */ + rtps_util_add_entity_id(tree, + tvb, + offset, + hf_rtps_sm_rdentity_id, + hf_rtps_sm_rdentity_id_key, + hf_rtps_sm_rdentity_id_kind, + ett_rtps_rdentity, + "readerEntityId", + NULL); + offset += 4; + + /* writerEntityId */ + rtps_util_add_entity_id(tree, + tvb, + offset, + hf_rtps_sm_wrentity_id, + hf_rtps_sm_wrentity_id_key, + hf_rtps_sm_wrentity_id_kind, + ett_rtps_wrentity, + "writerEntityId", + &wid); + offset += 4; + + + /* virtualWriterCount */ + virtual_writer_count = NEXT_guint32(tvb, offset, little_endian); + proto_tree_add_item(tree, hf_rtps_param_app_ack_virtual_writer_count, tvb, offset+4, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + + + { + /* Deserialize Virtual Writers */ + proto_tree * sil_tree_writer_list = NULL; + proto_tree * sil_tree_writer = NULL; + + proto_tree * sil_tree_interval_list = NULL; + proto_tree * sil_tree_interval = NULL; + guint32 current_writer_index = 0; + guint32 current_interval_count = 0; + guint16 interval_count = 0; + /* guint16 interval_flags = 0; */ + guint16 interval_payload_length = 0; + /* guint32 current_virtual_guid_index = 0;*/ + + /** Writer list **/ + sil_tree_writer_list = proto_tree_add_subtree_format(tree, tvb, offset, -1, + ett_rtps_app_ack_virtual_writer_list, NULL, "Virtual Writer List"); + + current_writer_index = 0; + + while (current_writer_index < virtual_writer_count) { + sil_tree_writer = proto_tree_add_subtree_format(sil_tree_writer_list, tvb, offset, -1, + ett_rtps_app_ack_virtual_writer, NULL, "virtualWriter[%d]", current_writer_index); + + /* Virtual Writer Guid */ + /*rtps_util_add_generic_guid(sil_tree_writer, + tvb, + offset, + "virtualGUID", + buffer, + MAX_GUID_SIZE);*/ + offset += 16; + + + /* Interval count */ + interval_count = NEXT_guint16(tvb, offset, little_endian); + proto_tree_add_item(sil_tree_writer, hf_rtps_param_app_ack_interval_count, + tvb, offset, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 2; + + /* bytes to next virtual writer */ + proto_tree_add_item(sil_tree_writer, hf_rtps_param_app_ack_octets_to_next_virtual_writer, + tvb, offset, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 2; + + /* Interval list */ + sil_tree_interval_list = proto_tree_add_subtree_format(sil_tree_writer, tvb, offset, -1, + ett_rtps_app_ack_virtual_writer_interval_list, NULL, "Interval List"); + + current_interval_count = 0; + while (current_interval_count < interval_count) { + sil_tree_interval = proto_tree_add_subtree_format(sil_tree_interval_list, tvb, offset, -1, + ett_rtps_app_ack_virtual_writer_interval, NULL, "Interval[%d]", current_interval_count); + + /* firstVirtualSN */ + rtps_util_add_seq_number(sil_tree_interval, + tvb, + offset, + little_endian, + "firstVirtualSN"); + offset += 8; + + /* lastVirtualSN */ + rtps_util_add_seq_number(sil_tree_interval, + tvb, + offset, + little_endian, + "lastVirtualSN"); + offset += 8; + + /* interval flags */ + /* interval_flags = NEXT_guint16(tvb, offset, little_endian); */ + proto_tree_add_item(sil_tree_interval, hf_rtps_param_app_ack_interval_flags, + tvb, offset, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 2; + + /* interval payload length */ + interval_payload_length = NEXT_guint16(tvb, offset, little_endian); + proto_tree_add_item(sil_tree_interval, hf_rtps_param_app_ack_interval_payload_length, + tvb, offset, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 2; + + if (interval_payload_length > 0) { + dissect_serialized_data(sil_tree_interval, + pinfo, + tvb, + offset, + interval_payload_length, + "payload", + vendor_id, + FALSE /* from_builtin_writer */); + offset += interval_payload_length; + } + + ++current_interval_count; + + } /* interval list */ + + /* Count */ + proto_tree_add_item(tree, hf_rtps_param_app_ack_count, tvb, offset+4, 4, + little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + + current_writer_index++; + + } /* virtual_writer_count */ + } + + + if (offset < original_offset + octets_to_next_header) + { + /* In this case there must be something wrong in the bitmap: there + * are some extra bytes that we don't know how to decode + */ + expert_add_info_format(pinfo, item, &ei_rtps_extra_bytes, "Don't know how to decode those extra bytes: %d", octets_to_next_header - offset); + } + else if (offset > original_offset + octets_to_next_header) + { + /* Decoding the bitmap went over the end of this submessage. + * Enter an item in the protocol tree that spans over the entire + * submessage. + */ + expert_add_info(pinfo, item, &ei_rtps_missing_bytes); } } @@ -4269,6 +5111,7 @@ static void dissect_DATA_v2(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin guint32 wid; /* Writer EntityID */ guint32 status_info = 0xffffffff; proto_item* octet_item; + gboolean from_builtin_writer; rtps_util_decode_flags(tree, tvb, offset + 1, flags, DATA_FLAGSv2); @@ -4352,9 +5195,11 @@ static void dissect_DATA_v2(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin /* SerializedData */ if ((flags & FLAG_DATA_D_v2) != 0) { + from_builtin_writer = + (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - "serializedData", vendor_id); + "serializedData", vendor_id, from_builtin_writer); } info_summary_append_ex(pinfo, wid, status_info); } @@ -4401,7 +5246,8 @@ static void dissect_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu int min_len; gint old_offset = offset; proto_item* octet_item; - + guint32 wid; + gboolean from_builtin_writer; rtps_util_decode_flags(tree, tvb, offset + 1, flags, NOKEY_DATA_FRAG_FLAGS); octet_item = proto_tree_add_item(tree, hf_rtps_sm_octets_to_next_header, tvb, @@ -4432,7 +5278,7 @@ static void dissect_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu /* writerEntityId */ rtps_util_add_entity_id(tree, tvb, offset, hf_rtps_sm_wrentity_id, hf_rtps_sm_wrentity_id_key, - hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", NULL); + hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", &wid); offset += 4; /* Sequence number */ @@ -4483,9 +5329,11 @@ static void dissect_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu /* SerializedData */ if ((flags & FLAG_DATA_D_v2) != 0) { + from_builtin_writer = + (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - "serializedData", vendor_id); + "serializedData", vendor_id, from_builtin_writer); } } @@ -4567,6 +5415,8 @@ static void dissect_NOKEY_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, g */ int min_len; + guint32 wid; /* Writer EntityID */ + gboolean from_builtin_writer; gint old_offset = offset; proto_item* octet_item; @@ -4593,7 +5443,7 @@ static void dissect_NOKEY_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, g /* writerEntityId */ rtps_util_add_entity_id(tree, tvb, offset, hf_rtps_sm_wrentity_id, hf_rtps_sm_wrentity_id_key, - hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", NULL); + hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", &wid); offset += 4; /* Sequence number */ @@ -4616,9 +5466,11 @@ static void dissect_NOKEY_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, g } if ((version >= 0x0200) && (flags & FLAG_DATA_D_v2) != 0) { + from_builtin_writer = + (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - "serializedData", vendor_id); + "serializedData", vendor_id, from_builtin_writer); } } @@ -4659,6 +5511,8 @@ static void dissect_NOKEY_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offs */ int min_len; + guint32 wid; /* Writer EntityID */ + gboolean from_builtin_writer; gint old_offset = offset; proto_item* octet_item; rtps_util_decode_flags(tree, tvb, offset + 1, flags, NOKEY_DATA_FRAG_FLAGS); @@ -4689,7 +5543,7 @@ static void dissect_NOKEY_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offs /* writerEntityId */ rtps_util_add_entity_id(tree, tvb, offset, hf_rtps_sm_wrentity_id, hf_rtps_sm_wrentity_id_key, - hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", NULL); + hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", &wid); offset += 4; /* Sequence number */ @@ -4720,9 +5574,11 @@ static void dissect_NOKEY_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offs /* SerializedData */ if ((flags & FLAG_DATA_D_v2) != 0) { + from_builtin_writer = + (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; dissect_serialized_data(tree, pinfo, tvb,offset, octets_to_next_header - (offset - old_offset) + 4, - "serializedData", vendor_id); + "serializedData", vendor_id, from_builtin_writer); } } @@ -4821,7 +5677,7 @@ static void dissect_ACKNACK(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin */ if (offset + 4 == original_offset + octets_to_next_header) { /* Count is present */ - proto_tree_add_item(tree, hf_rtps_acknack_counter, tvb, offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_rtps_acknack_count, tvb, offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); } else if (offset < original_offset + octets_to_next_header) { /* In this case there must be something wrong in the bitmap: there * are some extra bytes that we don't know how to decode @@ -5090,6 +5946,271 @@ static void dissect_HEARTBEAT_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs } /* *********************************************************************** */ +/* * H E A R T B E A T _ V I R T U A L * */ +/* *********************************************************************** */ + +static void dissect_HEARTBEAT_VIRTUAL(tvbuff_t *tvb, packet_info *pinfo _U_, gint offset, + guint8 flags, gboolean little_endian, int octets_to_next_header, proto_tree *tree, + guint16 vendor_id _U_) { + + /* + * VIRTUAL_HB: + * + * 0...2...........7...............15.............23...............31 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VIRTUAL_HB |X|X|X|X|N|W|V|E| octetsToNextHeader | + * +---------------+---------------+---------------+---------------+ + * | EntityId readerId | + * +---------------+---------------+---------------+---------------+ + * | EntityId writerId | + * +---------------+---------------+---------------+---------------+ + * | Guid_t virtualGUID (V=0 & N=0) | + * + + + * | | + * + + + * | | + * + + + * | | + * +---------------+---------------+---------------+---------------+ + * | unsigned long numWriters (W=1) | + * +---------------+---------------+---------------+---------------+ + * | | + * ~ WriterVirtualHBList writerVirtualHBList ~ + * | | + * +---------------+---------------+---------------+---------------+ + * | unsigned long count | + * +---------------+---------------+---------------+---------------+ + + * WRITER_VIRTUAL_HB: + * + * 0...2...........7...............15.............23...............31 + * +---------------+---------------+---------------+---------------+ + * | EntityId writerId (W=1) | + * +---------------+---------------+---------------+---------------+ + * | unsigned long numVirtualGUIDs (N=0) | + * +---------------+---------------+---------------+---------------+ + * | | + * ~ VirtualGUIDHBList virtualGUIDHBList ~ + * | | + * +---------------+---------------+---------------+---------------+ + * + * VIRTUAL_GUID_HB: + * + * 0...2...........7...............15.............23...............31 + * +---------------+---------------+---------------+---------------+ + * | Guid_t virtualGUID (V=1) | + * + + + * | | + * + + + * | | + * + + + * | | + * +---------------+---------------+---------------+---------------+ + * | | + * + SequenceNumber firstVirtualSN + + * | | + * +---------------+---------------+---------------+---------------+ + * | | + * + SequenceNumber lastVirtualSN + + * | | + * +---------------+---------------+---------------+---------------+ + * | | + * + SequenceNumber firstRTPSSN + + * | | + * +---------------+---------------+---------------+---------------+ + * | | + * + SequenceNumber lastRTPSSN + + * | | + * +---------------+---------------+---------------+---------------+ + */ + + guint32 num_writers, num_virtual_guids; + gint writer_id_offset, virtual_guid_offset = 0, old_offset; + proto_item *octet_item, *ti; + rtps_util_decode_flags(tree, tvb, offset + 1, flags, HEARTBEAT_VIRTUAL_FLAGS); + + + octet_item = proto_tree_add_item(tree, hf_rtps_sm_octets_to_next_header, tvb, + offset + 2, 2, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + + if (octets_to_next_header < 12) { + expert_add_info_format(pinfo, octet_item, &ei_rtps_sm_octets_to_next_header_error, "(Error: should be >= %u)", 12); + return; + } + offset += 4; + + /* readerEntityId */ + rtps_util_add_entity_id(tree, + tvb, + offset, + hf_rtps_sm_rdentity_id, + hf_rtps_sm_rdentity_id_key, + hf_rtps_sm_rdentity_id_kind, + ett_rtps_rdentity, + "readerEntityId", + NULL); + offset += 4; + + /* writerEntityId */ + rtps_util_add_entity_id(tree, + tvb, + offset, + hf_rtps_sm_wrentity_id, + hf_rtps_sm_wrentity_id_key, + hf_rtps_sm_wrentity_id_kind, + ett_rtps_wrentity, + "writerEntityId", + NULL); + writer_id_offset = offset; + offset += 4; + + /* virtualGUID */ + if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V) && !(flags & FLAG_VIRTUAL_HEARTBEAT_N)) { + /*rtps_util_add_generic_guid(tree, + tvb, + offset, + "virtualGUID", + buffer, + MAX_GUID_SIZE);*/ + virtual_guid_offset = offset; + offset += 16; + } + + /* num_writers */ + ti = proto_tree_add_item(tree, hf_rtps_virtual_heartbeat_num_writers, tvb, + offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + if (flags & FLAG_VIRTUAL_HEARTBEAT_W) { + num_writers = NEXT_guint32(tvb, offset, little_endian); + offset += 4; + } else { + proto_item_set_text(ti, "numWriters: 1"); + num_writers = 1; + } + + { + /* Deserialize Writers */ + proto_tree * sil_tree_writer_list = NULL; + proto_tree * sil_tree_writer = NULL; + proto_tree * sil_tree_virtual_guid_list = NULL; + proto_tree * sil_tree_virtual_guid = NULL; + guint32 current_writer_index = 0; + guint32 current_virtual_guid_index = 0; + + /** Writer list **/ + sil_tree_writer_list = proto_tree_add_subtree_format(tree, tvb, offset, -1, + ett_rtps_writer_heartbeat_virtual_list, NULL, "Writer List"); + + current_writer_index = 0; + + while (current_writer_index < num_writers) { + sil_tree_writer = proto_tree_add_subtree_format(sil_tree_writer_list, tvb, offset, -1, + ett_rtps_writer_heartbeat_virtual, NULL, "writer[%d]", current_writer_index); + + if (num_writers == 1) { + old_offset = offset; + offset = writer_id_offset; + } + + rtps_util_add_entity_id(sil_tree_writer, + tvb, + offset, + hf_rtps_sm_wrentity_id, + hf_rtps_sm_wrentity_id_key, + hf_rtps_sm_wrentity_id_kind, + ett_rtps_wrentity, + "writerEntityId", + NULL); + + if (num_writers == 1) { + offset = old_offset; + } else { + offset += 4; + } + + if (!(flags & FLAG_VIRTUAL_HEARTBEAT_N)) { + proto_tree_add_item(sil_tree_writer, hf_rtps_virtual_heartbeat_num_virtual_guids, tvb, + offset, 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + offset += 4; + } else { + num_virtual_guids = 0; + } + + /** Virtual GUID list **/ + if (num_virtual_guids != 0) { + sil_tree_virtual_guid_list = proto_tree_add_subtree_format(sil_tree_writer, tvb, offset, -1, + ett_rtps_virtual_guid_heartbeat_virtual_list, NULL, "Virtual GUID List"); + + current_virtual_guid_index = 0; + + while (current_virtual_guid_index < num_virtual_guids) { + sil_tree_virtual_guid = proto_tree_add_subtree_format(sil_tree_virtual_guid_list, tvb, offset, -1, + ett_rtps_virtual_guid_heartbeat_virtual, NULL, "virtualGUID[%d]", current_virtual_guid_index); + + if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V)) { + old_offset = offset; + offset = virtual_guid_offset; + } + + /*rtps_util_add_generic_guid_v2(sil_tree_virtual_guid, + tvb, + offset, + "virtualGUID", + buffer, + MAX_GUID_SIZE);*/ + + if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V)) { + offset = old_offset; + } else { + offset += 16; + } + + /* firstVirtualSN */ + rtps_util_add_seq_number(sil_tree_virtual_guid, + tvb, + offset, + little_endian, + "firstVirtualSN"); + offset += 8; + + /* lastVirtualSN */ + rtps_util_add_seq_number(sil_tree_virtual_guid, + tvb, + offset, + little_endian, + "lastVirtualSN"); + offset += 8; + + /* firstRTPSSN */ + rtps_util_add_seq_number(sil_tree_virtual_guid, + tvb, + offset, + little_endian, + "firstRTPSSN"); + offset += 8; + + /* lastRTPSSN */ + rtps_util_add_seq_number(sil_tree_virtual_guid, + tvb, + offset, + little_endian, + "lastRTPSSN"); + offset += 8; + + current_virtual_guid_index++; + } + } + + current_writer_index++; + } + } + + /* Count */ + proto_tree_add_item(tree, hf_rtps_virtual_heartbeat_count, tvb, offset, + 4, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN); + } + + +/* *********************************************************************** */ /* * H E A R T B E A T _ F R A G * */ /* *********************************************************************** */ static void dissect_HEARTBEAT_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, @@ -5219,6 +6340,7 @@ static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu gint old_offset = offset; guint32 wid; /* Writer EntityID */ guint32 status_info = 0xffffffff; + gboolean from_builtin_writer; proto_item* octet_item; rtps_util_decode_flags(tree, tvb, offset + 1, flags, RTPS_DATA_FLAGS); @@ -5366,10 +6488,13 @@ static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu label = "<invalid or unknown data type>"; } + from_builtin_writer = + (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; + /* At the end still dissect the rest of the bytes as raw data */ dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - label, vendor_id); + label, vendor_id, from_builtin_writer); } } @@ -5379,13 +6504,8 @@ static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu /* *********************************************************************** */ /* * R T P S _ D A T A _ F R A G * */ /* *********************************************************************** */ -static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, - packet_info *pinfo, - gint offset, - guint8 flags, - gboolean little_endian, - int octets_to_next_header, - proto_tree *tree, +static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, + gboolean little_endian, int octets_to_next_header, proto_tree *tree, guint16 vendor_id) { /* * @@ -5421,6 +6541,7 @@ static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, int min_len; gint old_offset = offset; guint32 wid; /* Writer EntityID */ + gboolean from_builtin_writer; guint32 status_info = 0xffffffff; proto_item* octet_item; @@ -5515,9 +6636,12 @@ static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, if ((flags & FLAG_RTPS_DATA_FRAG_K) != 0) { label = "serializedKey"; } + from_builtin_writer = + (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; + dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - label, vendor_id); + label, vendor_id, from_builtin_writer); } info_summary_append_ex(pinfo, wid, status_info); } @@ -5833,13 +6957,8 @@ static void dissect_RTPS_DATA_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs /* *********************************************************************** */ /* * G A P * */ /* *********************************************************************** */ -static void dissect_GAP(tvbuff_t *tvb, - packet_info *pinfo, - gint offset, - guint8 flags, - gboolean little_endian, - int octets_to_next_header, - proto_tree *tree) { +static void dissect_GAP(tvbuff_t *tvb, packet_info *pinfo, gint offset, + guint8 flags, gboolean little_endian, int octets_to_next_header, proto_tree *tree) { /* RTPS 1.0/1.1: * 0...2...........7...............15.............23...............31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -6189,13 +7308,8 @@ static void dissect_INFO_DST(tvbuff_t *tvb, packet_info *pinfo, gint offset, gui /* *********************************************************************** */ /* * I N F O _ R E P L Y * */ /* *********************************************************************** */ -static void dissect_INFO_REPLY(tvbuff_t *tvb, - packet_info *pinfo, - gint offset, - guint8 flags, - gboolean little_endian, - int octets_to_next_header, - proto_tree *tree) { +static void dissect_INFO_REPLY(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, + gboolean little_endian, int octets_to_next_header, proto_tree *tree) { /* RTPS 1.0/1.1: * INFO_REPLY is *NOT* the same thing as the old INFO_REPLY. * @@ -6268,6 +7382,14 @@ static gboolean dissect_rtps_submessage_v2(tvbuff_t *tvb, packet_info *pinfo, gi dissect_ACKNACK(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree, submessage_item); break; + case SUBMESSAGE_APP_ACK: + dissect_APP_ACK(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree, vendor_id, submessage_item); + break; + + case SUBMESSAGE_APP_ACK_CONF: + dissect_APP_ACK_CONF(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree, submessage_item); + break; + case SUBMESSAGE_HEARTBEAT_SESSION: case SUBMESSAGE_HEARTBEAT_BATCH: dissect_HEARTBEAT_BATCH(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree); @@ -6277,10 +7399,14 @@ static gboolean dissect_rtps_submessage_v2(tvbuff_t *tvb, packet_info *pinfo, gi dissect_HEARTBEAT_FRAG(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree); break; + case SUBMESSAGE_HEARTBEAT_VIRTUAL: + dissect_HEARTBEAT_VIRTUAL(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree, vendor_id); + break; + case SUBMESSAGE_RTPS_DATA_SESSION: case SUBMESSAGE_RTPS_DATA: - dissect_RTPS_DATA(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree, - vendor_id, (submessageId == SUBMESSAGE_RTPS_DATA_SESSION)); + dissect_RTPS_DATA(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, + rtps_submessage_tree, vendor_id, (submessageId == SUBMESSAGE_RTPS_DATA_SESSION)); break; case SUBMESSAGE_RTPS_DATA_FRAG: @@ -7066,6 +8192,28 @@ void proto_register_rtps(void) { HFILL } }, + { &hf_rtps_transportInfo_classId, { + "classID", + "rtps.transportInfo.classID", + FT_INT32, + BASE_DEC, + NULL, + 0, + "Class ID of transport", + HFILL } + }, + + { &hf_rtps_transportInfo_messageSizeMax, { + "messageSizeMax", + "rtps.transportInfo.messageSizeMax", + FT_INT32, + BASE_DEC, + NULL, + 0, + "Maximum message size of transport", + HFILL } + }, + /* Parameter / Topic Data ---------------------------------------------- */ { &hf_rtps_param_topic_data, { "topicData", @@ -7249,12 +8397,60 @@ void proto_register_rtps(void) { NULL, HFILL } }, - { &hf_rtps_acknack_counter, - { "Counter", "rtps.acknack.counter", + { &hf_rtps_acknack_count, + { "Count", "rtps.acknack.count", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_virtual_writer_count, + { "virtualWriterCount", "rtps.app_ack.virtual_writer_count", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_count, + { "count", "rtps.app_ack.virtual_writer_count", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_conf_virtual_writer_count, + { "virtualWriterCount", "rtps.app_ack_conf.virtual_writer_count", FT_INT32, BASE_DEC, NULL, 0, NULL, HFILL } }, + { &hf_rtps_param_app_ack_conf_count, + { "count", "rtps.app_ack_conf.count", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_interval_payload_length, + { "intervalPayloadLength", "rtps.app_ack.interval_payload_length", + FT_INT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_interval_flags, + { "intervalFlags", "rtps.app_ack.interval_flags", + FT_INT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_interval_count, + { "intervalCount", "rtps.app_ack.interval_count", + FT_INT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_app_ack_octets_to_next_virtual_writer, + { "octetsToNextVirtualWriter", "rtps.app_ack.octects_to_next_virtual_writer", + FT_INT16, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_rtps_durability_service_history_kind, { "History Kind", "rtps.durability_service.history_kind", FT_UINT32, BASE_HEX, VALS(history_qos_vals), 0, @@ -7339,12 +8535,24 @@ void proto_register_rtps(void) { NULL, HFILL } }, + { &hf_rtps_direct_communication, + { "Direct Communication", "rtps.direct_communication", + FT_BOOLEAN, 8, TFS(&tfs_true_false), 0, + NULL, HFILL } + }, + { &hf_rtps_expects_ack, { "expectsAck", "rtps.expects_ack", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0, NULL, HFILL } }, + { &hf_rtps_expects_virtual_heartbeat, + { "expectsVirtualHB", "rtps.expects_virtual_heartbeat", + FT_BOOLEAN, 8, TFS(&tfs_true_false), 0, + NULL, HFILL } + }, + { &hf_rtps_reliability_kind, { "Kind", "rtps.reliability_kind", FT_UINT32, BASE_HEX, VALS(reliability_qos_vals), 0, @@ -7406,6 +8614,21 @@ void proto_register_rtps(void) { HFILL } }, + /* Parameter / NtpTime ------------------------------------------------- */ + { &hf_rtps_param_ntpt_sec, { + "seconds", "rtps.param.ntpTime.sec", + FT_INT32, BASE_DEC, NULL, 0, + "The 'second' component of a NTP time", + HFILL } + }, + + { &hf_rtps_param_ntpt_fraction, { + "fraction", "rtps.param.ntpTime.fraction", + FT_UINT32, BASE_DEC, NULL, 0, + "The 'fraction' component of a NTP time", + HFILL } + }, + { &hf_rtps_param_transport_priority, { "Value", "rtps.param.transport_priority", FT_UINT32, BASE_DEC, NULL, 0, @@ -7418,6 +8641,12 @@ void proto_register_rtps(void) { NULL, HFILL } }, + { &hf_rtps_param_peer_host_epoch, + { "Peer Host Epoch", "rtps.param.peer_host_epoch", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_rtps_param_entity_name, { "entity", "rtps.param.entityName", FT_STRINGZ, BASE_NONE, NULL, 0, @@ -7497,6 +8726,18 @@ void proto_register_rtps(void) { NULL, HFILL } }, + { &hf_rtps_param_extended_pid_length, + { "Extended Length", "rtps.param.extended_pid_length", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_param_extended_parameter, + { "Extended Parameter", "rtps.param.extended_parameter", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL } + }, + { &hf_rtps_data_frag_number, { "fragmentStartingNum", "rtps.data_frag.number", FT_UINT32, BASE_DEC, NULL, 0, @@ -7563,12 +8804,36 @@ void proto_register_rtps(void) { NULL, HFILL } }, + { &hf_rtps_virtual_heartbeat_count, + { "Count", "rtps.virtual_heartbeat.count", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_virtual_heartbeat_num_virtual_guids, + { "numVirtualGUIDs", "rtps.virtual_heartbeat.num_virtual_guids", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + + { &hf_rtps_virtual_heartbeat_num_writers, + { "numWriters", "rtps.virtual_heartbeat.num_virtual_guids", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_rtps_data_serialize_data, { "serializedData", "rtps.data.serialize_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } }, + { &hf_rtps_parameter_data, { + "parameterData", "rtps.parameter_data", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL } + }, + { &hf_rtps_data_batch_timestamp, { "Timestamp", "rtps.data_batch.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, @@ -7707,6 +8972,18 @@ void proto_register_rtps(void) { NULL, HFILL } }, + { &hf_rtps_param_type_consistency_kind, + { "Type Consistency Kind", "rtps.param.type_consistency_kind", + FT_UINT16, BASE_HEX, VALS(type_consistency_kind_vals), 0, + NULL, HFILL } + }, + + { &hf_rtps_param_acknowledgment_kind, + { "Acknowledgment Kind", "rtps.param.acknowledgment_kind", + FT_UINT32, BASE_HEX, VALS(acknowledgement_kind_vals), 0, + NULL, HFILL } + }, + /* Finally the raw issue data ------------------------------------------ */ { &hf_rtps_issue_data, { "serializedData", @@ -7718,12 +8995,39 @@ void proto_register_rtps(void) { "The user data transferred in a ISSUE submessage", HFILL } }, + + { &hf_rtps_param_product_version_major, { + "Major", "rtps.param.product_version.major", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_rtps_param_product_version_minor, { + "Minor", "rtps.param.product_version.minor", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_rtps_param_product_version_release, { + "Release", "rtps.param.product_version.release", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + + { &hf_rtps_param_product_version_release_as_char, { + "Release", "rtps.param.product_version.release", + FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } + }, + + { &hf_rtps_param_product_version_revision, { + "Revision", "rtps.param.product_version.revision", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } + }, + }; static gint *ett[] = { &ett_rtps, &ett_rtps_default_mapping, &ett_rtps_proto_version, + &ett_rtps_product_version, &ett_rtps_submessage, &ett_rtps_parameter_sequence, &ett_rtps_parameter, @@ -7750,7 +9054,17 @@ void proto_register_rtps(void) { &ett_rtps_part_message_data, &ett_rtps_sample_info_list, &ett_rtps_sample_info, - &ett_rtps_sample_batch_list + &ett_rtps_sample_batch_list, + &ett_rtps_locator_filter_locator, + &ett_rtps_writer_heartbeat_virtual_list, + &ett_rtps_writer_heartbeat_virtual, + &ett_rtps_virtual_guid_heartbeat_virtual_list, + &ett_rtps_virtual_guid_heartbeat_virtual, + &ett_rtps_app_ack_virtual_writer_list, + &ett_rtps_app_ack_virtual_writer, + &ett_rtps_app_ack_virtual_writer_interval_list, + &ett_rtps_app_ack_virtual_writer_interval, + &ett_rtps_transport_info }; static ei_register_info ei[] = { @@ -7764,6 +9078,7 @@ void proto_register_rtps(void) { { &ei_rtps_extra_bytes, { "rtps.extra_bytes", PI_MALFORMED, PI_ERROR, "Don't know how to decode those extra bytes: %d", EXPFILL }}, { &ei_rtps_missing_bytes, { "rtps.missing_bytes", PI_MALFORMED, PI_ERROR, "Not enough bytes to decode", EXPFILL }}, { &ei_rtps_more_samples_available, { "rtps.more_samples_available", PI_PROTOCOL, PI_NOTE, "More samples available. Configure this limit from preferences dialog", EXPFILL }}, + { &ei_rtps_unsupported_non_builtin_param_seq, { "rtps.unsupported_non_builtin_param_seq", PI_PROTOCOL, PI_WARN, "Unsupported non-builtin parameter sequence", EXPFILL }}, }; module_t *rtps_module; diff --git a/epan/dissectors/packet-rtps.h b/epan/dissectors/packet-rtps.h index 1c6bb792cc..c409a2f418 100644 --- a/epan/dissectors/packet-rtps.h +++ b/epan/dissectors/packet-rtps.h @@ -3,9 +3,9 @@ * * Routines for Real-Time Publish-Subscribe Protocol (RTPS) dissection * - * Copyright 2005, Fabrizio Bertocci <fabrizio@rti.com> + * (c) 2005-2014 Copyright, Real-Time Innovations, Inc. * Real-Time Innovations, Inc. - * 385 Moffett Park Drive, Suite 115 + * 232 East Java Drive * Sunnyvale, CA 94089 * * Copyright 2003, LUKAS POKORNY <maskis@seznam.cz> @@ -80,9 +80,36 @@ typedef enum { RTI_CDR_TK_WCHAR, RTI_CDR_TK_WSTRING, RTI_CDR_TK_VALUE, - RTI_CDR_TK_VALUE_PARARM + RTI_CDR_TK_VALUE_PARAM } RTICdrTCKind; +typedef enum { + RTI_CDR_TYPE_OBJECT_TYPE_KIND_NO_TYPE=0, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_BOOLEAN_TYPE=1, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_BYTE_TYPE=2, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_INT_16_TYPE=3, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_UINT_16_TYPE=4, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_INT_32_TYPE=5, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_UINT_32_TYPE=6, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_INT_64_TYPE=7, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_UINT_64_TYPE=8, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_FLOAT_32_TYPE=9, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_FLOAT_64_TYPE=10, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_FLOAT_128_TYPE=11, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_CHAR_8_TYPE=12, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_CHAR_32_TYPE=13, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_ENUMERATION_TYPE=14, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_BITSET_TYPE=15, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_ALIAS_TYPE=16, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_ARRAY_TYPE=17, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_SEQUENCE_TYPE=18, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_STRING_TYPE=19, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_MAP_TYPE=20, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_UNION_TYPE=21, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_STRUCTURE_TYPE=22, + RTI_CDR_TYPE_OBJECT_TYPE_KIND_ANNOTATION_TYPE=23 +} RTICdrTypeObjectTypeKind; + #define RTPS_MAGIC_NUMBER 0x52545053 /* RTPS */ /* Traffic type */ @@ -125,6 +152,9 @@ typedef enum { #define FLAG_SAMPLE_INFO_I (0x10) #define FLAG_SAMPLE_INFO_K (0x20) +#define FLAG_VIRTUAL_HEARTBEAT_V (0x02) +#define FLAG_VIRTUAL_HEARTBEAT_W (0x04) +#define FLAG_VIRTUAL_HEARTBEAT_N (0x08) /* The following PIDs are defined since RTPS 1.0 */ #define PID_PAD (0x00) @@ -211,6 +241,8 @@ typedef enum { #define PID_ENTITY_NAME (0x0062) #define PID_KEY_HASH (0x0070) #define PID_STATUS_INFO (0x0071) +#define PID_TYPE_OBJECT (0x0072) +#define PID_TYPE_CONSISTENCY (0x0074) /* Vendor-specific: RTI */ #define PID_PRODUCT_VERSION (0x8000) @@ -220,6 +252,15 @@ typedef enum { #define PID_TYPECODE_RTPS2 (0x8004) /* Was: 0x47 in RTPS 1.2 */ #define PID_DISABLE_POSITIVE_ACKS (0x8005) #define PID_LOCATOR_FILTER_LIST (0x8006) +#define PID_EXPECTS_VIRTUAL_HB (0x8009) +#define PID_ROLE_NAME (0x800a) +#define PID_ACK_KIND (0x800b) +#define PID_PEER_HOST_EPOCH (0x800e) +#define PID_DOMAIN_ID (0x800f) +#define PID_TRANSPORT_INFO_LIST (0x8010) +#define PID_DIRECT_COMMUNICATION (0x8011) +#define PID_EXTENDED (0x3f01) +#define PID_LIST_END (0x3f02) /* appId.appKind possible values */ #define APPKIND_UNKNOWN (0x00) @@ -227,7 +268,6 @@ typedef enum { #define APPKIND_MANAGER (0x02) - /* Predefined EntityId */ #define ENTITYID_UNKNOWN (0x00000000) #define ENTITYID_PARTICIPANT (0x000001c1) @@ -295,6 +335,9 @@ typedef enum { #define SUBMESSAGE_HEARTBEAT_BATCH (0x19) /* RTPS 2.1 only */ #define SUBMESSAGE_ACKNACK_SESSION (0x1a) /* RTPS 2.1 only */ #define SUBMESSAGE_HEARTBEAT_SESSION (0x1b) /* RTPS 2.1 only */ +#define SUBMESSAGE_APP_ACK (0x1c) +#define SUBMESSAGE_APP_ACK_CONF (0x1d) +#define SUBMESSAGE_HEARTBEAT_VIRTUAL (0x1e) /* An invalid IP Address: @@ -390,6 +433,32 @@ typedef enum { #define PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE (0x00000001) #define PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE (0x00000002) +/* Type Consistency Kinds */ +#define DISALLOW_TYPE_COERCION (0) +#define ALLOW_TYPE_COERCION (1) + +/* Ack kind */ +#define PROTOCOL_ACKNOWLEDGMENT (0) +#define APPLICATION_AUTO_ACKNOWLEDGMENT (1) +#define APPLICATION_ORDERED_ACKNOWLEDGMENT (2) +#define APPLICATION_EXPLICIT_ACKNOWLEDGMENT (3) + +/* NDDS_TRANSPORT_CLASSID */ +#define NDDS_TRANSPORT_CLASSID_ANY (0) +#define NDDS_TRANSPORT_CLASSID_UDPv4 (1) +#define NDDS_TRANSPORT_CLASSID_SHMEM (2) +#define NDDS_TRANSPORT_CLASSID_INTRA (3) +#define NDDS_TRANSPORT_CLASSID_UDPv6 (5) +#define NDDS_TRANSPORT_CLASSID_DTLS (6) +#define NDDS_TRANSPORT_CLASSID_WAN (7) +#define NDDS_TRANSPORT_CLASSID_TCPV4_LAN (8) +#define NDDS_TRANSPORT_CLASSID_TCPV4_WAN (9) +#define NDDS_TRANSPORT_CLASSID_TLSV4_LAN (10) +#define NDDS_TRANSPORT_CLASSID_TLSV4_WAN (11) +#define NDDS_TRANSPORT_CLASSID_PCIE (12) +#define NDDS_TRANSPORT_CLASSID_ITP (13) + + /* Utilities to add elements to the protocol tree for packet-rtps.h and packet-rtps2.h */ extern guint16 rtps_util_add_protocol_version(proto_tree *tree, tvbuff_t* tvb, gint offset); extern guint16 rtps_util_add_vendor_id(proto_tree *tree, tvbuff_t * tvb, gint offset); |