找出与 sendto 函数中使用的套接字关联的 src IP 和端口
Finding out the src IP and port associated with the socket used in sendto function
在下面的函数中,在我使用 sendto() 之后,我想知道用于发送消息的源 IP 和端口。有可能查到吗?
void sendMsg(char* payload, size_t payloadLength, const char* ip6Addr, short port)
{
int sock;
size_t size;
socklen_t clilen;
struct sockaddr_in6 server_addr, client_addr;
sock = socket(PF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
perror("creating socket");
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
inet_pton(AF_INET6, ip6Addr, &server_addr.sin6_addr);
server_addr.sin6_port = htons(port);
size = sendto(sock, payload, payloadLength, 0 , (const struct sockaddr *) &server_addr,sizeof(server_addr));
if(size < 0)
printf("Error in sending message\n");
else
printf("[%d] bytes written to network\n",size);
}
这是获取端口的方法。绑定到 INADDR_ANY 地址 (IN6ADDR_ANY_INIT)。然后使用getsockname.
sockaddr_in6 addr = {0};
sockaddr_in6 addrLocal = {0};
socklen_t addrSize = sizeof(addrLocal);
unsigned short port = 0;
addr.sin6_family = AF_INET6;
sock = socket(AF_INET6, SOCK_DGRAM,0);
bind(sock, (sockaddr*)&addr, sizeof(addr)); // bind to the INADDR_ANY address for IPV6
getsockname(sock, (sockaddr*)&addrLocal, &addrSize);
port = addrLocal.sin6_port;
我不确定 IP 地址。 addrLocal
中嵌入的 IP 地址仍将全为零。不确定您如何获得用于特定数据包发送的 IP 地址。最坏的情况是,您枚举路由 table 以推断哪个接口和地址最有可能用于特定目标 IP。
来自 udp(7)
的 Linux 联机帮助页
In order to receive packets, the socket can be bound to a local address first by using bind(2)
. Otherwise, the socket layer will automatically assign a free local port out of the range defined by /proc/sys/net/ipv4/ip_local_port_range
and bind the socket to INADDR_ANY
.
未绑定的 UDP IPv6 套接字被同等对待。因此,您可以在使用 getsockname()
发送第一个数据包后获取套接字使用的本地端口,如已经演示的那样,但是您无法获取特定的本地地址,因为没有一个 - 发送到任何一个的数据包该端口上的机器地址将被接收(当然是模数防火墙规则等)。
但是还是有希望的。
shell 命令 ip route get ADDRESS
将显示用于向 ADDRESS
发送数据包的网络接口和 IP 地址。有关如何以编程方式访问路由表的信息,请参阅 rtnetlink(7)
。
在下面的函数中,在我使用 sendto() 之后,我想知道用于发送消息的源 IP 和端口。有可能查到吗?
void sendMsg(char* payload, size_t payloadLength, const char* ip6Addr, short port)
{
int sock;
size_t size;
socklen_t clilen;
struct sockaddr_in6 server_addr, client_addr;
sock = socket(PF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
perror("creating socket");
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
inet_pton(AF_INET6, ip6Addr, &server_addr.sin6_addr);
server_addr.sin6_port = htons(port);
size = sendto(sock, payload, payloadLength, 0 , (const struct sockaddr *) &server_addr,sizeof(server_addr));
if(size < 0)
printf("Error in sending message\n");
else
printf("[%d] bytes written to network\n",size);
}
这是获取端口的方法。绑定到 INADDR_ANY 地址 (IN6ADDR_ANY_INIT)。然后使用getsockname.
sockaddr_in6 addr = {0};
sockaddr_in6 addrLocal = {0};
socklen_t addrSize = sizeof(addrLocal);
unsigned short port = 0;
addr.sin6_family = AF_INET6;
sock = socket(AF_INET6, SOCK_DGRAM,0);
bind(sock, (sockaddr*)&addr, sizeof(addr)); // bind to the INADDR_ANY address for IPV6
getsockname(sock, (sockaddr*)&addrLocal, &addrSize);
port = addrLocal.sin6_port;
我不确定 IP 地址。 addrLocal
中嵌入的 IP 地址仍将全为零。不确定您如何获得用于特定数据包发送的 IP 地址。最坏的情况是,您枚举路由 table 以推断哪个接口和地址最有可能用于特定目标 IP。
来自 udp(7)
的 Linux 联机帮助页In order to receive packets, the socket can be bound to a local address first by using
bind(2)
. Otherwise, the socket layer will automatically assign a free local port out of the range defined by/proc/sys/net/ipv4/ip_local_port_range
and bind the socket toINADDR_ANY
.
未绑定的 UDP IPv6 套接字被同等对待。因此,您可以在使用 getsockname()
发送第一个数据包后获取套接字使用的本地端口,如已经演示的那样,但是您无法获取特定的本地地址,因为没有一个 - 发送到任何一个的数据包该端口上的机器地址将被接收(当然是模数防火墙规则等)。
但是还是有希望的。
shell 命令 ip route get ADDRESS
将显示用于向 ADDRESS
发送数据包的网络接口和 IP 地址。有关如何以编程方式访问路由表的信息,请参阅 rtnetlink(7)
。