Finding host address range in C

1.3k views Asked by At

I write a simple C program that prints all the usable host addresses in a network.

Input

We provide the IP address of our network and the subnet mask.

Output

We print all the usable ip addresses that corresponds to the network.

Example

If we give the Ip 192.168.3.0 and the subnet 255.255.255.0 (/24 at CIDR) we get the following output:

192.168.3.1
192.168.3.2
192.168.3.3
192.168.3.4
...etc until 254

Problem

I don't get the results correctly. Suppose we provide 192.168.3.0 and 255.255.255.0. I currently use bpf_u_int32 type from pcap lib to save both the ip and the subnet mask variables.

If I run the bellow code this is what I get as output:

0.3.168.193
0.3.168.194
0.3.168.195
0.3.168.196
0.3.168.197
0.3.168.198
0.3.168.199
0.3.168.200
0.3.168.201
0.3.168.202
0.3.168.203
0.3.168.204
0.3.168.205
0.3.168.206
0.3.168.207
0.3.168.208
0.3.168.209
0.3.168.210
0.3.168.211
0.3.168.212
0.3.168.213
0.3.168.214
0.3.168.215
0.3.168.216
0.3.168.217
0.3.168.218
0.3.168.219
0.3.168.220
0.3.168.221
0.3.168.222
0.3.168.223
0.3.168.224
0.3.168.225
0.3.168.226
0.3.168.227
0.3.168.228
0.3.168.229
0.3.168.230
...etc

Actual code

// suppose we have declare ip and subnet mask variables and passed values to it.
// bpf_u_int32 subnet_mask;
// bpf_u_int32 ip_address;

bpf_u_int32 x = subnet_mask;
  int numbits; // get the CIDR Prefix
  for (numbits = 0; x != 0; x >>= 1) {
    if (x & 0x01) {
      numbits++;
    }
  }

  // determine maximum and minimum host values.
  // we exclude the host and the broadcast (should we?)
  unsigned long hoststart;
  unsigned long hostend;
  hoststart = 1;
  hostend = (1 << (32 - numbits)) - 1;

  // mask off the network
  uint32_t network = ip_address & subnet_mask;

  // Calculate all host addresses in the range
  for (unsigned i = hoststart; i <= hostend; i++) {
    uint32_t hostip;
    int b1, b2, b3, b4;
    char ipstr[16];

    hostip = network + i;
    b1 = (hostip & 0xff000000) >> 24;
    b2 = (hostip & 0x00ff0000) >> 16;
    b3 = (hostip & 0x0000ff00) >> 8;
    b4 = (hostip & 0x000000ff);
    snprintf(ipstr, sizeof(ipstr), "%d.%d.%d.%d", b1, b2, b3, b4);
    printf("%s\n", ipstr);
  }
1

There are 1 answers

0
dbush On BEST ANSWER

Looks like an endianness issue.

The IP address and subnet mask are being stored in little endian format, which means the least significant byte is first. You need to swap the bytes using htonl.

uint32_t network = htonl(ip_address & subnet_mask);

Then the bytes will be in the correct order.