#!/bin/ksh set -o errexit -o pipefail -o nounset -o noclobber -o noglob set +o monitor export PATH=/usr/bin:/bin:/usr/sbin:/sbin # Convert the IP to an integer so do calculations on it dottedQuad2int() { local IFS=. local ip set -A ip $* 0 0 0 0 echo $(( (${ip[0]}<<24) + (${ip[1]}<<16) + (${ip[2]}<<8) + ${ip[3]} )) } int2dottedQuad() { local int=$1 local ip="" for b in 24 16 8 0; do ip="$ip.$(( int >> b & 0xff ))" done echo ${ip#.} } netmask2cidr() { local c m n=$( dottedQuad2int "$1" ) typeset -i2 n typeset -i10 c=0 m=${n#2#} while [[ $m = 1* ]]; do c=$((++c)) m=${m#1} done if (( m != 0 )); then echo "Invalid netmask!" >&2 exit 1 fi echo "$c" } ip=$1 cidr=${2:-} [ -z "$cidr" ] && [[ $ip = */* ]] && cidr=${ip#*/} [[ $cidr = *.* ]] && cidr=$( netmask2cidr "$cidr" ) if (( cidr > 32 )); then echo "Invalid netmask!" >&2 exit 1 fi ip=${ip%/*} ip=$(dottedQuad2int "$ip" ) integer ip integer cidr integer netmask=$(( 0xFFFFFFFF << (32 - cidr) )) integer network="$(( ip & netmask & 0xFFFFFFFF ))" integer broadcast="$(( ip | ~netmask & 0xFFFFFFFF ))" echo "IP: $( int2dottedQuad "$ip" )/$cidr" echo "Netmask: $( int2dottedQuad "$netmask" )" echo "Network: $( int2dottedQuad "$network" )" echo "Broadcast: $( int2dottedQuad "$broadcast" )" (( cidr > 30 )) && exit integer i=$(( network & ~netmask )) integer e=$(( broadcast & ~netmask )) echo "IPs: ($(( e - i - 1 )))" # start with the first IP after the network address # end one before the broadcast address while (( i < e -1 )); do i=$((i + 1)) echo -n " " int2dottedQuad $(( network + i )) done