summaryrefslogtreecommitdiff
path: root/monitor/control.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-10-30 04:03:56 +0100
committerMarcel Holtmann <marcel@holtmann.org>2015-10-30 04:04:16 +0100
commitb133254dc1c782eedbeca0d3e89520211b909f24 (patch)
tree0492b88e6ef411d5982377e39285f6895ac7bfb3 /monitor/control.c
parent2cdea86e270d6a6bc9e88ac0aefde39185a3f92b (diff)
downloadbluez-b133254dc1c782eedbeca0d3e89520211b909f24.tar.gz
monitor: Add support for handling SCM_CREDENTIALS if present
Diffstat (limited to 'monitor/control.c')
-rw-r--r--monitor/control.c25
1 files changed, 20 insertions, 5 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;