Find free ip: Difference between revisions

From Lolly's Wiki
Jump to navigationJump to search
No edit summary
m (Text replacement - "</source" to "</syntaxhighlight")
Line 168: Line 168:
   fi
   fi
done
done
</source>
</syntaxhighlight>

Revision as of 17:53, 25 November 2021

find_free_ip <source lang=bash>

  1. !/bin/bash
  1. $Id: find_free_ip.sh,v 1.2 2019/09/06 14:33:32 lollypop Exp $
  2. $Source: /var/cvs/lollypop/scripts/linux/find_free_ip.sh,v $
  3. Written in 2019 by Lars Timmann <L@rs.Timmann.de>

function usage () {

 printf "Usage: ${0} <ip address>[/(<CIDR suffix>|<netmask>)]\n\n"
 printf "  This script searches a range of IP addresses for ones that have no reverse DNS.\n"
 printf "  Default range if no CIDR suffix or netmask is given is a class C (/24) range of 256 addresses.\n" 
 printf "  address     : This has to be a IPv4 address. Zero octets can be omittet.\n"
 printf "                For example 192.168 is sufficient for 192.168.0.0 .\n"
 printf "  CIDR suffix : This describes the nomber of bits set to 1 from left in the netmask.\n"
 printf "  netmask     : Four octets representing the netmask.\n"
 printf "\n"

}

case ${1} in ""|--help|-h)

 usage
 exit 1
 ;;
  • )
 input=${1}
 ;;

esac

case $(uname -s) in Linux)

 PING='ping -4 -c 1 -n -q -W 1 ${ip}'
 ;;

SunOS)

 PING='ping -s -A inet -n -t 1 ${ip} 56 1'
 ;;

esac

IFS='/' read -ra parts <<< "${input}" address=${parts[0]} suffix=${parts[1]:-24}

  1. build binary notation from CIDR suffix

function ones2bin () {

 ones=${1}
 printf "%0.s1" $(seq 1 ${ones})
 [ ${ones} -lt 32 ] && printf "%0.s0" $(seq 1 $[ 32 - ${ones} ])

}

function bin2ones () {

 bin=${1}
 ones=0
 for((i=0;i<${#bin};i++))
 do
   bit=${bin:$i:1}
   [ ${bit} -eq 0 ] && break
   ones=$[ ones + 1 ]
 done
 echo ${ones}

}

  1. dezimal number to octets
  2. for example: 2130706689 -> 127.0.1.1

function dec2ipv4 () {

 ipdec=${1}
 octets=()
 for((i=24;i>=0;i-=8))
 do
   octet=$((${ipdec} >> ${i}))
   octets+=(${octet})
   ipdec=$(( ${ipdec} - ( ${octet} << ${i} ) ))
 done
 echo $(IFS=.;echo "${octets[*]}")

}

  1. ipv4 to decimal

function ipv42dec () {

 ipv4=$1
 dec=0
 IFS='.' read -ra octets <<< "${ipv4}"
 for ((i=0;i<4;i++))
 do
         dec=$(( dec + ${octets[i]} * ( 256 ** ( 3 - i ) ) ))
 done
 echo ${dec}

}

  1. decimal to binary

function dec2bin () {

 dec=$1
 bin=""
 for((i=${dec};i>0;i>>=1))
 do
   bin=$(( ${i} % 2 ))${bin}
 done
 echo ${bin}

}

  1. binary to decimal : dec = $(( 2#010001010001 ))
  1. binary complement

function binaryComplement () {

 unset complement
 binary=$1
 for((i=0;i<${#binary};i++))
 do
   complement+=$(( ${binary:${i}:1} ^ 1 ))
 done
 echo $complement

}

  1. Add missing octets

function fillOctets () {

 IFS='.' read -ra octets <<< "${1}"
 for ((i=${#octets[@]};i<4;++i))
 do
   octets+=(0)
 done
 echo "$(IFS=. ; echo "${octets[*]}")"

}

if [[ ${suffix} =~ ^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$ ]] then

 suffixbin=$(dec2bin $(ipv42dec $(fillOctets ${suffix})))

else

 suffixbin=$(ones2bin ${suffix})

fi

address=$(fillOctets ${address})

firstipdec=$(( ( $(ipv42dec ${address}) & 2#${suffixbin} ) )) network=$(dec2ipv4 ${firstipdec}) lastipdec=$(( ( $(ipv42dec ${address}) & 2#${suffixbin} ) | 2#$(binaryComplement ${suffixbin}) )) broadcast=$(dec2ipv4 ${lastipdec}) netmask=$(dec2ipv4 $(( 2#${suffixbin} )) )

printf "Your request:\t${address}/$(bin2ones ${suffixbin})\nNetwork:\t${network}\nBroadcast:\t${broadcast}\nNetmask:\t${netmask}\nSearching in:\t${network}-${broadcast}\n" printf "%0.s-" $(seq 1 80) ; echo

count=1 bool=( yes no ) for((i=${firstipdec};i<=${lastipdec};i++)) do

 ip=$(dec2ipv4 ${i})
 info=$(getent hosts ${ip})
 if [ "_${info}_" == "__" ]
 then
   eval ${PING} ${ip} >/dev/null 2>&1 ; pingable=$?
   case ${ip} in
     ${network})
       remark="This is the network IP."
       ;;
     ${broadcast})
       remark="This is the network IP."
       ;;
     *)
       remark=""
       ;;
     esac
   printf "%s\tfrei\t%d\t( got a pong: %s )\t%s\n" "${ip}" "${count}" "${bool[${pingable}]}" "${remark}"
   count=$[ ${count} + 1 ]
 else
   printf "%s\n" "${info}"
   count=1
 fi

done </syntaxhighlight>