[英]How to bind a (UDP) raw socket to interface device
我的目标是从单个接口设备获取所有(UDP)消息。 我在 Ubuntu 20.04 上工作,用 C 编程。
原始套接字似乎是最好的解决方案,问题是与接口的绑定似乎不起作用。 我仍然收到来自所有设备的所有消息。
//Create raw socket
if ((sock_fd = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
printf ("Cannot create raw socket!\n");
return -1;
}
//Bind to interface
if ((setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, if_name, strlen(if_name)+1)) < 0) {
printf ("Failed to bind socket to interface device %s!\n", if_name);
return -1;
}
while(1){
memset (buffer, 0, BUF);
if ((n = recv(sock_fd, buffer, BUF, 0)) < 0){
printf("No data available!\n");
continue;
}
//Print data frame
for(i=0; i<n; i++) {
printf("0x%x ", buffer[i]);
}
printf("\n\n");
}
在执行期间,我没有收到任何错误。
有趣的是,当我在socket()
命令htons(ETH_P_ALL)
更改为IPPROTO_UDP
时,我根本没有收到任何消息(最后,我只想得到 UDP 消息)。
我错过了什么?
编辑:为了更好地指定我的目标:我希望 IPv4 和 IPv6 以及具有多个 src 和 dst IP/端口的单个接口设备上的所有 UDP 消息(因此基本上是该接口上 UDP 消息的嗅探器)。
如果您想查看所有进入系统的 UDP 数据包,您需要使用AF_INET
套接字,而不是AF_PACKET
,并且您需要将协议设置为IPPROTO_UDP
:
if ((sock_fd = socket (AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) {
perror("Cannot create raw socket!\n");
return -1;
}
请注意,当套接字函数失败时,您希望使用perror
而不是printf
。 这将告诉您呼叫失败的原因。
另请注意,这也只接收您的系统“应该”看到的数据包,即目标 IP 是接口 IP 或广播/多播地址的数据包。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.