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.
This commit is contained in:
Simon Holesch 2021-12-26 00:21:59 +01:00 committed by AndersBroman
parent 034ac6dad9
commit d5d635d7b7
1 changed files with 66 additions and 0 deletions

View File

@ -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