Diff between 2cdea86e270d6a6bc9e88ac0aefde39185a3f92b and b133254dc1c782eedbeca0d3e89520211b909f24

Changed Files

File Additions Deletions Status
monitor/control.c +20 -5 modified
monitor/hcidump.c +6 -4 modified
monitor/packet.c +38 -34 modified
monitor/packet.h +11 -8 modified

Full Patch

diff --git a/monitor/control.c b/monitor/control.c
index 10e8b7f..00a60bc 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 e910c5e..bef1338 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 e4bb635..678993e 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -36,6 +36,7 @@
 #include <inttypes.h>
 #include <time.h>
 #include <sys/time.h>
+#include <sys/socket.h>
 
 #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 fb64cc6..59da5af 100644
--- a/monitor/packet.h
+++ b/monitor/packet.h
@@ -25,6 +25,7 @@
 #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)
@@ -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);