繁体   English   中英

如何将(UDP)原始套接字绑定到接口设备

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM