From d5d635d7b7d8235b742dadcbc4d4e33f8eab033f Mon Sep 17 00:00:00 2001 From: Simon Holesch Date: Sun, 26 Dec 2021 00:21:59 +0100 Subject: D-Bus: Resolve unique names into well-known names Use the information gained from conversation tracking to infer well-known names. Show well-known names as addresses to improve the readability of a D-Bus capture. --- epan/dissectors/packet-dbus.c | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'epan/dissectors/packet-dbus.c') diff --git a/epan/dissectors/packet-dbus.c b/epan/dissectors/packet-dbus.c index da8d4ef6ad..84f5ae0d0c 100644 --- a/epan/dissectors/packet-dbus.c +++ b/epan/dissectors/packet-dbus.c @@ -53,6 +53,7 @@ void proto_reg_handoff_dbus(void); static int proto_dbus = -1; static gboolean dbus_desegment = TRUE; +static gboolean dbus_resolve_names = TRUE; static dissector_handle_t dbus_handle; static dissector_handle_t dbus_handle_tcp; @@ -250,6 +251,7 @@ typedef struct { } dbus_conv_info_t; static wmem_map_t *request_info_map; +static wmem_map_t *unique_name_map; static gboolean is_ascii_digit(char c) { @@ -945,6 +947,32 @@ dissect_dbus_body(dbus_packet_t *packet) { return err; } +static void +update_unique_name_map(const gchar *name1, const gchar *name2) { + const gchar *unique_name; + const gchar *well_known_name; + + if (!dbus_resolve_names) { + return; + } + + if (name1[0] == ':' && name2[0] != ':') { + unique_name = name1; + well_known_name = name2; + } else if (name2[0] == ':' && name1[0] != ':') { + unique_name = name2; + well_known_name = name1; + } else { + // both are well-known or both are unique names + return; + } + if (!wmem_map_contains(unique_name_map, unique_name)) { + wmem_map_insert(unique_name_map, + wmem_strdup(wmem_file_scope(), unique_name), + wmem_strdup(wmem_file_scope(), well_known_name)); + } +} + static void add_conversation(dbus_packet_t *packet, proto_tree *header_field_tree) { gboolean is_request; @@ -994,6 +1022,10 @@ add_conversation(dbus_packet_t *packet, proto_tree *header_field_tree) { conversation_create_endpoint(packet->pinfo, &sender_addr, &packet->pinfo->dst, conversation_pt_to_endpoint_type(packet->pinfo->ptype), packet->pinfo->srcport, packet->pinfo->destport); + + if (!PINFO_FD_VISITED(packet->pinfo) && packet->message_type == DBUS_MESSAGE_TYPE_METHOD_RETURN) { + update_unique_name_map(request_dest, packet->sender); + } } break; case DBUS_MESSAGE_TYPE_SIGNAL: @@ -1067,6 +1099,30 @@ add_conversation(dbus_packet_t *packet, proto_tree *header_field_tree) { } } +void +resolve_unique_name(dbus_packet_t *packet, proto_tree *header_field_tree) { + proto_item *it; + tvbuff_t *tvb = ptvcursor_tvbuff(packet->cursor); + + if (packet->sender) { + const gchar *sender_well_known = (const gchar *)wmem_map_lookup(unique_name_map, packet->sender); + if (sender_well_known) { + set_address(&packet->pinfo->src, AT_STRINGZ, (int)strlen(sender_well_known)+1, sender_well_known); + it = proto_tree_add_string(header_field_tree, hf_dbus_sender, tvb, 0, 0, sender_well_known); + proto_item_set_generated(it); + } + } + + if (packet->destination) { + const gchar *destination_well_known = (const gchar *)wmem_map_lookup(unique_name_map, packet->destination); + if (destination_well_known) { + set_address(&packet->pinfo->dst, AT_STRINGZ, (int)strlen(destination_well_known)+1, destination_well_known); + it = proto_tree_add_string(header_field_tree, hf_dbus_destination, tvb, 0, 0, destination_well_known); + proto_item_set_generated(it); + } + } +} + static int dissect_dbus_header_fields(dbus_packet_t *packet) { dbus_type_reader_t root_reader = { @@ -1237,6 +1293,9 @@ dissect_dbus_header_fields(dbus_packet_t *packet) { } add_conversation(packet, proto_item_get_subtree(header_field_array_pi)); + if (dbus_resolve_names) { + resolve_unique_name(packet, proto_item_get_subtree(header_field_array_pi)); + } switch(packet->message_type) { case DBUS_MESSAGE_TYPE_METHOD_CALL: @@ -1551,6 +1610,7 @@ proto_register_dbus(void) { }; expert_module_t *expert_dbus; + module_t *dbus_module; proto_dbus = proto_register_protocol("D-Bus", "D-Bus", "dbus"); proto_register_field_array(proto_dbus, hf, array_length(hf)); @@ -1561,7 +1621,13 @@ proto_register_dbus(void) { dbus_handle = create_dissector_handle(dissect_dbus, proto_dbus); dbus_handle_tcp = create_dissector_handle(dissect_dbus_tcp, proto_dbus); + dbus_module = prefs_register_protocol(proto_dbus, NULL); + prefs_register_bool_preference(dbus_module, "resolve_names", + "Resolve unique names into well-known names", + "Show the first inferred well-known bus name (e.g. \"com.example.MusicPlayer1\") instead of the unique connection name (e.g. \":1.18\"). Might be confusing if a connection owns more than one well-known name.", &dbus_resolve_names); + request_info_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), wmem_str_hash, g_str_equal); + unique_name_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), wmem_str_hash, g_str_equal); } void -- cgit v1.2.3