gpt4 book ai didi

c - 为什么我使用带有 udp 套接字的 BPF 收不到任何数据包?

转载 作者:行者123 更新时间:2023-11-30 14:37:37 25 4
gpt4 key购买 nike

目标:编写一个 BPF 过滤器,仅允许来自特定 src 地址的 UDP 数据包并将其附加到 UDP 套接字。

问题:如果我执行程序并尝试从具有正确源 IP 的虚拟机发送 udp 数据包,我不会收到任何数据包

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#include <arpa/inet.h>
#include <linux/filter.h>

/* udp and src 192.168.56.101 */
struct sock_filter bpfcode[] = {
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 6, 0, 0x000086dd },
{ 0x15, 0, 5, 0x00000800 },
{ 0x30, 0, 0, 0x00000017 },
{ 0x15, 0, 3, 0x00000011 },
{ 0x20, 0, 0, 0x0000001a },
{ 0x15, 0, 1, 0xc0a83865 },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000000 },
};

int main(void)
{
struct sock_fprog bpf = {
sizeof(bpfcode) / sizeof(struct sock_filter),
bpfcode
};
struct sockaddr_in src = {
.sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY,
.sin_port = htons(1025)
};
char buf[1024];
ssize_t res;
int fd, ret;

fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
printf("error: socket\n");
exit(EXIT_FAILURE);
}

ret = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
if (ret < 0) {
perror("error: setsockopt\n");
close(fd);
exit(EXIT_FAILURE);
}

ret = bind(fd, (struct sockaddr *)&src, sizeof(src));
if (ret < 0) {
printf("error: bind\n");
close(fd);
exit(EXIT_FAILURE);
}

res = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0);
printf("res = %zi\n", res);

close(fd);

return 0;
}

最佳答案

评论中的讨论摘要:

首先,套接字的类型是 SOCK_DGRAM,因此您获取的数据从 L4 (UDP) 开始,而不是像过滤器期望的那样从 L2 开始。请改用 SOCK_RAW

然后,使用 SOCK_RAW 将使您能够访问 L3,而不是 L2(您需要为此更改套接字域)。所以你需要稍微调整你的过滤器:

    { 0x28, 0, 0, 0x0000000c }, // load Ethertype
{ 0x15, 6, 0, 0x000086dd }, // If IPv6 goto drop
{ 0x15, 0, 5, 0x00000800 }, // If not IPv4 (and not IPv6) goto drop
{ 0x30, 0, 0, 0x00000017 }, // Load IP protocol
{ 0x15, 0, 3, 0x00000011 }, // If not UDP goto drop
{ 0x20, 0, 0, 0x0000001a }, // Load src address
{ 0x15, 0, 1, 0xc0a83865 }, // If not 192.168.56.1.1 goto drop
{ 0x6, 0, 0, 0x00040000 }, // Pass packet
{ 0x6, 0, 0, 0x00000000 }, // Drop

应该成为(归功于自己修复它的OP:)):

    // UDP check is harmless but useless
// { 0x30, 0, 0, 0x00000009 }, // Note the offset update
// { 0x15, 0, 3, 0x00000011 },
{ 0x20, 0, 0, 0x0000000c }, // Note the offset update
{ 0x15, 0, 1, 0xc0a83865 },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000000 },

关于c - 为什么我使用带有 udp 套接字的 BPF 收不到任何数据包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57199413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com