Question

My program aims to browse a range of IPs, delimited by a start IP, and an end IP. Here's an example on a local wireless network :

MyIP & Netmask = 192.168.1.0
MyIP | ~Netmask = 192.168.1.255

My program must be able to iterate over all available IPs, from 192.168.1.1 to 192.168.1.254, but I cannot find a constant or "proper" way to get the distance between an IP and another. Here's a sample program I used for testing :

#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;
}

I get the following output :

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

Now, I understand why the distance between 192.168.1.1 and 192.168.1.2 is 16777216 (2^24). Now, is there any way I could get the above values "properly", using predefined constants if possible (manipulating IP strings in dot format isn't really a solution) ?

  • What do I need to add to the in_addr_t value to jump from 192.168.1.1 to 192.168.1.2 ?
  • What do I need to add to the in_addr_t value to jump from 175.1.1.255 to 175.1.2.0 on bigger subnets ? What about class A IPs then ?
  • Is there anyway to determine the "gap" values using the network information, in case my subnet is more specific ?
  • Am I missing an easier/cleaner way for my iterating problem ?
Was it helpful?

Solution

It's an endian problem

In your system the inet_addr("192.168.1.1") returns the ip address presented in 4 octets in this way:

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

the inet_addr("192.168.1.2") returns

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

The difference inet_addr("192.168.1.2") - inet_addr("192.168.1.2") will be:

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

Use htonl() function for each inet_addr() inorder to avoid the endian issues

So htonl() of inet_addr("192.168.1.2") will return

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

And htonl() of inet_addr("192.168.1.1") returns

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

And then the difference will be equal to 1

      addr1.sin_addr.s_addr = htonl(inet_addr("192.168.1.1"));
      addr2.sin_addr.s_addr = htonl(inet_addr("192.168.1.2"));
      addr3.sin_addr.s_addr = htonl(inet_addr("192.168.1.3"));
      addr4.sin_addr.s_addr = htonl(inet_addr("192.168.1.255"));
      addr5.sin_addr.s_addr = htonl(inet_addr("192.168.2.1"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top