Использование BPF с SOCK_DGRAM на Linux-машине

Можно ли фильтровать пакеты с помощью BPF на сокете дейтаграммы?

Когда я пытаюсь прикрепить фильтр, но я не получаю никаких пакетов, ошибок не возникает. Я скомпилировал фильтр с помощью libpcap, а фильтр работает с tcpdump.

Вот сокращенная версия моего кода:

static const char filter[] = "udp[8] == 0x00";
int sock = socket(AF_INET, SOCK_DGRAM, 0);
pcap_t *pcap = pcap_open_dead(DLT_RAW, 1024);
struct bpf_program bpf_prog;
pcap_compile(pcap, &bpf_prog, filter, 0, PCAP_NETMASK_UNKNOWN);
struct sock_fprog linux_bpf = {
    .len = bpf_prog.bf_len,
    .filter = (struct sock_filter *) bpf_prog.bf_insns,
};
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &linux_bpf, sizeof(linux_bpf));

Моя машина - ubuntu 12.04 x86.


person nans    schedule 01.07.2014    source источник
comment
потому что это имя в linux   -  person nans    schedule 02.07.2014


Ответы (1)


Что ж, после некоторых тестов и испытаний это возможно. однако libpcap не поддерживает его напрямую.

что нужно сделать, это открыть обработчик pcap, определяющий тип данных ethernet, а затем получить доступ к байтам в пакете udp, как если бы вы обращались к пакету ethernet. смещения фильтра начинаются с начала пакета, но «пакет» зависит от уровня, для которого вы открыли сокет. если открыть сокет с SOCK_DGRAM, инструкция bpf ldb 0 загрузит первый байт заголовка udp. поэтому при доступе к ether[0] в фильтре libpcap скомпилирует его в ldb 0, что мы и хотим.

Итак, исправленный код должен быть примерно таким:

static const char filter[] = "ether[8] == 0x00";
int sock = socket(AF_INET, SOCK_DGRAM, 0);
pcap_t *pcap = pcap_open_dead(DLT_EN10MB, 1024);
struct bpf_program bpf_prog;
pcap_compile(pcap, &bpf_prog, filter, 0, PCAP_NETMASK_UNKNOWN);
struct sock_fprog linux_bpf = {
    .len = bpf_prog.bf_len,
    .filter = (struct sock_filter *) bpf_prog.bf_insns,
};
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &linux_bpf, sizeof(linux_bpf));
person nans    schedule 02.07.2014