1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
#!/bin/bash
######################################################
#
# Author: Ceasar Sun Chen-kai <ceasar@nchc.org.tw>
# License: GPL
# Description: List IP addresses from a set of given subnet and count
# Usage: ipcalc-list 192.168.21.13/24 -n 10 # to list ip from 192.168.21.13 ~ 192.168.21.22
# ChangeLog:
# * 20100603 First version
# * 20100604 Fix fisrt character of binary type ip address is 0 within first ip session
# * 20140321 Add option "-r"
######################################################
# Load DRBL setting and functions
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"
. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
[ -e /etc/drbl/drbl-ocs.conf ] && . /etc/drbl/drbl-ocs.conf
[ -e $DRBL_SCRIPT_PATH/sbin/ocs-functions ] && . $DRBL_SCRIPT_PATH/sbin/ocs-functions
######################################################
# Sub functions
######################################################
# Print usage
Usage(){
echo "$0 : List legal IP addresses from a given start IP/subnet and count";
echo "Usage: $0 <ipcalc_parameters> -c <count> [-b] [-v]";
echo " -b, --binary Binary output for IP address"
echo " -c,--count [COUNT] Amount of IP address, positive number for ascending order, negative for descending, ex: 10, -5"
echo " -r, --range <START_IP END_IP NETMASK> Assign IP range and netmask"
echo " -v, --verbose Verbose mode, if not enough IP address, show what we have"
echo ""
echo "Help options:";
echo " -h, --help Show this help message"
echo " "
echo "Example:"
echo "To list 20 ascending legal IP addresses in form 192.168.121.1/24."
echo " $0 192.168.121.1/24 -c 20"
echo "To list 3 legal descending IP addresses in form 172.16.1.32/16 and convert IP address as binary."
echo " $0 172.16.1.32 255.255.0.0 -c -3 -b"
echo "To list 10 descnding IP addresses in form 10.0.0.3/8. Nothing will be shown due to not enough addresses in the range"
echo " $0 10.0.0.3/8 -c -10"
echo "But use VERBOSE mode. Output: '10.0.0.3 10.0.0.2 10.0.0.1'"
echo " $0 10.0.0.3/8 -c -10 -v"
echo "To list all IP addresss form 172.16.0.1 to 172.16.1.46 with netmask 16. Output: '172.16.0.1 172.16.0.2 ... 172.16.1.45 172.16.1.46'"
echo " $0 -r 172.16.0.1 172.16.1.46 255.255.0.0 (or: $0 -r 172.16.0.1 172.16.1.46 16)"
echo ""
echo "ipcalc_parameters : <start_ip netmask> or <start_ip/netmask>"
echo " <start_ip netmask> , ex: 192.168.11.1 255.255.255.0"
echo "the same with "
echo " <start_ip/netmask> , ex: 192.168.11.1/24"
}
######################################################
#Main
######################################################
declare _OUTPUT_MODE _VERBOSE _COUNT _IPCALC_PARM _IP_START _IP_END _NETMASK
declare -a _IP_ARRAY
declare __VERSION='1.0.0'
declare _OUTPUT_MODE=d
declare _VERBOSE=0
declare _COUNT=1
[ $# -eq 0 ] && Usage && exit 1;
while [ $# -gt 0 ]; do
case "$1" in
-b|--binary)
shift; _OUTPUT_MODE="b";
;;
-c|--count)
shift;
if [[ $1 =~ ^-*[[:digit:]]+$ ]]; then
_COUNT=$1
else
echo "Illegal value for option \"-c\"." >&2
Usage; exit 1;
fi
shift;
;;
-h|--help)
Usage;
exit;
;;
-r|--range)
shift;
if [[ $1 =~ ^[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}$ ]] ; then
_IP_START=$1
else
echo "Illegal 'Start' IP format !?" >&2
Usage; exit 1;
fi
shift;
if [[ $1 =~ ^[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}$ ]] ; then
_IP_END=$1
else
echo "Illegal 'End' IP format !?" >&2
Usage; exit 1;
fi
shift;
if [[ $1 =~ ^[[:digit:]]{1,2}$ ]] && [ $1 -le 30 ] ; then
_NETMASK=$1
elif [[ $1 =~ ^[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}$ ]] ; then
_NETMASK=$1
else
echo "Illegal netmask format !?" >&2
Usage; exit 1;
fi
shift;
;;
-v|--verbose)
shift; _VERBOSE=1;
;;
*)
[ -n "$_IPCALC_PARM" ] && _IPCALC_PARM="$_IPCALC_PARM $1" || _IPCALC_PARM="$1";
shift;
;;
esac
done
# chek if ipcalc_parameters format : '192.168.11.1 255.255.255.0' or '192.168.11.1/24'
# or not list a range of IPs
if [ -n "$_IP_START" -a -n "$_IP_END" ] ; then
real_bin_start_ip="$(drbl-ipcalc $_IP_START/0 | grep -E "^Address:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
real_dec_start_ip="$(LC_ALL=C echo "ibase=2; obase=A; $real_bin_start_ip" | bc)"
real_bin_end_ip="$(drbl-ipcalc $_IP_END/0 | grep -E "^Address:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
real_dec_end_ip="$(LC_ALL=C echo "ibase=2; obase=A; $real_bin_end_ip" | bc)"
[ "$(expr $real_dec_end_ip - $real_dec_start_ip)" -ge 0 ] && _COUNT="$(expr $real_dec_end_ip - $real_dec_start_ip + 1)" || _COUNT="$(expr $real_dec_end_ip - $real_dec_start_ip - 1)"
_IPCALC_PARM="${_IP_START}/${_NETMASK}"
_VERBOSE=1
fi
#echo "_IPCALC_PARM='$_IPCALC_PARM' ; _COUNT='$_COUNT' "
if [ -z "$(echo $_IPCALC_PARM | grep -E '^[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}\/[[:digit:]]{1,2}$')" ] && [ -z "$(echo $_IPCALC_PARM | grep -E '^[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}[[:space:]]+[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}$')" ] && [ -z "$_IP_START" -o -z "$_IP_END" ]; then
echo "Illegal parameters for ipcalc!" >&2
Usage; exit 1;
fi
# Add "1" on first string for solve if the fisrt session of ip is 0xxxxxxx.~
#
# Exit when it gave an invild netmask
[[ -n "$(LC_ALL=C drbl-ipcalc $_IPCALC_PARM | grep -E "^INVALID MASK")" ]] && echo "Illegal parameters for netmask:'$_IPCALC_PARM'" >&2 && exit 1;
bin_start_ip=1"$(LC_ALL=C drbl-ipcalc $_IPCALC_PARM | grep -E "^Address:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
dec_start_ip="$(LC_ALL=C echo "ibase=2; obase=A; $bin_start_ip" | bc)"
bin_max_ip=1"$(LC_ALL=C drbl-ipcalc $_IPCALC_PARM | grep -E "^HostMax:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
dec_max_ip="$(LC_ALL=C echo "ibase=2; obase=A; $bin_max_ip" | bc)"
bin_min_ip=1"$(LC_ALL=C drbl-ipcalc $_IPCALC_PARM | grep -E "^HostMin:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
dec_min_ip="$(LC_ALL=C echo "ibase=2; obase=A; $bin_min_ip" | bc)"
bin_network_ip=1"$(LC_ALL=C drbl-ipcalc $_IPCALC_PARM | grep -E "^Network:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
dec_network_ip="$(LC_ALL=C echo "ibase=2; obase=A; $bin_network_ip" | bc)"
bin_broadcast_ip=1"$(LC_ALL=C drbl-ipcalc $_IPCALC_PARM | grep -E "^Broadcast:" | awk -F" " '{print $3 $4 }'| sed -e "s/\.//g")"
dec_broadcast_ip="$(LC_ALL=C echo "ibase=2; obase=A; $bin_broadcast_ip" | bc)"
#echo "$_OUTPUT_MODE, $_VERBOSE, $_COUNT, '$_IPCALC_PARM', $dec_start_ip, $dec_min_ip, $dec_max_ip";
if [[ $_COUNT =~ ^[[:digit:]]+$ ]]; then
for ((i=0; i<$_COUNT; i++)) ;do
dec_current_ip=$(expr $dec_start_ip + $i)
if [ $dec_max_ip -ge $dec_current_ip ] && [ $dec_min_ip -le $dec_current_ip ] && [ $dec_network_ip -ne $dec_current_ip ] && [ $dec_broadcast_ip -ne $dec_current_ip ]; then
_tmp_bin_ip="$(LC_ALL=C echo "ibase=A; obase=2; $dec_current_ip" | bc)"
_IP_ARRAY[${#_IP_ARRAY[*]}]=${_tmp_bin_ip:1:32}
elif [ $_VERBOSE = 0 ] ; then
_IP_ARRAY=() ; echo "Not enough IP addresses to output!" >&2
exit 1;
fi
done
else
for ((i=0; i>$_COUNT; i--)) ;do
dec_current_ip=$(expr $dec_start_ip + $i)
if [ $dec_max_ip -ge $dec_current_ip ] && [ $dec_min_ip -le $dec_current_ip ] && [ $dec_network_ip -ne $dec_current_ip ] && [ $dec_broadcast_ip -ne $dec_current_ip ]; then
_tmp_bin_ip=`echo "ibase=A; obase=2; $dec_current_ip" | bc`
_IP_ARRAY[${#_IP_ARRAY[*]}]=${_tmp_bin_ip:1:32}
elif [ $_VERBOSE = 0 ] ; then
_IP_ARRAY=() ; echo "Not enough IP addresses to output!" >&2
exit 1;
fi
done
fi
for ((i=0; i<${#_IP_ARRAY[*]}; i++)) ;do
[ $_OUTPUT_MODE = 'b' ] && p1=${_IP_ARRAY[$i]:0:8} || p1="$(echo "ibase=2; obase=A; ${_IP_ARRAY[$i]:0:8}" | bc )"
[ $_OUTPUT_MODE = 'b' ] && p2=${_IP_ARRAY[$i]:8:8} || p2="$(echo "ibase=2; obase=A; ${_IP_ARRAY[$i]:8:8}" | bc )"
[ $_OUTPUT_MODE = 'b' ] && p3=${_IP_ARRAY[$i]:16:8} || p3="$(echo "ibase=2; obase=A; ${_IP_ARRAY[$i]:16:8}" | bc )"
[ $_OUTPUT_MODE = 'b' ] && p4=${_IP_ARRAY[$i]:24:8} || p4="$(echo "ibase=2; obase=A; ${_IP_ARRAY[$i]:24:8}" | bc )"
echo $p1.$p2.$p3.$p4
done
exit 0;
|