Find free ip
find_free_ip <source lang=bash>
- !/bin/bash
- $Id: find_free_ip.sh,v 1.2 2019/09/06 14:33:32 lollypop Exp $
- $Source: /var/cvs/lollypop/scripts/linux/find_free_ip.sh,v $
- 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}
- 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}
}
- dezimal number to octets
- 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[*]}")
}
- 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}
}
- decimal to binary
function dec2bin () {
dec=$1 bin="" for((i=${dec};i>0;i>>=1)) do bin=$(( ${i} % 2 ))${bin} done echo ${bin}
}
- binary to decimal : dec = $(( 2#010001010001 ))
- binary complement
function binaryComplement () {
unset complement binary=$1 for((i=0;i<${#binary};i++)) do complement+=$(( ${binary:${i}:1} ^ 1 )) done echo $complement
}
- 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>