【问题标题】:inet_ntoa probleminet_ntoa 问题
【发布时间】:2011-01-31 14:18:33
【问题描述】:

我声明以下变量

unsigned long   dstAddr;
unsigned long   gateWay;
unsigned long   mask;

这些变量包含按网络字节顺序排列的 IP 地址。因此,当我尝试使用inet_ntoa 函数为掩码变量打印点符号时,有时它会打印奇怪的值。下面的代码在一个while循环中..循环n次。

printf("%s\t%s\t%s\t",inet_ntoa(dstAddr),inet_ntoa(gateWay),inet_ntoa(mask));

  192.168.122.0         0.0.0.0    0.255.255.255    

但应该是

  192.168.122.0         0.0.0.0    255.255.255.0

我打印了变量的十六进制值,它显示..

007aa8c0    00000000      ffffff00  

这是因为 inet_ntoa 吗??

实际上,我正在尝试通过 NETLINKS 从内核中的 254 路由表中获取声明变量的值。我想我仍然应该使用 inet_ntoa 函数将值转换为点符号.. ??

【问题讨论】:

  • 只是一个警告,inet_ntoa 已被弃用 - 您应该改用 inet_ntop() 或 inet_pton()。
  • inet_ntop() 和 inet_pton() 也被弃用,因为它们不支持 IPv6 范围标识符。如果你想要 IPv6 支持,你应该使用 getaddrinfo() 和 getnameinfo()。
  • @codingfreak,无论设置你的掩码都是错误的。根据我的回答,该值应为 00ffffff。

标签: c sockets


【解决方案1】:

唯一有意义的是,您关于所有地址都按网络字节顺序排列的假设是不正确的。

【讨论】:

    【解决方案2】:

    好吧,鉴于它适用于您的非掩码值(包括第一个也设置了高位的值),我会查看 mask 实际包含的内容。

    当您将其打印为正常的无符号长时,它是什么?我敢打赌,mask 实际上不是正确的值:

    printf ("%08x\t%08x\t%08x\n", dstAddr, gateWay, mask);
    

    (假设您有四字节长)。

    比如这个小程序(在Cygwin下编译):

    #include <stdio.h>
    
    int main (void) {
        unsigned long dstAddr, gateWay, mask;
        dstAddr = 0x007aa8c0;
        gateWay = 0x00000000;
        mask    = 0x00ffffff;
    
        printf("%-15s %-15s %-15s\n",
            inet_ntoa (dstAddr),
            inet_ntoa (gateWay),
            inet_ntoa (mask));
    
        printf("%-15s ",  inet_ntoa (dstAddr));
        printf("%-15s ",  inet_ntoa (gateWay));
        printf("%-15s\n", inet_ntoa (mask));
    
        printf ("%08x%8s%08x%8s%08x\n",
            dstAddr, "",
            gateWay, "",
            mask);
    
        return 0;
    }
    

    输出:

    192.168.122.0   192.168.122.0   192.168.122.0
    192.168.122.0   0.0.0.0         255.255.255.0
    007aa8c0        00000000        00ffffff
    

    请注意,我必须将我对inet_ntoa 的调用分开,因为它似乎使用了静态缓冲区。当我在单个printf 中完成所有操作时,它在打印任何内容之前覆盖了该缓冲区的内容,因此我只处理了最后一个。我不认为在你的情况下会发生这种情况,因为你得到了不同的值。

    【讨论】:

    • 那我猜你的面具设置不正确。它应该是 00ffffff,不是 ffffff00。您需要找出设置的位置并修复它。这不是 inet_ntoa 的问题。
    • 我猜 255.255.255.0 的十六进制值是 ffffff00 ?使用以下工具检查 - kloth.net/services/iplocate.php
    • 您必须了解网络和架构的字节顺序(小端或大端)。将 192.168.122.0 插入同一个工具,你会得到 C0A87A00,这也是错误的顺序。在 little-endian 上,值 0x01020304 在内存中存储为 04,03,02,01。
    • 一个小疑问,我实际上是通过 netlink 套接字从内核获取值.. 所以仍然大端和小端进入画面??
    • 现在你已经超越了我的专业领域,@codingfreak。我只能说,从经验证据来看,面具是错误的。我以前从未使用过 netlinks 接口。
    【解决方案3】:

    我也有同样的问题。 如果您需要其他方式,请使用 inet_ntop() 和 inet_pton()。不要使用 inet_ntoa()、inet_aton() 和类似的,因为它们已被弃用并且不支持 ipv6。 见链接:convert Ip address int to string

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      • 2011-02-14
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多