4

Is it possible to filter packets using BPF on datagram socket?

No error occures when I try to attach a filter, but I don't receive any packet. I compiled a filter using libpcap, and the filter works with tcpdump.

Here is shortened version of my code:

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));

My machine is ubuntu 12.04 x86.

pchaigno
  • 11,313
  • 2
  • 29
  • 54
nans
  • 101
  • 4
  • because that's the name on [linux](https://www.kernel.org/doc/Documentation/networking/filter.txt) – nans Jul 02 '14 at 17:57

1 Answers1

6

well, after some tests and trials, it is possible. however, libpcap does not support it directly.

what should be done is open a pcap handler specifying ethernet data type, and then access the bytes in the udp packet as if you access the ethernet packet. the filter offsets start from the beginning of the packet, but the 'packet' depends on the layer you opened the socket for. if one opens socket with SOCK_DGRAM, the bpf instruction ldb 0 will load the first byte of the udp header. so when accessing ether[0] in the filter libpcap will compile it to ldb 0 which is what we want.

so, the corrected code should be something like this:

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));
nans
  • 101
  • 4