gpt4 book ai didi

c - 无法将原始套接字绑定(bind)到接口(interface)

转载 作者:IT王子 更新时间:2023-10-29 00:35:39 26 4
gpt4 key购买 nike

我正在努力将原始套接字绑定(bind)到接口(interface),我的目标是实现简单的数据包嗅探器。已经投入大量时间在网上搜索并浏览引用资料,其中一部分列在底部。

我可以打开套接字,bind 没有错误,但是当剥离以太网 header 并观察 IP header 时,我看到捕获的环回 (127.0.0.1) 和其他不需要的 ethX ifaces 流量。

结论之一是 setsockopt 不能用于我的情况,这是我的代码片段:

struct sockaddr_ll sll;
int raw_sock;

raw_sock = socket( PF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
// also tried with AF_PACKET

bzero(&sll , sizeof(sll));

sll.sll_family = PF_PACKET;
// also tried with AF_PACKET
sll.sll_ifindex =get_iface_index(raw_sock,"eth1");
// returns valid ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);
if((bind(raw_sock , (struct sockaddr *)&sll , sizeof(sll))) ==-1)
{
perror("bind: ");
exit(-1);
}

saddr_size = (sizeof sll);
data_size = recvfrom(raw_sock , buffer_ptr, 65536, 0 , &sll , (socklen_t*)&saddr_size);

提前致谢!

引用资料:

  1. http://man7.org/linux/man-pages/man7/packet.7.html
  2. http://man7.org/linux/man-pages/man2/bind.2.html
  3. Raw socket with device bind using setsockopt() system is not working in Fedora core 6(2.6.18-1.2798.fc6)
  4. how to bind raw socket to specific interface

编辑-1:非常感谢您花时间回复,我对无休止的解决方案搜索感到非常迷茫和沮丧。

  1. 我仅限于自己的实现,因此无法使用 libcap 或其他。
  2. 从 ioctl 调用 SIOCGIFINDEX 返回的接口(interface)索引在我的例子中是 3,与 sll.sll_ifindex 值相同。假设我可以依赖“ip link show”——我的 eth1 索引确实是 3。

    int get_iface_index(int socket,char *iface_name){
    struct ifreq ifr;
    char ifname[IFNAMSIZ]="eth1";
    // Ugly hard coded, will be changed
    memset(&ifr, 0, sizeof(struct ifreq));
    strncpy((char *)ifr.ifr_name, ifname, IFNAMSIZ);
    if (ioctl(socket, SIOCGIFINDEX, &ifr) < 0){
    perror("ioctl: ");
    return -1;
    }
    return ifr.ifr_ifindex;
    // Always success here 2 for eth0, 3 for eth1
    }

最佳答案

如果你想写一个数据包嗅探器,我强烈建议你使用为此目的而设计的libpcap。这将确保在数据到达用户区域之前使用伯克利数据包过滤器 (BPF) 完成过滤(关于您想要的数据包)。

您的最后一个链接是关于原始套接字的,即 IPPROTO_RAW。这些套接字使用 setsockoptSO_BINDTODEVICE 进行绑定(bind)。来自 raw 的手册页:

A raw socket can be bound to a specific local address using the bind(2) call. If it isn't bound, all packets with the specified IP protocol are received. In addition, a RAW socket can be bound to a specific network device using SO_BINDTODEVICE; see socket(7).

An IPPROTO_RAW socket is send only. If you really want to receive all IP packets, use a packet(7) socket with the ETH_P_IP protocol. Note that packet sockets don't reassemble IP fragments, unlike raw sockets.

因此您的最后一个链接不相关,您使用正常的 bind() 调用是正确的。

如果您确定不使用libpcap,我建议您首先打印出sll.sll_ifindex 的值。我打赌它是零(所有接口(interface))。您没有向我们展示 get_iface_index 的源代码,但我怀疑可能存在错误。

关于c - 无法将原始套接字绑定(bind)到接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21660868/

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