diff options
author | Juanjo Martin <juanjo@rti.com> | 2015-11-06 16:40:11 +0100 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2015-11-21 13:52:52 +0000 |
commit | 1df7c07326237e585e0fe87f8b1bd5ea05e5274a (patch) | |
tree | 3f4b8f1b0e9ff4d865f2cd49f0db062f45c073d7 /epan/dissectors/packet-rtps.c | |
parent | 67d9daa65b9d555ced9fb1a9df90b1f8f1a4a257 (diff) |
RTPS: Added Topic Information feature. This feature shows the Topic
Name and the Type Name of the sample by consulting a hash table
that relates GUIDs and this information.
This information is very useful to any analysis performed to RTPS
data. It can be disabled using a checkbox so it doesn't impact
performance when capturing (default = disabled).
Bug: 11729
Change-Id: Ic9fa3a777dfed3cb46166b8e7c9783a12c161e7d
Reviewed-on: https://code.wireshark.org/review/11602
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-rtps.c')
-rw-r--r-- | epan/dissectors/packet-rtps.c | 201 |
1 files changed, 172 insertions, 29 deletions
diff --git a/epan/dissectors/packet-rtps.c b/epan/dissectors/packet-rtps.c index 73946c7a8c..e275375a7e 100644 --- a/epan/dissectors/packet-rtps.c +++ b/epan/dissectors/packet-rtps.c @@ -373,6 +373,7 @@ static gint ett_rtps_app_ack_virtual_writer = -1; static gint ett_rtps_product_version = -1; static gint ett_rtps_property_list = -1; static gint ett_rtps_property = -1; +static gint ett_rtps_topic_info = -1; static expert_field ei_rtps_sm_octets_to_next_header_error = EI_INIT; static expert_field ei_rtps_port_invalid = EI_INIT; @@ -390,6 +391,7 @@ static expert_field ei_rtps_unsupported_non_builtin_param_seq = EI_INIT; /* Preferences */ /***************************************************************************/ static guint rtps_max_batch_samples_dissected = 16; +static gboolean enable_topic_info = FALSE; /***************************************************************************/ /* Value-to-String Tables */ @@ -1150,6 +1152,22 @@ static const int* NACK_FLAGS[] = { }; #endif +typedef struct _endpoint_guid { + guint32 host_id; + guint32 app_id; + guint32 instance_id; + guint32 entity_id; +} endpoint_guid; + +#define MAX_TOPIC_AND_TYPE_LENGTH 256 +typedef struct _type_mapping { + endpoint_guid guid; + gchar type_name[MAX_TOPIC_AND_TYPE_LENGTH]; + gchar topic_name[MAX_TOPIC_AND_TYPE_LENGTH]; + gint fields_visited; +} type_mapping; + +static wmem_map_t * registry = NULL; /***************************************************************************/ /* Inline macros */ @@ -2760,6 +2778,82 @@ static int rtps_util_add_fragment_number_set(proto_tree *tree, packet_info *pinf return offset; } +static void rtps_util_store_type_mapping(tvbuff_t *tvb, gint offset, + type_mapping * type_mapping_object, const gchar * value, + gint topic_info_add_id) { + if (enable_topic_info && type_mapping_object) { + switch (topic_info_add_id) { + case TOPIC_INFO_ADD_GUID: { + type_mapping_object->guid.host_id = tvb_get_ntohl(tvb, offset); + type_mapping_object->guid.app_id = tvb_get_ntohl(tvb, offset+4); + type_mapping_object->guid.instance_id = tvb_get_ntohl(tvb, offset+8); + type_mapping_object->guid.entity_id = tvb_get_ntohl(tvb, offset+12); + type_mapping_object->fields_visited = + type_mapping_object->fields_visited | TOPIC_INFO_ADD_GUID; + break; + } + case TOPIC_INFO_ADD_TOPIC_NAME: { + g_strlcpy(type_mapping_object->topic_name, value, MAX_TOPIC_AND_TYPE_LENGTH); + type_mapping_object->fields_visited = + type_mapping_object->fields_visited | TOPIC_INFO_ADD_TOPIC_NAME; + break; + } + case TOPIC_INFO_ADD_TYPE_NAME: { + g_strlcpy(type_mapping_object->type_name, value, MAX_TOPIC_AND_TYPE_LENGTH); + type_mapping_object->fields_visited = + type_mapping_object->fields_visited | TOPIC_INFO_ADD_TYPE_NAME; + break; + } + default: + break; + } + if ((type_mapping_object->fields_visited & TOPIC_INFO_ALL_SET) == TOPIC_INFO_ALL_SET && + !wmem_map_lookup(registry, &(type_mapping_object->guid))) { + if (((type_mapping_object->guid.entity_id & 0x02) == 0x02)){ + /* If it is an application defined writer matches 0x02 */ + wmem_map_insert(registry, &(type_mapping_object->guid), type_mapping_object); + } + } + } +} +guint hash_by_guid(gconstpointer key) { + endpoint_guid * guid = (endpoint_guid *) key; + return g_int_hash(&(guid->app_id)); +} + +gboolean compare_by_guid(gconstpointer a, gconstpointer b) { + endpoint_guid * guid_a = (endpoint_guid *) a; + endpoint_guid * guid_b = (endpoint_guid *) b; + return memcmp(guid_a, guid_b, sizeof(endpoint_guid)) == 0; +} + +static type_mapping * rtps_util_get_topic_info(endpoint_guid * guid) { + /* At this point, we know the boolean enable_topic_info is true */ + type_mapping * result = NULL; + if (guid) + result = (type_mapping *)wmem_map_lookup(registry, guid); + return result; +} + +static void rtps_util_show_topic_info(proto_tree *tree, tvbuff_t *tvb, + gint offset, endpoint_guid * guid) { + if (enable_topic_info && tree) { + type_mapping * type_mapping_object = rtps_util_get_topic_info(guid); + if (type_mapping_object != NULL) { + proto_tree * topic_info_tree; + proto_item * ti; + topic_info_tree = proto_tree_add_subtree(tree, tvb, offset, 0, + ett_rtps_topic_info, NULL, "[Topic Information (from Discovery)]"); + ti = proto_tree_add_string(topic_info_tree, hf_rtps_param_topic_name, tvb, offset, 0, + type_mapping_object->topic_name); + PROTO_ITEM_SET_GENERATED(ti); + ti = proto_tree_add_string(topic_info_tree, hf_rtps_param_type_name, tvb, offset, 0, + type_mapping_object->type_name); + PROTO_ITEM_SET_GENERATED(ti); + } + } +} + /* *********************************************************************** */ /* * Parameter Sequence dissector * */ /* *********************************************************************** */ @@ -2780,12 +2874,10 @@ static int rtps_util_add_fragment_number_set(proto_tree *tree, packet_info *pinf 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) { + gboolean little_endian, int param_length, guint16 parameter) { switch(parameter) { - /* 0...2...........7...............15.............23...............31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | PID_DEFAULT_MULTICAST_LOCATOR | 0x0018 | @@ -3173,7 +3265,7 @@ static gboolean dissect_parameter_sequence_toc(proto_tree *rtps_parameter_tree, 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, - guint16 parameter, guint16 version) { + guint16 parameter, guint16 version, type_mapping * type_mapping_object) { proto_tree *subtree; switch(parameter) { @@ -3220,10 +3312,17 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p * | ... | * +---------------+---------------+---------------+---------------+ */ - case PID_TOPIC_NAME: + case PID_TOPIC_NAME: { + const gchar * retVal = NULL; + guint32 str_size = NEXT_guint32(tvb, offset, little_endian); + + retVal = (gchar*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, str_size, ENC_ASCII); + + rtps_util_store_type_mapping(tvb, offset, type_mapping_object, retVal, TOPIC_INFO_ADD_TOPIC_NAME); + rtps_util_add_string(rtps_parameter_tree, tvb, offset, hf_rtps_param_topic_name, little_endian); break; - + } /* 0...2...........7...............15.............23...............31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -3249,9 +3348,17 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p * | ... | * +---------------+---------------+---------------+---------------+ */ - case PID_TYPE_NAME: + case PID_TYPE_NAME: { + const gchar * retVal = NULL; + guint32 str_size = NEXT_guint32(tvb, offset, little_endian); + + retVal = (gchar*) tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, str_size, ENC_ASCII); + + rtps_util_store_type_mapping(tvb, offset, type_mapping_object, retVal, TOPIC_INFO_ADD_TYPE_NAME); + rtps_util_add_string(rtps_parameter_tree, tvb, offset, hf_rtps_param_type_name, little_endian); break; + } /* 0...2...........7...............15.............23...............31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -4124,7 +4231,8 @@ 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 _U_, proto_item *param_len_item, gint offset, gboolean little_endian, int param_length, - guint16 parameter, guint32 *pStatusInfo, guint16 vendor_id _U_) { + guint16 parameter, guint32 *pStatusInfo, guint16 vendor_id _U_, + type_mapping * type_mapping_object) { proto_item *ti; switch(parameter) { @@ -4347,6 +4455,7 @@ static gboolean dissect_parameter_sequence_v2(proto_tree *rtps_parameter_tree, p */ case PID_ENDPOINT_GUID: ENSURE_LENGTH(16); + rtps_util_store_type_mapping(tvb, offset, type_mapping_object, NULL, TOPIC_INFO_ADD_GUID); rtps_util_add_generic_guid_v2(rtps_parameter_tree, tvb, offset, hf_rtps_endpoint_guid, hf_rtps_param_host_id, hf_rtps_param_app_id, hf_rtps_param_instance_id, hf_rtps_param_app_kind, hf_rtps_param_counter, @@ -4370,6 +4479,10 @@ static gint dissect_parameter_sequence(proto_tree *tree, packet_info *pinfo, tvb guint16 parameter, param_length; gint original_offset = offset; gboolean dissect_return_value = FALSE; + type_mapping * type_mapping_object = NULL; + + if (!pinfo->fd->flags.visited) + type_mapping_object = wmem_new(wmem_file_scope(), type_mapping); rtps_parameter_sequence_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_rtps_parameter_sequence, &ti, "%s:", label); @@ -4442,11 +4555,11 @@ static gint dissect_parameter_sequence(proto_tree *tree, packet_info *pinfo, tvb 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)) { + offset, little_endian, size, param_length, parameter, version, type_mapping_object)) { 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)) { + pStatusInfo, vendor_id, type_mapping_object)) { if (param_length > 0) { proto_tree_add_item(rtps_parameter_tree, hf_rtps_parameter_data, tvb, offset, param_length, ENC_NA); @@ -4614,7 +4727,8 @@ static void dissect_APP_ACK_CONF(tvbuff_t *tvb, * 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, gboolean is_discovery_data) { + int size, const char *label, guint16 vendor_id, gboolean is_discovery_data, + endpoint_guid * guid) { proto_item *ti; proto_tree *rtps_parameter_sequence_tree; guint16 encapsulation_id; @@ -4623,6 +4737,9 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff /* Creates the sub-tree */ rtps_parameter_sequence_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_rtps_serialized_data, &ti, label); + /* Add Topic Information if enabled (checked inside)*/ + rtps_util_show_topic_info(rtps_parameter_sequence_tree, tvb, offset, guid); + /* Encapsulation ID */ 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); @@ -4658,7 +4775,7 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff break; default: - proto_tree_add_item(rtps_parameter_sequence_tree, hf_rtps_data_serialize_data, tvb, + proto_tree_add_item(rtps_parameter_sequence_tree, hf_rtps_data_serialize_data, tvb, offset, size, ENC_NA); } } @@ -4842,7 +4959,8 @@ static void dissect_APP_ACK(tvbuff_t *tvb, interval_payload_length, "payload", vendor_id, - FALSE /* from_builtin_writer */); + FALSE /* from_builtin_writer */, + NULL /* guid pointer */); offset += interval_payload_length; } @@ -5086,7 +5204,7 @@ static void dissect_DATA_v1(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin static void dissect_DATA_v2(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, gboolean little_endian, int octets_to_next_header, proto_tree *tree, - guint16 vendor_id) { + guint16 vendor_id, endpoint_guid *guid) { /* * * 0...2...........7...............15.............23...............31 @@ -5193,9 +5311,10 @@ static void dissect_DATA_v2(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin if ((flags & FLAG_DATA_D_v2) != 0) { from_builtin_writer = (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; + guid->entity_id = wid; dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - "serializedData", vendor_id, from_builtin_writer); + "serializedData", vendor_id, from_builtin_writer, guid); } info_summary_append_ex(pinfo, wid, status_info); } @@ -5323,7 +5442,7 @@ static void dissect_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu (((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, from_builtin_writer); + "serializedData", vendor_id, from_builtin_writer, NULL); } } @@ -5460,7 +5579,7 @@ static void dissect_NOKEY_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, g (((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, from_builtin_writer); + "serializedData", vendor_id, from_builtin_writer, NULL); } } @@ -5563,7 +5682,7 @@ static void dissect_NOKEY_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offs (((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, from_builtin_writer); + "serializedData", vendor_id, from_builtin_writer, NULL); } } @@ -6263,7 +6382,7 @@ static void dissect_HEARTBEAT_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offse /* *********************************************************************** */ static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, gboolean little_endian, int octets_to_next_header, proto_tree *tree, - guint16 vendor_id, gboolean is_session) { + guint16 vendor_id, gboolean is_session, endpoint_guid * guid) { /* * * 0...2...........7...............15.............23...............31 @@ -6448,11 +6567,11 @@ static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu from_builtin_writer = (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE; - + guid->entity_id = wid; /* 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, from_builtin_writer); + label, vendor_id, from_builtin_writer, guid); } } @@ -6581,7 +6700,7 @@ static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offse dissect_serialized_data(tree, pinfo, tvb, offset, octets_to_next_header - (offset - old_offset) + 4, - label, vendor_id, from_builtin_writer); + label, vendor_id, from_builtin_writer, NULL); } info_summary_append_ex(pinfo, wid, status_info); } @@ -7279,7 +7398,8 @@ static void dissect_INFO_REPLY(tvbuff_t *tvb, packet_info *pinfo, gint offset, g static gboolean dissect_rtps_submessage_v2(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, gboolean little_endian, guint8 submessageId, guint16 vendor_id, gint octets_to_next_header, - proto_tree *rtps_submessage_tree, proto_item *submessage_item) + proto_tree *rtps_submessage_tree, proto_item *submessage_item, + endpoint_guid * guid) { switch (submessageId) { @@ -7324,7 +7444,7 @@ static gboolean dissect_rtps_submessage_v2(tvbuff_t *tvb, packet_info *pinfo, gi 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)); + rtps_submessage_tree, vendor_id, (submessageId == SUBMESSAGE_RTPS_DATA_SESSION), guid); break; case SUBMESSAGE_RTPS_DATA_FRAG: @@ -7346,7 +7466,8 @@ static gboolean dissect_rtps_submessage_v2(tvbuff_t *tvb, packet_info *pinfo, gi static gboolean dissect_rtps_submessage_v1(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags, gboolean little_endian, guint8 submessageId, guint16 version, guint16 vendor_id, gint octets_to_next_header, - proto_tree *rtps_submessage_tree, proto_item *submessage_item) + proto_tree *rtps_submessage_tree, proto_item *submessage_item, + endpoint_guid * guid) { switch (submessageId) { @@ -7356,9 +7477,11 @@ static gboolean dissect_rtps_submessage_v1(tvbuff_t *tvb, packet_info *pinfo, gi case SUBMESSAGE_DATA: if (version < 0x0200) { - dissect_DATA_v1(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree); + dissect_DATA_v1(tvb, pinfo, offset, flags, little_endian, + octets_to_next_header, rtps_submessage_tree); } else { - dissect_DATA_v2(tvb, pinfo, offset, flags, little_endian, octets_to_next_header, rtps_submessage_tree, vendor_id); + dissect_DATA_v2(tvb, pinfo, offset, flags, little_endian, + octets_to_next_header, rtps_submessage_tree, vendor_id, guid); } break; @@ -7419,6 +7542,7 @@ static gboolean dissect_rtps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree gint next_submsg, octets_to_next_header; int sub_hf; const value_string *sub_vals; + endpoint_guid guid; /* Check 'RTPS' signature: * A header is invalid if it has less than 16 octets @@ -7459,6 +7583,10 @@ static gboolean dissect_rtps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree rtps_util_add_guid_prefix_v2(rtps_tree, tvb, offset+8, hf_rtps_guid_prefix, hf_rtps_host_id, hf_rtps_app_id, hf_rtps_sm_counter, NULL); + guid.host_id = tvb_get_ntohl(tvb, offset+8); + guid.app_id = tvb_get_ntohl(tvb, offset+12); + guid.instance_id = tvb_get_ntohl(tvb, offset+16); + #ifdef RTI_BUILD pinfo->guid_prefix_host = tvb_get_ntohl(tvb, offset + 8); pinfo->guid_prefix_app = tvb_get_ntohl(tvb, offset + 12); @@ -7598,10 +7726,10 @@ static gboolean dissect_rtps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree */ if (!dissect_rtps_submessage_v1(tvb, pinfo, offset, flags, little_endian, submessageId, version, vendor_id, - octets_to_next_header, rtps_submessage_tree, ti)) { + octets_to_next_header, rtps_submessage_tree, ti, &guid)) { if ((version < 0x0200) || !dissect_rtps_submessage_v2(tvb, pinfo, offset, flags, little_endian, submessageId, - vendor_id, octets_to_next_header, rtps_submessage_tree, ti)) { + vendor_id, octets_to_next_header, rtps_submessage_tree, ti, &guid)) { proto_tree_add_uint(rtps_submessage_tree, hf_rtps_sm_flags, tvb, offset + 1, 1, flags); proto_tree_add_uint(rtps_submessage_tree, @@ -7638,6 +7766,13 @@ static gboolean dissect_rtps_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree * return dissect_rtps(tvb, pinfo, tree, offset); } +static void +rtps_init(void) +{ + if (enable_topic_info) + registry = wmem_map_new(wmem_file_scope(), hash_by_guid, compare_by_guid); +} + void proto_register_rtps(void) { static hf_register_info hf[] = { @@ -9282,6 +9417,7 @@ void proto_register_rtps(void) { &ett_rtps_transport_info, &ett_rtps_property_list, &ett_rtps_property, + &ett_rtps_topic_info, }; static ei_register_info ei[] = { @@ -9318,6 +9454,13 @@ void proto_register_rtps(void) { "a DATA_BATCH submessage. Increasing this value may affect " "performances if the trace has a lot of big batched samples.", 10, &rtps_max_batch_samples_dissected); + + prefs_register_bool_preference(rtps_module, "enable_topic_info", + "Enable Topic Information feature", + "Shows the Topic Name and Type Name of the samples.", + &enable_topic_info); + register_init_routine(rtps_init); + } |