Showing posts with label convert ip to decimal. Show all posts
Showing posts with label convert ip to decimal. Show all posts

Wednesday, January 29, 2014

Determining IP address range from Subnet/CIDR

Script to find the IP address range from the given Subnet.

There are few functions which can be reused like
  1. Convert IP to Decimal ip_to_int()
  2. Convert Decimal to IP int_to_ip()
  3. Netmask to CIDR to_cidr()

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/bin/bash
# http://linuxcalling.blogspot.in/
# Script to find the IP address range
# Script : ip_range
# Usage  : ip_range <IP> <Subnet> [0|1 print range]
# Ahamed (ahamed.en@gmail.com)

usage()
{
  EXE=${0#*/}
  echo "Usage: $EXE <IP> <Subnet> [0|1]<print range>"
  echo "   eg: To display the IP address range"
  echo "       $EXE 192.168.1.1 255.255.140.0"
  echo "   eg: To display the IP address range with entire range"
  echo "       $EXE 192.168.1.1 255.255.140.0 1"
  exit
}

[ $# -lt 2 ] && usage

echo $1 $2 $3 | awk '

  BEGIN{
    BITS=8
    mask_add[0]=valid_subnet[0]=0
    for(i=BITS-1;i>=0;i--){
      k=or(k,lshift(1,i))
      mask_add[k]=BITS-i
      valid_subnet[BITS-i]=k
    }
  }
  function validate_subnet(input)
  {
    split(input, oc, ".")

    if(oc[4] > oc[3] || oc[3] > oc[2] || oc[2] > oc[1]){
        print "Invalid Subnet: ",input
        exit
    }
    for(j=1; j<=BITS/2; j++){
      for(i=0;i<=BITS;i++){
        if(!xor(oc[j],valid_subnet[i])){
          break;
        }
        err++
      }
      if(err == (BITS+1)){
        print "Invalid Subnet: ",input
        exit
      }
      err=0
    }
  }

  function to_cidr(input)
  {
    split(input, oc, ".")
    ret=mask_add[oc[1]]+mask_add[oc[2]]+mask_add[oc[3]]+mask_add[oc[4]]
    return ret
  }

  function ip_to_int(input)
  {

    split(input, oc, ".")
    ip_int=(oc[1]*(256^3))+(oc[2]*(256^2))+(oc[3]*(256))+(oc[4])
    return ip_int

  }

  function int_to_ip(input)
  {
    str=""
    num=input
    for(i=3;i>=0;i--){
      octet = int (num / (256 ^ i))
      str= i==0?str octet:str octet "."
      num -= (octet * 256 ^ i)
    }
    return str
  }
  {
    ip=$1
    mask=$2
    range=$3

    validate_subnet(mask)

    cidr=to_cidr(mask)
    diff=32-cidr
    no_of_ip=2^diff

    ip_int=ip_to_int(ip)
    ip_mask=and(ip_int, (2^32 - 2^diff))

    ip_start=ip_mask
    ip_end=ip_mask+no_of_ip-1

    print "No of IPs\t"(no_of_ip-2)
    print "First IP\t" int_to_ip(ip_start+1)
    print "Last IP\t\t" int_to_ip(ip_end-1)
    print "Subnet\t\t" int_to_ip(ip_mask)
    print "Broadcast\t" int_to_ip(ip_end)

    if(range){
      print "\nIP address range -- START --\n"
      curr=ip_start
      i=0
      while(curr<=ip_end){
        printf int_to_ip(curr)"\t"
        if(j++%4 == 0) printf "\n"
        curr+=1
      }
      print "\nIP address range -- END --"
    }
  } '

Script Usage

[root@maximus] → ./ip_range 192.168.1.1 255.255.255.224
No of IPs       30
First IP        192.168.1.1
Last IP         192.168.1.30
Subnet          192.168.1.0
Broadcast       192.168.1.31


[root@maximus] → ./ip_range 192.168.1.1 255.255.255.224 1
No of IPs       30
First IP        192.168.1.1
Last IP         192.168.1.30
Subnet          192.168.1.0
Broadcast       192.168.1.31

IP address range -- START --

192.168.1.0     192.168.1.1     192.168.1.2     192.168.1.3
192.168.1.4     192.168.1.5     192.168.1.6     192.168.1.7
192.168.1.8     192.168.1.9     192.168.1.10    192.168.1.11
192.168.1.12    192.168.1.13    192.168.1.14    192.168.1.15
192.168.1.16    192.168.1.17    192.168.1.18    192.168.1.19
192.168.1.20    192.168.1.21    192.168.1.22    192.168.1.23
192.168.1.24    192.168.1.25    192.168.1.26    192.168.1.27
192.168.1.28    192.168.1.29    192.168.1.30    192.168.1.31

IP address range -- END --

[root@maximus] → ./ip_range 192.168.1.1 255.255.0.0
No of IPs       65534
First IP        192.168.0.1
Last IP         192.168.255.254
Subnet          192.168.0.0
Broadcast       192.168.255.255