diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2018-07-19 16:58:02 +0300 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2018-07-19 17:03:55 +0300 |
commit | 390b93f90189917addc4e9c0a5670f1fe797e7ba (patch) | |
tree | 68a0dd7ed05ea7868735b530af1a4c96e968bf59 /monitor/control.c | |
parent | 0a080597220a1233edd71601682263b3faa931dc (diff) | |
download | bluez-390b93f90189917addc4e9c0a5670f1fe797e7ba.tar.gz |
monitor: Use BPF to filter packets by index
This uses a BPF filter to filter packets to specific index.
Diffstat (limited to 'monitor/control.c')
-rw-r--r-- | monitor/control.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/monitor/control.c b/monitor/control.c index 150bdcc44..991dea1c3 100644 --- a/monitor/control.c +++ b/monitor/control.c @@ -28,6 +28,7 @@ #include <stdio.h> #include <stdbool.h> +#include <stddef.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> @@ -39,6 +40,7 @@ #include <sys/stat.h> #include <termios.h> #include <fcntl.h> +#include <linux/filter.h> #include "lib/bluetooth.h" #include "lib/hci.h" @@ -58,6 +60,7 @@ 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; @@ -1028,6 +1031,37 @@ static int open_socket(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; @@ -1045,6 +1079,9 @@ static int open_channel(uint16_t channel) 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; @@ -1468,3 +1505,8 @@ void control_disable_decoding(void) { decode_control = false; } + +void control_filter_index(uint16_t index) +{ + filter_index = index; +} |