gpt4 book ai didi

c - 使用 af_packet 从数据包中获取接口(interface)名称

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:50 43 4
gpt4 key购买 nike

使用以下方法使用 AF_PACKET 和环形缓冲区(伪 C)捕获数据包:

// Set up socket
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

// Set socket bind options
struct sockaddr_ll sll;
sll.sll_family = AF_PACKET
sll.sll_protocol = htons(ETH_P_ALL)
sll.sll_ifindex = 0 // Bind to all interfaces

// Bind socket to all interfaces
bind(fd, (struct sockaddr *) &sll, socklen_t(sizeof(sll)))

// Set tpacket options in tp
setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &tp, socklen_t(sizeof(tp)))

// Map the ring buffer
mmap(NULL, ring_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)

// Read from ring using offsets
...

如上所示,如果 sll_ifindex 设置为 0,套接字将在所有接口(interface)上接收。有没有办法修改此方法,或以某种方式收集数据包到达的网络接口(interface)?

最佳答案

是的。放入环形缓冲区的每个帧都会在其前面插入两个结构:首先是 tpacket_hdr,然后是 sockaddr_ll。后者描述了接收数据包的接口(interface)。结构之间有填充,所以代码看起来像这样:

struct tpacket_hdr *tp = <Next frame in ring buffer>;
<wait for packet to arrive>
struct sockaddr_ll *sll = (struct sockaddr_ll*)((char *)tp + TPACKET_ALIGN(sizeof(*tp)));
printf("Frame received on IF index %u", sll->sll_ifindex);

您可以使用 SIOCGIFNAME ioctl 将接口(interface)索引转换为名称。

关于c - 使用 af_packet 从数据包中获取接口(interface)名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36126603/

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