Linux UDP 服务器 - 目标 IP 错误
Linux UDP server - Destination IP wrong
我有一个嵌入式 linux 设备可以侦听 UDP 数据包。
该设备有两个以太网接口,因此可以在两个接口上检索数据包。
在某些 UDP messages/packets 上,我必须针对接收它的接口做一些特定的事情。所以我需要检测哪个接口收到了数据包。
我在 Whosebug 上找到了展示如何从 IP_PKTINFO
中提取目标 IP 的帖子和示例。如果我一个一个地测试接口,这很好用。两个接口都连接,接收目的IP相同。
我注意到 ifindex
不一样,但是我不明白为什么 ipi_spec_dst
是一样的,当我在两个不同的接口上用两个不同的 IP 清楚地收到一个数据包时.
C/C++ 负责提取目的IP的代码:
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
...
首先,我不确定这是否是预期的,我认为不是,但我可能没有正确理解文档。
如果需要,我可以提供更多代码。
代码取自:
- Getting the destination address of UDP packet
- 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\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);
}
我通过使用 ifindex
获取接口名称然后用于执行接口特定代码解决了这个问题。
我有一个嵌入式 linux 设备可以侦听 UDP 数据包。 该设备有两个以太网接口,因此可以在两个接口上检索数据包。 在某些 UDP messages/packets 上,我必须针对接收它的接口做一些特定的事情。所以我需要检测哪个接口收到了数据包。
我在 Whosebug 上找到了展示如何从 IP_PKTINFO
中提取目标 IP 的帖子和示例。如果我一个一个地测试接口,这很好用。两个接口都连接,接收目的IP相同。
我注意到 ifindex
不一样,但是我不明白为什么 ipi_spec_dst
是一样的,当我在两个不同的接口上用两个不同的 IP 清楚地收到一个数据包时.
C/C++ 负责提取目的IP的代码:
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
...
首先,我不确定这是否是预期的,我认为不是,但我可能没有正确理解文档。
如果需要,我可以提供更多代码。
代码取自:
- Getting the destination address of UDP packet
- 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\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);
}
我通过使用 ifindex
获取接口名称然后用于执行接口特定代码解决了这个问题。