Translate

Image of Android Wireless Application Development
Image of Beginning Google Maps API 3
Image of RHCE Red Hat Certified Engineer Linux Study Guide (Exam RH302) (Certification Press)
Image of Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)

Calculate IPv4 Subnet Mask and Prefix

Here is a simple ksh93 script which I recently wrote to calculate the subnet mask and prefix when given a range of IPv4 addresses. It makes use of the bit manipulation facilities available in ksh93.

#!/bin/ksh93

[[ $# != 2 ]] && {
   echo "Usage: $0 ipaddress1 ipaddress2"
   exit 1
}

SaveIFS=$IFS
IFS="./"
typeset -a IParr1=($1)
typeset -a IParr2=($2)
IFS=$SaveIFS

typeset -i2 ip11=${IParr1[0]}
typeset -i2 ip12=${IParr1[1]}
typeset -i2 ip13=${IParr1[2]}
typeset -i2 ip14=${IParr1[3]}

typeset -i2 ip21=${IParr2[0]}
typeset -i2 ip22=${IParr2[1]}
typeset -i2 ip23=${IParr2[2]}
typeset -i2 ip24=${IParr2[3]}

mask=0; match=1
for ((arr=1; arr < 5; arr++))
do
    binary_value1=""
    binary_value2=""
    for ((b=7; b >= 0; b--))
    do
       bit_mask=$(( 1 << $b ))
       bit1=$(( ip1$arr & bit_mask ? 1 : 0 ))
       bit2=$(( ip2$arr & bit_mask ? 1 : 0 ))
       if (( match == 1 && bit1 == bit2 ))
       then
          (( mask++ ))
       else
          match=0
       fi
       binary_value1="$binary_value1$bit1"
       binary_value2="$binary_value2$bit2"
    done
    binary1="$binary1$binary_value1 "
    binary2="$binary2$binary_value2 "
done

typeset -i2 nm1=0 nm2=0 nm3=0 nm4=0

typeset -i quad=$(( mask / 8 ))
sigbits=$(( mask % 8 ))
if (( sigbits != 0 )); then
   slot=$(( 256 - ( 256 >> $sigbits ) ))
fi

for (( i=1; i < 5; i++ ))
do
   nameref nm=nm${i}
   if (( quad != 0 )); then
      nm=255
      (( --quad ))
   elif (( quad == 0 )); then
      nm=slot
      break
   fi
done


echo "   Start IP: $binary1"
echo "     End IP: $binary2"
echo "Subnet Mask: $((nm1)).$((nm2)).$((nm3)).$((nm4))"
echo "     Prefix: $((ip11 & nm1)).$((ip12 & nm2)).$((ip13 & nm3)).$((ip14 & nm4))/$mask"

exit 0

Here is the output for a number of inputs:

$ ./script 10.1.1.1  10.1.1.255
   Start IP: 00001010 00000001 00000001 00000001
     End IP: 00001010 00000001 00000001 11111111
Subnet Mask: 255.255.255.0
     Prefix: 10.1.1.0/24
$ ./script 10.1.1.1  10.1.1.127
   Start IP: 00001010 00000001 00000001 00000001
     End IP: 00001010 00000001 00000001 01111111
Subnet Mask: 255.255.255.128
     Prefix: 10.1.1.0/25
$ ./script 10.1.1.1  10.1.1.63
   Start IP: 00001010 00000001 00000001 00000001
     End IP: 00001010 00000001 00000001 00111111
Subnet Mask: 255.255.255.192
     Prefix: 10.1.1.0/26


This script can be easily modified to work with the Bash shell. The main change required is the replacement of the nameref syntax with the equivalent Bash syntax.

Comments are closed.