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
...
首先,我不确定这是否是预期的,我认为不是,但我可能没有正确理解文档。
如果需要,我可以提供更多代码。
代码取自:
非常感谢任何和所有的帮助。谢谢。
-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应用层协议