Linux UDP服务器 - 目标IP错误

问题描述 投票:0回答:2

我有一个嵌入式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

c++ linux sockets networking udp
2个回答
1
投票

我认为行中存在问题:

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\n", 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\n", inet_ntoa(pi->ipi_addr), pi->ipi_ifindex);
}

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.