Get IP list from CIDR

Dear Srs :slight_smile:

I'm looking for a shell script, that given a network in CIDR format it lists all IPs, for example:

Preferredly a shell script, but a Perl, Python, C, etc.. is also welcome :slight_smile:

I have been looking in sipcalc, ipcalc, etc.. options but this feature is not implemented :frowning:

Regards,

ip=$( echo $1 | cut -d"/" -f1 )
no=$( echo $1 | cut -d"/" -f2 )
num=1
new_ip=$( echo $ip | cut -d"." -f1-3 )

while [[ $num -ne $no ]]
do
	echo $new_ip".$num"
	(( num = num + 1 ))
done

I'm afraid it's not that easy, anbu23. That works only for class C addresses :slight_smile:
I'll try to write a script and post it, but I'll need some time :wink:
Regards.

Thanks for the fast reply!! But it doesnt works with all CIDR.. for this simple example:

Complete list according to this network must be:

I have found this module for Perl, but I prefer a shell script:

Regards,

checkout this script

ip=$( echo $1 | cut -d"/" -f1 )
no=$( echo $1 | cut -d"/" -f2 )
k=`expr 32 - $no`
nu=$(echo "2 ^ $k" | bc)
num=1
new_ip=$( echo $ip | cut -d"." -f1-3 )
while [[ $num -ne $nu ]]
do
echo $new_ip".$num"
(( num = num + 1 ))
done

Krrishv , this scripts works fine for CIDR from /24 to /32, but for bigger networks it doenst work, example:

Thanks anyway, regards :slight_smile:

yeah i will get u that script soon.

Hi again.
I hope this script do the trick:

#!/bin/bash

function addzeros {
   NUM=$1
   ZS=$2
   NBITS=$(echo "$NUM" | grep -o "[0-9]" | wc -l)
   if (( $NBITS < $ZS )); then
      ZEROS2ADD=$(expr $ZS - $NBITS)
      while (( $ZEROS2ADD << 0 )); do
         NUM="0$NUM"
         ZEROS2ADD=$(expr $ZEROS2ADD - 1)
      done
      echo "$NUM"
   else
      echo $NUM
   fi
}

function bin2dec {
   echo "obase=10; ibase=2; $1" | bc
}
function dec2bin {
   echo "obase=2; $1" | bc
}

function ipbin2ip {
   cont=1
   for l in $(echo $1 | grep -o [0,1]); do
      VIPTMP[$cont]=$l
      cont=$(expr $cont + 1)
   done
   ONE=`bin2dec $(echo ${VIPTMP[@]:1:8} | tr -d [:space:])`
   TWO=`bin2dec $(echo ${VIPTMP[@]:9:8} | tr -d [:space:])`
   THREE=`bin2dec $(echo ${VIPTMP[@]:17:8} | tr -d [:space:])`
   FOUR=`bin2dec $(echo ${VIPTMP[@]:25:8} | tr -d [:space:])`
   echo ${ONE}.${TWO}.${THREE}.${FOUR}
}

IPCIDR=$1
IP=$(echo $IPCIDR | cut -d"/" -f1)
BITS=$(echo $IPCIDR | cut -d"/" -f2)

FST=$(echo $IP | cut -d"." -f1)
FSTBIN=`addzeros $(echo "obase=2; $FST" | bc) 8`
SND=$(echo $IP | cut -d"." -f2)
SNDBIN=`addzeros $(echo "obase=2; $SND" | bc) 8`
TRD=$(echo $IP | cut -d"." -f3)
TRDBIN=`addzeros $(echo "obase=2; $TRD" | bc) 8`
FOH=$(echo $IP | cut -d"." -f4)
FOHBIN=`addzeros $(echo "obase=2; $FOH" | bc) 8`

VIP=0.0.0.0
IPBIN="$FSTBIN$SNDBIN$TRDBIN$FOHBIN"

i=1
for l in $(echo $IPBIN | grep -o [0,1]); do
   VIPBIN[$i]="$l"
   i=$(expr $i + 1)
done

BITSHOST=$(expr 32 - $BITS)
i=$BITSHOST
while (( $i > 0 )); do
   MAXHOSTBIN=1$MAXHOSTBIN
   i=$(expr $i - 1)
