找出与sendto函数中使用的套接字关联的src IP和端口

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

在下面的函数中,在使用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);
}
c linux udp
2个回答
1
投票

这是您获得港口的方式。绑定到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地址。最坏的情况是,您枚举路由表以推断最有可能用于特定目标IP的接口和地址。


0
投票

从Linux udp(7)的联机帮助页中>

为了接收数据包,可以先使用bind(2)将套接字绑定到本地地址。否则,套接字层将自动分配/proc/sys/net/ipv4/ip_local_port_range定义的范围之外的可用本地端口,并将套接字绑定到INADDR_ANY

未绑定的UDP IPv6套接字被视为相同。因此,您已经通过使用getsockname()发送了第一个数据包,然后获得了套接字使用的本地端口,但是您无法获取特定的本地地址,因为没有一个-数据包被发送到任何计算机的本地地址。该端口上的地址将被接收(当然是Modulo防火墙规则等)。


但是有希望。

shell命令ip route get ADDRESS将显示用于将数据包发送到ADDRESS的网络接口和IP地址。有关如何以编程方式访问路由表,请参见rtnetlink(7)

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