diff --git a/epan/dissectors/packet-rtps.c b/epan/dissectors/packet-rtps.c index be62d9fc2c..ce38b80b78 100644 --- a/epan/dissectors/packet-rtps.c +++ b/epan/dissectors/packet-rtps.c @@ -194,7 +194,6 @@ typedef enum { typedef struct _rtps_dissector_data { guint16 encapsulation_id; - gboolean info_displayed; /* Represents the position of a sample within a batch. Since the position can be 0, we use -1 as not valid (not a batch) */ gint position_in_batch; @@ -2651,6 +2650,9 @@ static int* const HEADER_EXTENSION_MASK_FLAGS[] = { #define RTPS_TCPMAP_DOMAIN_ID_KEY_STR "ParticipantGuid" #define RTPS_TCPMAP_DOMAIN_ID_PROTODATA_KEY 0 +/* Key for mapping the topic name in pinfo */ +#define RTPS_TOPIC_NAME_PROTODATA_KEY 1 + /* End of TCP get DomainId feature constants */ typedef struct _participant_info { @@ -3600,7 +3602,15 @@ static void append_status_info(packet_info *pinfo, } wmem_strbuf_append(buffer, ")"); col_append_str(pinfo->cinfo, COL_INFO, wmem_strbuf_get_str(buffer)); - } + /* DATA(w|r) have the topic information (PID_TOPIC_NAME) and it has been stored when parsed it */ + if (enable_topic_info && + (writer_id == ENTITYID_BUILTIN_SUBSCRIPTIONS_WRITER || writer_id == ENTITYID_BUILTIN_PUBLICATIONS_WRITER)) { + const gchar* topic_name = (const gchar*)p_get_proto_data(pinfo->pool, pinfo, proto_rtps, RTPS_TOPIC_NAME_PROTODATA_KEY); + if (topic_name != NULL) { + col_append_sep_str(pinfo->cinfo, COL_INFO, " -> ", topic_name); + } + } + } } /* *********************************************************************** */ @@ -6487,8 +6497,9 @@ static void rtps_util_format_typename(gchar * type_name, gchar ** output) { } -static void rtps_util_topic_info_add_tree(proto_tree *tree, tvbuff_t *tvb, +static const char* rtps_util_topic_info_add_tree(proto_tree *tree, tvbuff_t *tvb, gint offset, endpoint_guid * guid) { + const char* topic_name = NULL; if (enable_topic_info) { proto_tree * topic_info_tree; proto_item * ti; @@ -6500,6 +6511,7 @@ static void rtps_util_topic_info_add_tree(proto_tree *tree, tvbuff_t *tvb, const gchar* topic_information_text = (!is_builtin_type) ? "[Topic Information (from Discovery)]": "[Topic Information (BuiltIn type)]"; + topic_name = type_mapping_object->topic_name; topic_info_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_rtps_topic_info, NULL, topic_information_text); ti = proto_tree_add_string(topic_info_tree, hf_rtps_param_type_name, tvb, offset, 0, @@ -6507,7 +6519,7 @@ static void rtps_util_topic_info_add_tree(proto_tree *tree, tvbuff_t *tvb, proto_item_set_generated(ti); if (!is_builtin_type) { ti = proto_tree_add_string(topic_info_tree, hf_rtps_param_topic_name, tvb, offset, 0, - type_mapping_object->topic_name); + topic_name); proto_item_set_generated(ti); ti = proto_tree_add_uint(topic_info_tree, hf_rtps_dcps_publication_data_frame_number, tvb, 0, 0, type_mapping_object->dcps_publication_frame_number); @@ -6515,6 +6527,19 @@ static void rtps_util_topic_info_add_tree(proto_tree *tree, tvbuff_t *tvb, proto_item_set_generated(ti); } } + return topic_name; +} + +/* Adds the topic topic information to the tree and the topic name to the info column. + * Topic name will be added to the info column only if the topic information is stored + * in the "registry map". + * This is used when the packet doesn't contain the topic information (PID_TOPIC_INFORMATION) + */ +static void rtps_util_add_topic_info(proto_tree* tree, packet_info *pinfo,tvbuff_t* tvb, gint offset, endpoint_guid* guid) { + const char* topic_name = rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + if (enable_topic_info && topic_name != NULL) { + col_append_sep_str(pinfo->cinfo, COL_INFO, " -> ", topic_name); + } } @@ -6650,25 +6675,7 @@ gint rtps_util_dissect_encapsulation_options( return offset; } -static gboolean rtps_util_topic_info_add_column_info( - packet_info *pinfo, endpoint_guid * guid, - rtps_dissector_data * data) { - gboolean added = FALSE; - if (enable_topic_info) { - type_mapping * type_mapping_object = rtps_util_get_topic_info(guid); - - /* This part shows information available for the sample */ - if (data && !(data->info_displayed) && (type_mapping_object != NULL)) { - col_append_sep_str(pinfo->cinfo, COL_INFO, " -> ", type_mapping_object->topic_name); - data->info_displayed = TRUE; - added = TRUE; - } - } - /* Return false so the content is dissected by the codepath following this one */ - return added; -} - -static gboolean rtps_util_topic_info_add_column_info_and_try_dissector(proto_tree *tree, +static gboolean rtps_util_try_dissector(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, endpoint_guid * guid, rtps_dissector_data * data, guint encoding, guint encoding_version, gboolean try_dissection_from_type_object) { @@ -6680,14 +6687,6 @@ static gboolean rtps_util_topic_info_add_column_info_and_try_dissector(proto_tre tvbuff_t *next_tvb; dissection_info* info = NULL; - rtps_util_topic_info_add_column_info(pinfo, guid, data); - /* This part shows information available for the sample - if (data && !(data->info_displayed)) { - col_append_sep_str(pinfo->cinfo, COL_INFO, " -> ", type_mapping_object->topic_name); - data->info_displayed = TRUE; - } - */ - if (try_dissection_from_type_object && enable_user_data_dissection) { info = lookup_dissection_info_in_custom_and_builtin_types(type_mapping_object->type_id); if (info != NULL) { @@ -7825,11 +7824,15 @@ static gboolean dissect_parameter_sequence_v1(proto_tree *rtps_parameter_tree, p guint32 str_size = tvb_get_guint32(tvb, offset, encoding); retVal = (gchar*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, str_size, ENC_ASCII); - - rtps_util_store_type_mapping(pinfo, 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, encoding); + /* If topic information is enabled we have to store the topic name for showing after the DATA(r|w) + * in the infor column. This information is used in append_status_info function. + */ + if (retVal != NULL && enable_topic_info) { + rtps_util_store_type_mapping(pinfo, tvb, offset, type_mapping_object, retVal, TOPIC_INFO_ADD_TOPIC_NAME); + /* retVal has packet scope lifetime, enough for adding to the DATA(r|w) column information */ + p_add_proto_data(pinfo->pool, pinfo, proto_rtps, RTPS_TOPIC_NAME_PROTODATA_KEY, (gpointer)retVal); + } break; } @@ -9442,8 +9445,7 @@ static void dissect_APP_ACK_CONF(tvbuff_t *tvb, offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); - + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* virtualWriterCount */ proto_tree_add_item_ret_uint(tree, hf_rtps_param_app_ack_conf_virtual_writer_count, tvb, offset, 4, @@ -9836,7 +9838,6 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff gboolean uncompressed_ok = FALSE; proto_tree *compressed_subtree = NULL; - data->info_displayed = FALSE; data->encapsulation_id = 0; data->position_in_batch = -1; /* Creates the sub-tree */ @@ -9901,7 +9902,7 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff * tvb if it is not decompressed. * Only try to dissect the user data if it is not compressed or it is compressed and correctly uncompressed */ if (is_compressed == uncompressed_ok) { - if (rtps_util_topic_info_add_column_info_and_try_dissector(dissected_data_holdeer_tree, + if (rtps_util_try_dissector(dissected_data_holdeer_tree, pinfo, data_holder_tvb, offset, guid, data, encapsulation_encoding, get_encapsulation_version(encapsulation_id), try_dissection_from_type_object)) { return; @@ -9941,9 +9942,6 @@ static void dissect_serialized_data(proto_tree *tree, packet_info *pinfo, tvbuff proto_tree_add_item(dissected_data_holdeer_tree, hf_rtps_data_serialize_data, tvb, offset, size, ENC_NA); } - } else { - /* If uncompression fails we still need toadd the topic name to the column */ - rtps_util_topic_info_add_column_info(pinfo, guid, data); } } } @@ -10013,7 +10011,7 @@ static void dissect_APP_ACK(tvbuff_t *tvb, &wid); offset += 4; guid->entity_id = wid; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* writerEntityId */ rtps_util_add_entity_id(tree, @@ -10432,7 +10430,7 @@ static void dissect_DATA_v2(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* Sequence number */ rtps_util_add_seq_number(tree, tvb, offset, encoding, "writerSeqNumber"); @@ -10656,7 +10654,7 @@ static void dissect_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* Sequence number */ rtps_util_add_seq_number(tree, tvb, offset, encoding, "writerSeqNumber"); @@ -11011,10 +11009,9 @@ static void dissect_ACKNACK(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin gint original_offset; /* Offset to the readerEntityId */ proto_item *octet_item; guint32 wid; + proto_tree_add_bitmask_value(tree, tvb, offset + 1, hf_rtps_sm_flags, ett_rtps_flags, ACKNACK_FLAGS, flags); - octet_item = proto_tree_add_item(tree, hf_rtps_sm_octets_to_next_header, tvb, offset + 2, 2, encoding); - if (octets_to_next_header < 20) { expert_add_info_format(pinfo, octet_item, &ei_rtps_sm_octets_to_next_header_error, "(Error: should be >= 20)"); return; @@ -11034,7 +11031,7 @@ static void dissect_ACKNACK(tvbuff_t *tvb, packet_info *pinfo, gint offset, guin offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* Bitmap */ offset = rtps_util_add_bitmap(tree, tvb, offset, encoding, "readerSNState", TRUE); @@ -11207,7 +11204,7 @@ static void dissect_HEARTBEAT(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* First available Sequence Number */ rtps_util_add_seq_number(tree, tvb, offset, encoding, "firstAvailableSeqNumber"); @@ -11287,7 +11284,7 @@ static void dissect_HEARTBEAT_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* First available Batch Sequence Number */ rtps_util_add_seq_number(tree, tvb, offset, encoding, "firstBatchSN"); @@ -11429,7 +11426,7 @@ static void dissect_HEARTBEAT_VIRTUAL(tvbuff_t *tvb, packet_info *pinfo _U_, gin offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* virtualGUID */ if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V) && !(flags & FLAG_VIRTUAL_HEARTBEAT_N)) { @@ -11631,7 +11628,7 @@ static void dissect_HEARTBEAT_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offse offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* First available Sequence Number */ rtps_util_add_seq_number(tree, tvb, offset, encoding, "writerSeqNumber"); @@ -11754,7 +11751,7 @@ static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, gu offset += 4; guid->entity_id = writer_wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* Sequence number */ if (is_session) { @@ -12131,7 +12128,7 @@ static void dissect_RTPS_DATA_FRAG_kind(tvbuff_t *tvb, packet_info *pinfo, gint offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* Sequence number */ @@ -12343,7 +12340,6 @@ static void dissect_RTPS_DATA_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs data = wmem_new(wmem_packet_scope(), rtps_dissector_data); - data->info_displayed = FALSE; data->encapsulation_id = 0; proto_tree_add_bitmask_value(tree, tvb, offset + 1, hf_rtps_sm_flags, ett_rtps_flags, RTPS_DATA_BATCH_FLAGS, flags); @@ -12382,7 +12378,7 @@ static void dissect_RTPS_DATA_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* Batch sequence number */ @@ -12573,7 +12569,7 @@ static void dissect_RTPS_DATA_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs proto_tree_add_bytes_format(sil_tree, hf_rtps_serialized_key, data_holder_tvb, offset, sample_info_length[count], NULL, "serializedKey[%d]", count); } else { - if (!rtps_util_topic_info_add_column_info_and_try_dissector( + if (!rtps_util_try_dissector( sil_tree, pinfo, data_holder_tvb, offset, guid, data, get_encapsulation_endianness(encapsulation_id), get_encapsulation_version(encapsulation_id), try_dissection_from_type_object)) { proto_tree_add_bytes_format(sil_tree, hf_rtps_serialized_data, data_holder_tvb, offset, sample_info_length[count], NULL, "serializedData[%d]", count); @@ -12582,9 +12578,6 @@ static void dissect_RTPS_DATA_BATCH(tvbuff_t *tvb, packet_info *pinfo, gint offs offset += sample_info_length[count]; } } - } else { - /* If uncompression went wrong still need to add the topic column info */ - rtps_util_topic_info_add_column_info(pinfo, guid, data); } append_status_info(pinfo, wid, status_info); } @@ -12658,7 +12651,7 @@ static void dissect_GAP(tvbuff_t *tvb, packet_info *pinfo, gint offset, offset += 4; guid->entity_id = wid; guid->fields_present |= GUID_HAS_ENTITY_ID; - rtps_util_topic_info_add_tree(tree, tvb, offset, guid); + rtps_util_add_topic_info(tree, pinfo, tvb, offset, guid); /* First Sequence Number */