#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

void usage(void) {

  printf("Usage: ip_range ip-address netmask\n");
  printf("Syntax: ./ip_range [1-255].[0-255].[0-255].[1-254] [2-30]\n");
  printf("Example: ./ip_range 192.168.10.1 22\n");
  exit(1);

}

int main(int argc, char *argv[]) {

    if ((argc != 3) || (strlen(argv[1]) > 15) || (strlen(argv[2]) > 2)) {
        usage();
    }
    char ip_address[16];
    char netmask[3];

    strcpy(ip_address, argv[1]);
    strcpy(netmask, argv[2]);

char *endptr;
unsigned char a = strtol(ip_address, &endptr, 10);
if (a == 0) usage();
unsigned char b = strtol(endptr + 1, &endptr, 10);
unsigned char c = strtol(endptr + 1, &endptr, 10);
unsigned char d = strtol(endptr + 1, &endptr, 10);
if (d == 0) usage();
unsigned char net = strtol(netmask, &endptr, 10);
if (net > 30 || net < 2) usage();
printf("Input: %d.%d.%d.%d/%d\n", a,b,c,d,net);


    double pw, hosts;

    pw = pow(2,(32-net));
    hosts = pw - 2;

    if (net < 9) {
        a &= (255 << (8-net)); // 1111 1111 net 8  1111 1110 net 7 1111 1100 net 6
        b=c=d=0;
    } else if (net < 17) {
        b &= (255 << (16-net));
        c=d=0;

    } else if (net < 25) {
        c &= (255 << (24-net)); //  1<<0   0000 0001  ~ 1111 1110
        d=0;
    } else if (net < 33) {
        d &= (255 << (32-net));   // 1111 1111 << position (2)
    }

    printf("Network      : %d.%d.%d.%d/%d\n", a,b,c,d,net);
    printf("Start address: %d.%d.%d.%d\n", a,b,c,d+1);


    if (pw < 257) {
        d = d + (pw -2);
    } else
    if (pw < 65537) {
        d = 254;
        c = c + ((pw / 256) -1);
    } else
     if (pw < 16777217) {
        d = 254;
        c = 255;
        b = b + ((pw / 65536) -1);;
    }  else
    if (pw < 4294967297) {
         d = 254;
         b = c = 255;
         a = a + ((pw / 16777216) -1);
    }
    printf("End address  : %d.%d.%d.%d\n", a,b,c,d);
    printf("No of hosts  : %.0f\n", hosts);
    return 0;
}