From b133254dc1c782eedbeca0d3e89520211b909f24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 30 Oct 2015 04:03:56 +0100 Subject: [PATCH] monitor: Add support for handling SCM_CREDENTIALS if present --- monitor/control.c | 25 ++++++++++++---- monitor/hcidump.c | 10 ++++--- monitor/packet.c | 72 +++++++++++++++++++++++++---------------------- monitor/packet.h | 19 +++++++------ 4 files changed, 75 insertions(+), 51 deletions(-) diff --git a/monitor/control.c b/monitor/control.c index 10e8b7f76..00a60bc2f 100644 --- a/monitor/control.c +++ b/monitor/control.c @@ -902,7 +902,7 @@ void control_message(uint16_t opcode, const void *data, uint16_t size) static void data_callback(int fd, uint32_t events, void *user_data) { struct control_data *data = user_data; - unsigned char control[32]; + unsigned char control[64]; struct mgmt_hdr hdr; struct msghdr msg; struct iovec iov[2]; @@ -927,6 +927,8 @@ static void data_callback(int fd, uint32_t events, void *user_data) struct cmsghdr *cmsg; struct timeval *tv = NULL; struct timeval ctv; + struct ucred *cred = NULL; + struct ucred ccred; uint16_t opcode, index, pktlen; ssize_t len; @@ -946,6 +948,11 @@ static void data_callback(int fd, uint32_t events, void *user_data) memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv)); tv = &ctv; } + + if (cmsg->cmsg_type == SCM_CREDENTIALS) { + memcpy(&ccred, CMSG_DATA(cmsg), sizeof(ccred)); + cred = &ccred; + } } opcode = le16_to_cpu(hdr.opcode); @@ -954,14 +961,16 @@ static void data_callback(int fd, uint32_t events, void *user_data) switch (data->channel) { case HCI_CHANNEL_CONTROL: - packet_control(tv, index, opcode, data->buf, pktlen); + packet_control(tv, cred, index, opcode, + data->buf, pktlen); break; case HCI_CHANNEL_MONITOR: btsnoop_write_hci(btsnoop_file, tv, index, opcode, data->buf, pktlen); ellisys_inject_hci(tv, index, opcode, data->buf, pktlen); - packet_monitor(tv, index, opcode, data->buf, pktlen); + packet_monitor(tv, cred, index, opcode, + data->buf, pktlen); break; } } @@ -1001,6 +1010,12 @@ static int open_socket(uint16_t channel) return -1; } + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)) < 0) { + perror("Failed to enable credentials"); + close(fd); + return -1; + } + return fd; } @@ -1051,7 +1066,7 @@ static void client_callback(int fd, uint32_t events, void *user_data) uint16_t opcode = le16_to_cpu(hdr->opcode); uint16_t index = le16_to_cpu(hdr->index); - packet_monitor(NULL, index, opcode, + packet_monitor(NULL, NULL, index, opcode, data->buf + MGMT_HDR_SIZE, pktlen); data->offset -= pktlen + MGMT_HDR_SIZE; @@ -1190,7 +1205,7 @@ void control_reader(const char *path) if (opcode == 0xffff) continue; - packet_monitor(&tv, index, opcode, buf, pktlen); + packet_monitor(&tv, NULL, index, opcode, buf, pktlen); ellisys_inject_hci(&tv, index, opcode, buf, pktlen); } break; diff --git a/monitor/hcidump.c b/monitor/hcidump.c index e910c5eca..bef1338f9 100644 --- a/monitor/hcidump.c +++ b/monitor/hcidump.c @@ -160,17 +160,19 @@ static void device_callback(int fd, uint32_t events, void *user_data) switch (buf[0]) { case HCI_COMMAND_PKT: - packet_hci_command(tv, data->index, buf + 1, len - 1); + packet_hci_command(tv, NULL, data->index, + buf + 1, len - 1); break; case HCI_EVENT_PKT: - packet_hci_event(tv, data->index, buf + 1, len - 1); + packet_hci_event(tv, NULL, data->index, + buf + 1, len - 1); break; case HCI_ACLDATA_PKT: - packet_hci_acldata(tv, data->index, !!dir, + packet_hci_acldata(tv, NULL, data->index, !!dir, buf + 1, len - 1); break; case HCI_SCODATA_PKT: - packet_hci_scodata(tv, data->index, !!dir, + packet_hci_scodata(tv, NULL, data->index, !!dir, buf + 1, len - 1); break; } diff --git a/monitor/packet.c b/monitor/packet.c index e4bb635e3..678993e9c 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "lib/bluetooth.h" #include "lib/hci.h" @@ -168,7 +169,8 @@ void packet_select_index(uint16_t index) #define print_space(x) printf("%*c", (x), ' '); -static void print_packet(struct timeval *tv, uint16_t index, char ident, +static void print_packet(struct timeval *tv, struct ucred *cred, + uint16_t index, char ident, const char *color, const char *label, const char *text, const char *extra) { @@ -3655,7 +3657,8 @@ void packet_hexdump(const unsigned char *buf, uint16_t len) } } -void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode, +void packet_control(struct timeval *tv, struct ucred *cred, + uint16_t index, uint16_t opcode, const void *data, uint16_t size) { if (index_filter && index_number != index) @@ -3680,7 +3683,8 @@ struct index_data { static struct index_data index_list[MAX_INDEX]; -void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode, +void packet_monitor(struct timeval *tv, struct ucred *cred, + uint16_t index, uint16_t opcode, const void *data, uint16_t size) { const struct btsnoop_opcode_new_index *ni; @@ -3718,22 +3722,22 @@ void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode, packet_del_index(tv, index, str); break; case BTSNOOP_OPCODE_COMMAND_PKT: - packet_hci_command(tv, index, data, size); + packet_hci_command(tv, cred, index, data, size); break; case BTSNOOP_OPCODE_EVENT_PKT: - packet_hci_event(tv, index, data, size); + packet_hci_event(tv, cred, index, data, size); break; case BTSNOOP_OPCODE_ACL_TX_PKT: - packet_hci_acldata(tv, index, false, data, size); + packet_hci_acldata(tv, cred, index, false, data, size); break; case BTSNOOP_OPCODE_ACL_RX_PKT: - packet_hci_acldata(tv, index, true, data, size); + packet_hci_acldata(tv, cred, index, true, data, size); break; case BTSNOOP_OPCODE_SCO_TX_PKT: - packet_hci_scodata(tv, index, false, data, size); + packet_hci_scodata(tv, cred, index, false, data, size); break; case BTSNOOP_OPCODE_SCO_RX_PKT: - packet_hci_scodata(tv, index, true, data, size); + packet_hci_scodata(tv, cred, index, true, data, size); break; case BTSNOOP_OPCODE_OPEN_INDEX: if (index < MAX_INDEX) @@ -3773,7 +3777,7 @@ void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode, break; default: sprintf(extra_str, "(code %d len %d)", opcode, size); - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Unknown packet", NULL, extra_str); packet_hexdump(data, size); break; @@ -3790,7 +3794,7 @@ void packet_simulator(struct timeval *tv, uint16_t frequency, sprintf(str, "%u MHz", frequency); - print_packet(tv, 0, '*', COLOR_PHY_PACKET, + print_packet(tv, NULL, 0, '*', COLOR_PHY_PACKET, "Physical packet:", NULL, str); ll_packet(frequency, data, size, false); @@ -8630,25 +8634,25 @@ void packet_new_index(struct timeval *tv, uint16_t index, const char *label, sprintf(details, "(%s,%s,%s)", hci_typetostr(type), hci_bustostr(bus), name); - print_packet(tv, index, '=', COLOR_NEW_INDEX, "New Index", + print_packet(tv, NULL, index, '=', COLOR_NEW_INDEX, "New Index", label, details); } void packet_del_index(struct timeval *tv, uint16_t index, const char *label) { - print_packet(tv, index, '=', COLOR_DEL_INDEX, "Delete Index", + print_packet(tv, NULL, index, '=', COLOR_DEL_INDEX, "Delete Index", label, NULL); } void packet_open_index(struct timeval *tv, uint16_t index, const char *label) { - print_packet(tv, index, '=', COLOR_OPEN_INDEX, "Open Index", + print_packet(tv, NULL, index, '=', COLOR_OPEN_INDEX, "Open Index", label, NULL); } void packet_close_index(struct timeval *tv, uint16_t index, const char *label) { - print_packet(tv, index, '=', COLOR_CLOSE_INDEX, "Close Index", + print_packet(tv, NULL, index, '=', COLOR_CLOSE_INDEX, "Close Index", label, NULL); } @@ -8659,7 +8663,7 @@ void packet_index_info(struct timeval *tv, uint16_t index, const char *label, sprintf(details, "(%s)", bt_compidtostr(manufacturer)); - print_packet(tv, index, '=', COLOR_INDEX_INFO, "Index Info", + print_packet(tv, NULL, index, '=', COLOR_INDEX_INFO, "Index Info", label, details); } @@ -8671,8 +8675,8 @@ void packet_vendor_diag(struct timeval *tv, uint16_t index, sprintf(extra_str, "(len %d)", size); - print_packet(tv, index, '=', COLOR_VENDOR_DIAG, "Vendor Diagnostic", - NULL, extra_str); + print_packet(tv, NULL, index, '=', COLOR_VENDOR_DIAG, + "Vendor Diagnostic", NULL, extra_str); switch (manufacturer) { case 15: @@ -8684,7 +8688,7 @@ void packet_vendor_diag(struct timeval *tv, uint16_t index, } } -void packet_hci_command(struct timeval *tv, uint16_t index, +void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index, const void *data, uint16_t size) { const hci_command_hdr *hdr = data; @@ -8699,7 +8703,7 @@ void packet_hci_command(struct timeval *tv, uint16_t index, if (size < HCI_COMMAND_HDR_SIZE) { sprintf(extra_str, "(len %d)", size); - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Malformed HCI Command packet", NULL, extra_str); packet_hexdump(data, size); return; @@ -8757,7 +8761,7 @@ void packet_hci_command(struct timeval *tv, uint16_t index, sprintf(extra_str, "(0x%2.2x|0x%4.4x) plen %d", ogf, ocf, hdr->plen); - print_packet(tv, index, '<', opcode_color, "HCI Command", + print_packet(tv, cred, index, '<', opcode_color, "HCI Command", opcode_str, extra_str); if (!opcode_data || !opcode_data->cmd_func) { @@ -8789,7 +8793,7 @@ void packet_hci_command(struct timeval *tv, uint16_t index, opcode_data->cmd_func(data, hdr->plen); } -void packet_hci_event(struct timeval *tv, uint16_t index, +void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index, const void *data, uint16_t size) { const hci_event_hdr *hdr = data; @@ -8800,7 +8804,7 @@ void packet_hci_event(struct timeval *tv, uint16_t index, if (size < HCI_EVENT_HDR_SIZE) { sprintf(extra_str, "(len %d)", size); - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Malformed HCI Event packet", NULL, extra_str); packet_hexdump(data, size); return; @@ -8829,7 +8833,7 @@ void packet_hci_event(struct timeval *tv, uint16_t index, sprintf(extra_str, "(0x%2.2x) plen %d", hdr->evt, hdr->plen); - print_packet(tv, index, '>', event_color, "HCI Event", + print_packet(tv, cred, index, '>', event_color, "HCI Event", event_str, extra_str); if (!event_data || !event_data->func) { @@ -8861,8 +8865,8 @@ void packet_hci_event(struct timeval *tv, uint16_t index, event_data->func(data, hdr->plen); } -void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, - const void *data, uint16_t size) +void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index, + bool in, const void *data, uint16_t size) { const struct bt_hci_acl_hdr *hdr = data; uint16_t handle = le16_to_cpu(hdr->handle); @@ -8872,10 +8876,10 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, if (size < sizeof(*hdr)) { if (in) - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Malformed ACL Data RX packet", NULL, NULL); else - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Malformed ACL Data TX packet", NULL, NULL); packet_hexdump(data, size); return; @@ -8887,7 +8891,7 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, sprintf(handle_str, "Handle %d", acl_handle(handle)); sprintf(extra_str, "flags 0x%2.2x dlen %d", flags, dlen); - print_packet(tv, index, in ? '>' : '<', COLOR_HCI_ACLDATA, + print_packet(tv, cred, index, in ? '>' : '<', COLOR_HCI_ACLDATA, in ? "ACL Data RX" : "ACL Data TX", handle_str, extra_str); @@ -8904,8 +8908,8 @@ void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, l2cap_packet(index, in, acl_handle(handle), flags, data, size); } -void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, - const void *data, uint16_t size) +void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index, + bool in, const void *data, uint16_t size) { const hci_sco_hdr *hdr = data; uint16_t handle = le16_to_cpu(hdr->handle); @@ -8914,10 +8918,10 @@ void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, if (size < HCI_SCO_HDR_SIZE) { if (in) - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Malformed SCO Data RX packet", NULL, NULL); else - print_packet(tv, index, '*', COLOR_ERROR, + print_packet(tv, cred, index, '*', COLOR_ERROR, "Malformed SCO Data TX packet", NULL, NULL); packet_hexdump(data, size); return; @@ -8929,7 +8933,7 @@ void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, sprintf(handle_str, "Handle %d", acl_handle(handle)); sprintf(extra_str, "flags 0x%2.2x dlen %d", flags, hdr->dlen); - print_packet(tv, index, in ? '>' : '<', COLOR_HCI_SCODATA, + print_packet(tv, cred, index, in ? '>' : '<', COLOR_HCI_SCODATA, in ? "SCO Data RX" : "SCO Data TX", handle_str, extra_str); diff --git a/monitor/packet.h b/monitor/packet.h index fb64cc61d..59da5af89 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -25,6 +25,7 @@ #include #include #include +#include #define PACKET_FILTER_SHOW_INDEX (1 << 0) #define PACKET_FILTER_SHOW_DATE (1 << 1) @@ -53,9 +54,11 @@ void packet_print_channel_map_ll(const uint8_t *map); void packet_print_io_capability(uint8_t capability); void packet_print_io_authentication(uint8_t authentication); -void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode, +void packet_control(struct timeval *tv, struct ucred *cred, + uint16_t index, uint16_t opcode, const void *data, uint16_t size); -void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode, +void packet_monitor(struct timeval *tv, struct ucred *cred, + uint16_t index, uint16_t opcode, const void *data, uint16_t size); void packet_simulator(struct timeval *tv, uint16_t frequency, const void *data, uint16_t size); @@ -71,13 +74,13 @@ void packet_vendor_diag(struct timeval *tv, uint16_t index, uint16_t manufacturer, const void *data, uint16_t size); -void packet_hci_command(struct timeval *tv, uint16_t index, +void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index, const void *data, uint16_t size); -void packet_hci_event(struct timeval *tv, uint16_t index, - const void *data, uint16_t size); -void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in, - const void *data, uint16_t size); -void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in, +void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index, const void *data, uint16_t size); +void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index, + bool in, const void *data, uint16_t size); +void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index, + bool in, const void *data, uint16_t size); void packet_todo(void); -- 2.47.3