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:
parent
034ac6dad9
commit
d5d635d7b7
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue