从 struct sockaddr 获取 IP 地址不适用于 32 位编译

发布于 2024-11-06 04:03:31 字数 1600 浏览 0 评论 0原文

我有一个小型客户端/服务器应用程序,用于发送/接收 UDP 发现数据包。当收到 UDP 数据包时,我想显示源 IP。客户端/服务器代码基于 Beej 的 UDP 示例: https:// beej.us/guide/bgnet/html/multi/clientserver.html

当我编译 64 位时,IP 按预期显示,但当我编译 32 位(-m32 选项)时,它没有得到完全正确的价值。

代码片段:

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

...

printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
    (struct sockaddr *)their_addr, &addr_len)) == -1) {
    perror("recvfrom");
    exit(1);
}

printf("listener: got packet from %s\n",
    inet_ntop(their_addr->sa_family,
        get_in_addr((struct sockaddr *)their_addr),
        s, sizeof s));

printf("Sockaddr: ");
for (i=0; i<sizeof(struct sockaddr_in); i++)
    printf("%x ", ((char *)their_addr)[i]);
printf("\n");

编译 64 位时正确输出:

    listener: waiting to recvfrom...
    listener: got packet from 192.168.20.6
    Sockaddr: 2 0 ffffff80 19 ffffffc0 ffffffa8 14 6 64 2e 40 0 0 0 0 0 

使用 -m32 编译时输出错误:

    listener: waiting to recvfrom...
    listener: got packet from 168.32.140.255
    Sockaddr: 2 0 ffffff80 19 ffffffa8 20 ffffff8c ffffffff 50 ffffffdd 7d fffffff7 4 0 0 0 

我真的不明白为什么在编译 32 位时使用 get_in_addr 或 inet_ntop 会出现问题?

I have a small client/server app that sends/receives UDP discovery packets. When a UDP packet is received I want to display the source IP. The client/server code is based on the UDP example from Beej: https://beej.us/guide/bgnet/html/multi/clientserver.html

When I compile for 64bit the IP is displayed as expected but when I compile for 32bit (-m32 option) it doesn't get the right value at all.

Code snippit:

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

...

printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
    (struct sockaddr *)their_addr, &addr_len)) == -1) {
    perror("recvfrom");
    exit(1);
}

printf("listener: got packet from %s\n",
    inet_ntop(their_addr->sa_family,
        get_in_addr((struct sockaddr *)their_addr),
        s, sizeof s));

printf("Sockaddr: ");
for (i=0; i<sizeof(struct sockaddr_in); i++)
    printf("%x ", ((char *)their_addr)[i]);
printf("\n");

Correct output when compiled for 64bit:

    listener: waiting to recvfrom...
    listener: got packet from 192.168.20.6
    Sockaddr: 2 0 ffffff80 19 ffffffc0 ffffffa8 14 6 64 2e 40 0 0 0 0 0 

Wrong output when compiled with -m32:

    listener: waiting to recvfrom...
    listener: got packet from 168.32.140.255
    Sockaddr: 2 0 ffffff80 19 ffffffa8 20 ffffff8c ffffffff 50 ffffffdd 7d fffffff7 4 0 0 0 

I don't really understand why there is a problem using get_in_addr or inet_ntop when compiling for 32bit?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

狼性发作 2024-11-13 04:03:31

addr_len 应设置为地址结构的大小,而不是指针的大小(它恰好在 64 位模式下工作,因为指针在该模式下是两倍大)。所以应该是:

addr_len = sizeof *their_addr;

顺便说一句,ir_addr是如何初始化的?必须有一个真实的结构来指向。

addr_len should be set to the size of the address structure, not the size of the pointer (it's happening to work in 64 bit mode, because pointers are twice as large in that mode). So it should be:

addr_len = sizeof *their_addr;

Incidentally, how is their_addr initialised? There has to be a real structure to point to.

抱猫软卧 2024-11-13 04:03:31

除了这些错误之外,这是一种处理 IP 地址的错误方法。您应该将 getnameinfoNI_NUMERICHOST 标志一起使用来获取可呈现的地址形式。那么你就不必关心它是v4还是v6,甚至是v7还是v8。

Aside from the bugs, this is a broken way to handle IP addresses. You should use getnameinfo with the NI_NUMERICHOST flag to get presentable forms of addresses. Then you don't have to care if it's v4 or v6, or even v7 or v8.

爱人如己 2024-11-13 04:03:31

get_in_addr 不是标准函数。您的实现很可能是错误的。显示代码。

get_in_addr isn't a standard function. Most likely your implementation does it wrong. Show the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文