diff --git a/monitor/control.c b/monitor/control.c
index 10e8b7f..00a60bc 100644
--- a/monitor/control.c
+++ b/monitor/control.c
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];
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;
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);
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;
}
}
return -1;
}
+ if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)) < 0) {
+ perror("Failed to enable credentials");
+ close(fd);
+ return -1;
+ }
+
return fd;
}
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;
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 e910c5e..bef1338 100644
--- a/monitor/hcidump.c
+++ b/monitor/hcidump.c
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 e4bb635..678993e 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
#include <inttypes.h>
#include <time.h>
#include <sys/time.h>
+#include <sys/socket.h>
#include "lib/bluetooth.h"
#include "lib/hci.h"
#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)
{
}
}
-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)
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;
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)
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;
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);
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);
}
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);
}
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:
}
}
-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;
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;
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) {
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;
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;
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) {
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);
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;
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);
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);
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;
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 fb64cc6..59da5af 100644
--- a/monitor/packet.h
+++ b/monitor/packet.h
#include <stdint.h>
#include <stdbool.h>
#include <sys/time.h>
+#include <sys/socket.h>
#define PACKET_FILTER_SHOW_INDEX (1 << 0)
#define PACKET_FILTER_SHOW_DATE (1 << 1)
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);
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);