Linux UDP服务器 - 目标IP错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux UDP服务器 - 目标IP错误相关的知识,希望对你有一定的参考价值。

我有一个嵌入式Linux设备,可以监听UDP数据包。该设备有两个以太网接口,因此可以在两个接口上检索数据包。在某些UDP消息/数据包上,我必须做一些特定的接收它的接口。所以我需要检测哪个接口收到了数据包。

我在Stackoverflow上发现了帖子和示例,展示了如何从IP_PKTINFO中提取目标IP。如果我逐个测试接口,这可以正常工作。连接两个接口并接收目标IP是相同的。

我注意到ifindex不一样,但我不明白为什么ipi_spec_dst是相同的,当我清楚地在两个不同的接口和两个不同的IP接收数据包。

负责提取目标IP的C / C ++代码:

    ssize_t byteCount=recvmsg(f_socket, &message, 0);
    if (byteCount==-1) {
        printf("%s",strerror(errno));
    }

    for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&message); 
         cmsg != NULL; 
         cmsg = CMSG_NXTHDR(&message, cmsg)) 
    {
        if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) continue;
        struct in_pktinfo *pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
        char* destAddr = (char*) calloc(4, sizeof(char));
        destAddr = inet_ntoa(pi->ipi_spec_dst);
        std::cout << destAddr << " " << std::to_string(pi->ipi_ifindex) << std::endl;
    }

输出eth0已连接:

172.20.55.9 4
172.20.55.9 4
172.20.55.9 4
...

输出eth0已连接:

200.0.0.101 6
200.0.0.101 6
200.0.0.101 6
...

输出eth0和eth1连接:

172.20.55.9 6
172.20.55.9 4
172.20.55.9 6
172.20.55.9 4
...

预期产量:

200.0.0.101 6
172.20.55.9 4
200.0.0.101 6
172.20.55.9 4
...

首先,我不确定这是否是预期的,我认为不是,但我可能没有正确理解文档。

如果需要,我可以提供更多代码。

代码取自:

  1. Getting the destination address of UDP packet
  2. Get destination address of a received UDP packet

非常感谢任何和所有的帮助。谢谢。

-aln

答案

我认为行中存在问题:

char* destAddr = (char*) calloc(4, sizeof(char));
destAddr = inet_ntoa(pi->ipi_spec_dst);
std::cout << destAddr << " " << std::to_string(pi->ipi_ifindex) << std::endl;

两个问题:

  • 你应该使用ipi_addr而不是ipi_spec_dst(参见man 7 ip
  • 你不需要calloc的东西(也就是 不够大, 未正确初始化, 没有被释放。)

您可以通过以下方式简化:

printf("%s %d
", inet_ntoa(pi->ipi_addr), pi->ipi_ifindex);

因此,要恢复,您的循环可能如下所示:

for (   struct cmsghdr *cmsg = CMSG_FIRSTHDR(&message); 
        cmsg != NULL; 
        cmsg = CMSG_NXTHDR(&message, cmsg)) 
{
    if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) 
        continue;

    struct in_pktinfo *pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
    printf("%s %d
", inet_ntoa(pi->ipi_addr), pi->ipi_ifindex);
}
另一答案

我通过使用ifindex获取接口名称解决了这个问题,然后我用它来执行特定于接口的代码。

以上是关于Linux UDP服务器 - 目标IP错误的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核:从skb获取udp头,udp_hdr()获取到是错误的udp头(转)

[架构之路-43]:目标系统 - 系统软件 - Linux下的网络通信-3-TCP/IP协议族:IPTCP/UDP/SCTPSocket应用层协议

linux系统UDP的socket通信编程3

获取活动 udp 连接的目标 IP/端口?

网络编程

基于windows的回声udp服务器端/客户端