Find free ip: Difference between revisions
From Lolly's Wiki
Jump to navigationJump to search
(Die Seite wurde neu angelegt: „Kategorie: Bash <source lang=bash> #!/bin/bash # # $Id: find_free_ip.sh,v 1.1 2019/09/06 14:00:58 lollypop Exp $ # $Source: /var/cvs/lollypop/scripts/linu…“) |
m (Text replacement - "[[Kategorie:" to "[[Category:") |
||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[[ | [[Category: Bash|find_free_ip]] | ||
< | <syntaxhighlight lang=bash> | ||
#!/bin/bash | #!/bin/bash | ||
# | # | ||
# $Id: find_free_ip.sh,v 1. | # $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 $ | # $Source: /var/cvs/lollypop/scripts/linux/find_free_ip.sh,v $ | ||
# | # | ||
Line 10: | Line 10: | ||
# | # | ||
input=${1} | 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 | case $(uname -s) in | ||
Linux) | Linux) | ||
Line 29: | Line 49: | ||
printf "%0.s1" $(seq 1 ${ones}) | printf "%0.s1" $(seq 1 ${ones}) | ||
[ ${ones} -lt 32 ] && printf "%0.s0" $(seq 1 $[ 32 - ${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} | |||
} | } | ||
Line 93: | Line 125: | ||
if [[ ${suffix} =~ ^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$ ]] | if [[ ${suffix} =~ ^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$ ]] | ||
then | then | ||
suffixbin=$(dec2bin $(ipv42dec ${suffix})) | suffixbin=$(dec2bin $(ipv42dec $(fillOctets ${suffix}))) | ||
else | else | ||
suffixbin=$(ones2bin ${suffix}) | suffixbin=$(ones2bin ${suffix}) | ||
Line 106: | Line 138: | ||
netmask=$(dec2ipv4 $(( 2#${suffixbin} )) ) | netmask=$(dec2ipv4 $(( 2#${suffixbin} )) ) | ||
printf "Your request:\t${address}/${ | 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 | printf "%0.s-" $(seq 1 80) ; echo | ||
Line 136: | Line 168: | ||
fi | fi | ||
done | done | ||
</ | </syntaxhighlight> |
Latest revision as of 00:07, 26 November 2021
#!/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