done
MAXHOST=$(bin2dec $MAXHOSTBIN)

n=$(echo ${VIPBIN[@]:1:$BITS} | tr -d [:space:])
c=$MAXHOST
while (( $c > 0 )); do
   h=$c
   EUREKA=${n}$(addzeros `dec2bin $h` $BITSHOST)
   ipbin2ip "$EUREKA"
   c=$(expr $c - 1)
done

As you can guess, it's been written for bash/Linux.

$ ./cidr.sh 192.168.0.0/19
192.168.31.255
192.168.31.254
192.168.31.253
192.168.31.252
192.168.31.251
192.168.31.250
192.168.31.249
192.168.31.248
192.168.31.247
(...)

Though, I'm pretty sure there are several other (and much better and efficient) ways to do it! :slight_smile:
Regards.

great work grial. this is perfect.

Here is a revision of that will run without GNU grep. It also runs a little bit faster but it is still slow.

#!/usr/local/bin/bash
shopt -s extglob

oct2bin=("000" "001" "010" "011" "100" "101" "110" "111")

function squishtogether {
        result=""
        while (($#)) ; do
                result="${result}${1}"
                shift
        done
        echo $result
}

function splitapart {
        string=$1
        result=""
        while ((${#string})) ; do
                rest=${string#?}
                chr=${string%$rest}
                if [[ -z $result ]] ; then
                        result=$chr
                else
                        result="${result} ${chr}"
                fi
                string=$rest
        done
        echo $result
}

function addzeros {
# will also remove zeros if needed
        ZS=$2
        NUM=$1
        NUM=${NUM##+(0)}
        NUM=$(printf "%0${ZS}d\n" $NUM)
        echo $NUM
}

function bin2dec {
        string="2#${1}"
        ((idec=$string))
        echo $idec
}

function dec2bin {
        result=""
        for i in $(splitapart $(printf "%3o" $1)) ; do
                result="${result}${oct2bin}"
        done
        echo $result
}

function ipbin2ip {
   cont=1
   for l in $(splitapart $1); do
      VIPTMP[$cont]=$l
      ((cont=cont+1))
   done
   ONE=`bin2dec $(squishtogether ${VIPTMP[@]:1:8})`
   TWO=`bin2dec $(squishtogether ${VIPTMP[@]:9:8})`
   THREE=`bin2dec $(squishtogether ${VIPTMP[@]:17:8})`
   FOUR=`bin2dec $(squishtogether ${VIPTMP[@]:25:8})`
   echo ${ONE}.${TWO}.${THREE}.${FOUR}
}
IPCIDR=$1
IP=${IPCIDR%/*}
BITS=${IPCIDR#*/}

FST=${IP%%.*}
IP=${IP#*.}
FSTBIN=`addzeros $(dec2bin "$FST") 8`
SND=${IP%%.*}
IP=${IP#*.}
SNDBIN=`addzeros $(dec2bin "$SND") 8`
TRD=${IP%%.*}
FOH=${IP#*.}
TRDBIN=`addzeros $(dec2bin "$TRD") 8`
FOHBIN=`addzeros $(dec2bin "$FOH") 8`

VIP=0.0.0.0
IPBIN="$FSTBIN$SNDBIN$TRDBIN$FOHBIN"

i=1
for l in $(splitapart $IPBIN); do
   VIPBIN[$i]="$l"
   ((i=i+1))
done

BITSHOST=$(expr 32 - $BITS)
i=$BITSHOST
while (( $i > 0 )); do
   MAXHOSTBIN=1$MAXHOSTBIN
   ((i=i-1))
done
MAXHOST=$(bin2dec $MAXHOSTBIN)

n=$(squishtogether ${VIPBIN[@]:1:$BITS})
c=$MAXHOST
while (( $c > 0 )); do
   h=$c
   EUREKA=${n}$(addzeros `dec2bin $h` $BITSHOST)
   ipbin2ip "$EUREKA"
   c=$(expr $c - 1)
done

I have found a excellent utility to get a list of IPs from CIDR:

An output example:

Regards,