【问题标题】:Using BPF with SOCK_DGRAM on Linux machine在 Linux 机器上使用 BPF 和 SOCK_DGRAM
【发布时间】:2014-08-22 06:05:06
【问题描述】:

是否可以在数据报套接字上使用 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。

【问题讨论】:

  • 因为这是linux上的名字

标签: linux udp pcap bpf


【解决方案1】:

好吧,经过一些测试和试验,这是可能的。 但是,libpcap 不直接支持它。

应该做的是打开一个指定以太网数据类型的 pcap 处理程序,然后像访问以太网数据包一样访问 udp 数据包中的字节。 过滤器偏移量从数据包的开头开始,但“数据包”取决于您打开套接字的层。 如果使用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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    相关资源
    最近更新 更多