简体   繁体   English

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

[英]How to bind a (UDP) raw socket to interface device

My goal is to get all (UDP) messages from a single interface device.我的目标是从单个接口设备获取所有(UDP)消息。 I work on Ubuntu 20.04, programming in C.我在 Ubuntu 20.04 上工作,用 C 编程。

A raw socket seemed to be the best solution, the problem is the binding to the interface seems not to work.原始套接字似乎是最好的解决方案,问题是与接口的绑定似乎不起作用。 I still get what seems like ALL messages from all devices.我仍然收到来自所有设备的所有消息。

//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");
}

During execution, I get no errors.在执行期间,我没有收到任何错误。

Interestingly, I get no messages at all when I change htons(ETH_P_ALL) to IPPROTO_UDP in the socket() command (finally, I want to end up only with UDP messages).有趣的是,当我在socket()命令htons(ETH_P_ALL)更改为IPPROTO_UDP时,我根本没有收到任何消息(最后,我只想得到 UDP 消息)。

Did I miss something?我错过了什么?

EDIT: To better specify my goal: i want all UDP messages on a single interface device for both IPv4 and IPv6 and with multiple src and dst IPs/Ports (so basically a sniffer for UDP messages on that interface).编辑:为了更好地指定我的目标:我希望 IPv4 和 IPv6 以及具有多个 src 和 dst IP/端口的单个接口设备上的所有 UDP 消息(因此基本上是该接口上 UDP 消息的嗅探器)。

If you want to see all UDP packets coming into the system, you'll want to use an AF_INET socket, not AF_PACKET , and you'll want to set the protocol to IPPROTO_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;
}

Note that you want to use perror instead of printf when a socket function fails.请注意,当套接字函数失败时,您希望使用perror而不是printf This will tell you why the call failed.这将告诉您呼叫失败的原因

Also note that this also only receives packets that your system is "supposed to" see, ie those where the destination IP is either the interface IP or a broadcast / multicast address.另请注意,这也只接收您的系统“应该”看到的数据包,即目标 IP 是接口 IP 或广播/多播地址的数据包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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