找出与 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)