【问题标题】:Getting interface name from packet with af_packet使用 af_packet 从数据包中获取接口名称
【发布时间】:2016-03-21 08:58:29
【问题描述】:

使用以下方法使用 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,则套接字将在所有接口上接收。有没有办法修改这个方法,或者以某种方式收集数据包到达的网络接口?

【问题讨论】:

  • @JoachimPileborg 我的 C 有点太伪了。我对其进行了编辑以希望使其更清晰。

标签: c linux sockets


【解决方案1】:

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

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 的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 2012-08-02
    相关资源
    最近更新 更多