【发布时间】:2020-05-26 23:11:12
【问题描述】:
我是 ebpf 和 xdp 主题的新手,想学习它。我的问题是如何使用 ebpf 过滤器过滤特定有效负载匹配的数据包?例如,如果数据包的数据(有效负载)为 1234,则将其传递给网络堆栈,否则将阻止该数据包。我达到了有效载荷长度。例如,如果我想匹配消息有效负载长度,它可以正常工作,但是当我开始匹配有效负载字符时出现错误。这是我的代码:
int ret_val;
unsigned long payload_offset;
unsigned long payload_size;
const char *payload = "test";
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) <= data_end) {
struct iphdr *ip = data + sizeof(*eth);
if ((void*)ip + sizeof(*ip) <= data_end) {
if (ip->protocol == IPPROTO_UDP ) {
struct udphdr *udp = (void*)ip + sizeof(*ip);
if ((void*)udp + sizeof(*udp) <= data_end) {
if (udp->dest == ntohs(5005)) {
payload_offset = sizeof(struct udphdr);
payload_size = ntohs(udp->len) - sizeof(struct udphdr);
unsigned char *s = (unsigned char *)&payload_size;
if (ret_val == __builtin_memcmp(s,payload,4) == 0) {
return XDP_DROP;
}
}
}
}
}
}
错误已删除但无法比较有效负载...我正在从 python 套接字代码发送 UDP 消息。如果我比较有效载荷长度,它工作正常。
【问题讨论】:
-
尝试将
memcmp()替换为__builtin_memcmp()(如果您只需要比较两个字节,则将其完全删除,只需使用==)。如果它不起作用,提供更大的代码块会很有帮助。请注意,unsigned char *s=(unsigned char *)&payload_size;表示s指向保存有效负载大小的变量,这是您想要的吗?并且不确定您如何初始化payload。或者你如何检查长度。 -
ret_val == __builtin_memcmp(s,payload,4)看起来不正确,您可能需要一个=这里。关于代码风格,我会避免在if ()条件下进行比较,如果可以的话,我会更频繁地使用早期返回并避免嵌套所有ifs。 -
我尝试了 if (ret_val = __builtin_memcmp(s,payload,4) == 0) 但仍然无法匹配有效负载。
-
Good ol'
bpf_trace_printk()来拯救你,你必须调试你的程序:)。我会先查看*s和*payload中的内容,看看您是否满足了您的期望。如果没有完整的代码和观察到错误等,我不确定如何提供更多帮助。
标签: linux linux-kernel bpf xdp-bpf