#include <stdio.h>
#include <stdbool.h>
+#include <stddef.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
+#include <linux/filter.h>
#include "lib/bluetooth.h"
#include "lib/hci.h"
static struct btsnoop *btsnoop_file = NULL;
static bool hcidump_fallback = false;
static bool decode_control = true;
+static uint16_t filter_index = HCI_DEV_NONE;
struct control_data {
uint16_t channel;
return fd;
}
+static void attach_index_filter(int fd, uint16_t index)
+{
+ struct sock_filter filters[] = {
+ /* Load MGMT index:
+ * A <- MGMT index
+ */
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS,
+ offsetof(struct mgmt_hdr, index)),
+ /* Accept if index is HCI_DEV_NONE:
+ * A == HCI_DEV_NONE
+ */
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, HCI_DEV_NONE, 0, 1),
+ /* return */
+ BPF_STMT(BPF_RET|BPF_K, 0x0fffffff), /* pass */
+ /* Accept if index match:
+ * A == index
+ */
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, index, 0, 1),
+ /* returns */
+ BPF_STMT(BPF_RET|BPF_K, 0x0fffffff), /* pass */
+ BPF_STMT(BPF_RET|BPF_K, 0), /* reject */
+ };
+ struct sock_fprog fprog = {
+ .len = sizeof(filters) / sizeof(filters[0]),
+ /* casting const away: */
+ .filter = filters,
+ };
+
+ setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
+}
+
static int open_channel(uint16_t channel)
{
struct control_data *data;
return -1;
}
+ if (filter_index != HCI_DEV_NONE)
+ attach_index_filter(data->fd, filter_index);
+
mainloop_add_fd(data->fd, EPOLLIN, data_callback, data, free_data);
return 0;
{
decode_control = false;
}
+
+void control_filter_index(uint16_t index)
+{
+ filter_index = index;
+}
static int priority_level = BTSNOOP_PRIORITY_INFO;
static unsigned long filter_mask = 0;
static bool index_filter = false;
-static uint16_t index_number = 0;
static uint16_t index_current = 0;
static uint16_t fallback_manufacturer = UNKNOWN_MANUFACTURER;
{
filter_mask &= ~PACKET_FILTER_SHOW_INDEX;
+ control_filter_index(index);
+
index_filter = true;
- index_number = index;
}
#define print_space(x) printf("%*c", (x), ' ');
uint16_t index, uint16_t opcode,
const void *data, uint16_t size)
{
- if (index_filter && index_number != index)
- return;
-
control_message(opcode, data, size);
}
const char *ident;
if (index != HCI_DEV_NONE) {
- if (index_filter && index_number != index)
- return;
index_current = index;
}