Joshua Andrews wrote:
I am looking for a network calculator that will take input in the form of,I remembered I wrote a script to do something like that a few years ago and I called it cidrcalc.
67.160.0.0 : 67.191.255.255, and output the IP block in cidr notation, 67.160.0.0/11.
To use it to get the example output you provided, call it as follows:
./cidrcalc 160 191 8 67.
The comments in the script say what that means, but in essence; varying from 160 thru 191 at an offset of 8 bits with a leading text string of those 8 bits of '67.' generate the cidr.
To pass the script 2 IP addresses as you suggested and have it figure out the bit offsets, etc would take a bit of additional scripting. Fix it as you see fit.
#!/bin/bash
# This routine accepts 4 passed in parameters. # The starting IP octet value # The ending IP octet value. # A displacement constant. # A static prefix. # # The intent of this routine is to print out IP octets and CIDR values # that will encompass the range from starting octet to ending octet. # The need for this routine arose when we saw that a good portion of an # area of the world was serviced by a given range of IP addresses, and # we wanted to block that range in a firewall. # # As an example, suppose we want to block all the IP addresses from # 61.158.0.0 thru 61.189.255.255, and we need to specify this range in # CIDR notation. What we actually want to block are the networks 61.158 # 61.189. What varies is the range 158 through 189 with a displacement # of 8 bits which represents the static constant area between them namely # the 61 field. This routine would be called passing the parameters # 158 189 8 "61." to produce : # 61.158/15 # 61.160/12 # 61.176/13 # 61.184/14 # 61.188/15 # If the example were changed to block 123.61.158.00 thru 123.61.189.255, # the routine would be called passing 158 189 16 "123.61." to represent # that now 16 bits are static (123.61) and considered a displacement. # The output would be: # 123.61.158/23 # 123.61.160/20 # 123.61.176/21 # 123.61.184/22 # 123.61.188/23 # If the routine were called passing 158 189 16 "Hello there ", then the # output would be: # Hello There 158/23 # Hello There 160/20 # Hello There 176/21 # Hello There 184/22 # Hello There 188/23 # The prefix is applied with no processing. It is purely a convenience # for the user. # Note that the minimum execution would have DISPLACEMENT of 0, and a # PREFIX of "". Therefore, passing 158 189 0 "" produces: # 158/7 # 160/4 # 176/5 # 184/6 # 188/7 # That provides an answer as though the OCTETSTART and OCTETEND are for the # first octet of an IP address.
# Lets define some specialized variables and functions here. syntax() { echo "Syntax: $(basename $0) { OCTETSTART OCTETEND DISPLACEMENT PREFIX }" echo echo "Where: OCTETSTART is the starting octet value." echo " OCTETEND is the ending octet value." echo " DISPLACEMENT is a bit displacement constant." echo " PREFIX is a character string prefix constant." echo echo "The intent of this script is to output the network addresses in CIDR" echo "notation for the range of addresses specified between OCTETSTART and" echo "OCTETEND." echo echo "Examples:" echo "$(basename $0) 158 189 8 \"61.\" produces:" echo "61.158/15" echo "61.160/12" echo "61.176/13" echo "61.184/14" echo "61.188/15" echo echo "$(basename $0) 158 189 16 \"123.61.\" produces:" echo "123.61.158/23" echo "123.61.160/20" echo "123.61.176/21" echo "123.61.184/22" echo "123.61.188/23" echo echo "$(basename $0) 158 189 16 \"Hello.\" produces:" echo "Hello.158/23" echo "Hello.160/20" echo "Hello.176/21" echo "Hello.184/22" echo "Hello.188/23" echo echo "The DISPLACEMENT applies a constant bit distance to the answer for" echo "display purposes, and the PREFIX is also purely for display purposes." } getcidr() ( # This function gets the cidr from an octet value passed in. local octet=${1} local bits=0 local i local x
# Convert the octet to cidr. x=0; for i in 128 64 32 16 8 4 2 1; do x=$((${x}+1)) if [ ${octet} -ge ${i} ]; then bits=$x octet=$((${octet}-${i})) fi done
return ${bits} )
getcidrfromcommonbits() { # This routine gets 2 passed in parameters, the octet starting # and ending values. # The purpose of the routine is to find the common bits between # the start and end values and form a cidr that encompasses the # entire range. local start=${1} local end=${2}
[ ${start} -eq ${end} ] && return 8
local startbits[] local endbits[] local i local x local cidr=0
# Convert the start and end values into bits. x=0 for i in 128 64 32 16 8 4 2 1; do if [ ${start} -ge ${i} ]; then startbits[${x}]="1" start=$((${start}-${i})) else startbits[${x}]="0" fi let "x+=1" done x=0 for i in 128 64 32 16 8 4 2 1; do if [ ${end} -ge ${i} ]; then endbits[${x}]="1" end=$((${end}-${i})) else endbits[${x}]="0" fi let "x+=1" done
# Now compare the start and end bit patterns to find # out how many left most bits they have in common. # There are always 8 bits in each string to compare. for ((x=0;x<=7;++x)); do [ "${startbits[${x}]}" != "${endbits[${x}]}" ] && break done let "cidr+=x"
# If the startbits to the right of the proposed cidr are all 0 and # the endbits to the right of the proposed cidr are all 1, then # the cidr is OK. Else, we have to increase the cidr by 1 bit. let "x+=1" while [ ${x} -le 7 ]; do [ "${startbits[${x}]}" != "0" ] && break [ "${endbits[${x}]}" != "1" ] && break let "x+=1" done if [ ${x} -le 7 ]; then let "cidr+=1" fi
return ${cidr} }
getdisp() { # Get the displacement from the passed in cidr value. return $(((2**(8-${1}))-1)) }
[ $# -ne 4 ] && syntax && exit 1
# For each possible IP octet in the range do the following: i=${1} while [ $i -le ${2} ]; do #echo "IP=$i" getcidr ${i} cidr=$? #echo "cidr=${cidr}" getdisp ${cidr} displacement=$? #echo "displacement==${displacement}" endpoint=$((${i}+${displacement})) #echo "endpoint=${endpoint}"
if [ ${endpoint} -gt ${2} ]; then # We have to shorten up the endpoint to miss it and # recalculate cidr and displacement values for that endpoint endpoint=$((${endpoint}-1)) #echo " endpoint=${endpoint}" getcidrfromcommonbits ${i} ${endpoint} cidr=$? #echo " cidr=${cidr}" getdisp ${cidr} displacement=$? #echo " displacement==${displacement}" endpoint=$((${i}+${displacement})) #echo " endpoint=${endpoint}" fi cidr=$((${cidr}+${3})) echo "${4}${i}/${cidr}" i=$((${endpoint}+1)) done
-- Bill Gradwohl bill@xxxxxxx http://www.ycc.com spamSTOMPER Protected email