【发布时间】:2014-02-09 15:19:06
【问题描述】:
我正在努力将原始套接字绑定到接口,我的目标是实现简单的数据包嗅探器。 已经花费了数小时搜索网络并浏览了参考资料,其中一部分列在底部。
我能够打开套接字,bind 上没有错误,但是 在剥离以太网标头并观察 IP 标头时,我看到捕获的环回 (127.0.0.1) 和其他不受欢迎的 ethX iface 流量。
其中一个结论是在我的情况下不能使用 setsockopt,这是我的 code sn-ps :
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);
提前致谢!
参考资料:
- http://man7.org/linux/man-pages/man7/packet.7.html
- http://man7.org/linux/man-pages/man2/bind.2.html
- Raw socket with device bind using setsockopt() system is not working in Fedora core 6(2.6.18-1.2798.fc6)
- how to bind raw socket to specific interface
编辑-1: 非常感谢您抽出宝贵的时间来回复,我因无休止地寻找解决方案而感到迷茫和沮丧。
- 我仅限于自己的实现,因此无法使用 libcap 或其他人。
-
在我的例子中,从 ioctl 调用 SIOCGIFINDEX 返回的接口索引为 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 }
【问题讨论】:
-
也许您应该尝试
strace(1)以调查您为ioctl(2)和bind(2)系统调用提供的参数。 -
感谢 nodakai,我用调试器中的打印和值监视器重新检查了所有内容 - 没有任何可疑之处。任何其他线索将不胜感激。
标签: c linux sockets bind raw-sockets