in_addr_t,从一个IP跳转到下一个IP

时间:2014-02-12 10:50:49

标签: c networking ip-address

我的计划旨在浏览一系列IP,由起始IP和结束IP分隔。以下是本地无线网络的示例:

MyIP & Netmask = 192.168.1.0
MyIP | ~Netmask = 192.168.1.255

我的程序必须能够遍历所有可用的IP,从192.168.1.1到192.168.1.254,但我无法找到一个恒定或“正确”的方法来获得IP和另一个IP之间的距离。这是我用于测试的示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char** argv)
{
      struct sockaddr_in addr1, addr2, addr3, addr4, addr5;

      addr1.sin_addr.s_addr = inet_addr("192.168.1.1");
      addr2.sin_addr.s_addr = inet_addr("192.168.1.2");
      addr3.sin_addr.s_addr = inet_addr("192.168.1.3");
      addr4.sin_addr.s_addr = inet_addr("192.168.1.255");
      addr5.sin_addr.s_addr = inet_addr("192.168.2.1");

      fprintf(stdout, "addr2 - addr1 = %u\n", addr2.sin_addr.s_addr - addr1.sin_addr.s_addr);
      fprintf(stdout, "addr3 - addr2 = %u\n", addr3.sin_addr.s_addr - addr2.sin_addr.s_addr);
      fprintf(stdout, "addr4 - addr3 = %u\n", addr4.sin_addr.s_addr - addr3.sin_addr.s_addr);
      fprintf(stdout, "addr5 - addr4 = %u\n", addr5.sin_addr.s_addr - addr4.sin_addr.s_addr);

      return EXIT_SUCCESS;
}

我得到以下输出:

addr2 - addr1 = 16777216
addr3 - addr2 = 16777216
addr4 - addr3 = 4227858432
addr5 - addr4 = 33619968

现在,我理解为什么192.168.1.1和192.168.1.2之间的距离是16777216(2 ^ 24)。现在,有没有什么方法可以“正确地”获得上述值,如果可能的话使用预定义的常量(以点格式操作IP字符串实际上不是解决方案)?

  • 我需要添加in_addr_t值才能从192.168.1.1跳转到192.168.1.2?
  • 在较大的子网上,我需要添加in_addr_t值从175.1.1.255跳到175.1.2.0?那么A类IP呢?
  • 无论如何使用网络信息确定“间隙”值,以防我的子网更具体?
  • 我错过了一个更容易/更清晰的迭代问题方法吗?

1 个答案:

答案 0 :(得分:1)

这是一个endian问题

在您的系统中,inet_addr("192.168.1.1")以这种方式返回以4个八位字节呈现的IP地址:

    0x01 | 0x01 | 0xA8 | 0xC0
//    1  .   1  .  168 . 192

inet_addr("192.168.1.2")返回

    0x02 | 0x01 | 0xA8 | 0xC0
//    2  .   1  .  168 . 192

差异inet_addr("192.168.1.2") - inet_addr("192.168.1.2")将是:

0x0201A8C0 - 0x0101A8C0 = 0x1000000 // in decimal is 16777216

为每个htonl()使用inet_addr()函数以避免字节序问题

htonl()的{​​{1}}将返回

inet_addr("192.168.1.2")

0xC0 | 0xA8 | 0x01 | 0x02 // 192 . 168 . 1 . 2 的{​​{1}}返回

htonl()

然后差异将等于1

inet_addr("192.168.1.1")