Find free ip

From Lolly's Wiki
Revision as of 15:03, 6 September 2019 by Lollypop (talk | contribs) (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…“)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Kategorie: Bash

#!/bin/bash

#
# $Id: find_free_ip.sh,v 1.1 2019/09/06 14:00:58 lollypop Exp $
# $Source: /var/cvs/lollypop/scripts/linux/find_free_ip.sh,v $
#
# Written in 2019 by Lars Timmann <L@rs.Timmann.de>
#

input=${1}
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} ])
}

# 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 ${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}/${suffix}\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