Bash script to list all IPs in prefix Bash script to list all IPs in prefix bash bash

Bash script to list all IPs in prefix


Here is what I use to generate all the IP addresses in a given CIDR block

nmap -sL -n 10.10.64.0/27 | awk '/Nmap scan report/{print $NF}'

From the nmap man page, the flags are:

-sL: List Scan - simply list targets to scan-n: Never do DNS resolution

Just that simple

The above command outputs this

10.10.64.010.10.64.110.10.64.210.10.64.310.10.64.410.10.64.510.10.64.610.10.64.710.10.64.810.10.64.910.10.64.1010.10.64.1110.10.64.1210.10.64.1310.10.64.1410.10.64.1510.10.64.1610.10.64.1710.10.64.1810.10.64.1910.10.64.2010.10.64.2110.10.64.2210.10.64.2310.10.64.2410.10.64.2510.10.64.2610.10.64.2710.10.64.2810.10.64.2910.10.64.3010.10.64.31


I too was looking for this solution and found that @scherand script worked great. I also have added to this script to give you more option. Help File below.

THIS SCRIPT WILL EXPAND A CIDR ADDRESS.

SYNOPSIS

./cidr-to-ip.sh [OPTION(only one)] [STRING/FILENAME]

DESCRIPTION

-h Displays this help screen

-f Forces a check for network boundary when given a STRING(s)

-i Will read from an Input file (file should contain one CIDR per line) (no network boundary check)

-b Will do the same as –i but with network boundary check

EXAMPLES

./cidr-to-ip.sh 192.168.0.1/24

./cidr-to-ip.sh 192.168.0.1/24 10.10.0.0/28

./cidr-to-ip.sh -f 192.168.0.0/16

./cidr-to-ip.sh -i inputfile.txt

./cidr-to-ip.sh -b inputfile.txt

#!/bin/bash    ##############################  Methods############################   prefix_to_bit_netmask() {    prefix=$1;    shift=$(( 32 - prefix ));    bitmask=""    for (( i=0; i < 32; i++ )); do        num=0        if [ $i -lt $prefix ]; then            num=1        fi        space=        if [ $(( i % 8 )) -eq 0 ]; then            space=" ";        fi        bitmask="${bitmask}${space}${num}"    done    echo $bitmask}bit_netmask_to_wildcard_netmask() {    bitmask=$1;    wildcard_mask=    for octet in $bitmask; do        wildcard_mask="${wildcard_mask} $(( 255 - 2#$octet ))"    done    echo $wildcard_mask;}check_net_boundary() {    net=$1;    wildcard_mask=$2;    is_correct=1;    for (( i = 1; i <= 4; i++ )); do        net_octet=$(echo $net | cut -d '.' -f $i)        mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)        if [ $mask_octet -gt 0 ]; then            if [ $(( $net_octet&$mask_octet )) -ne 0 ]; then                is_correct=0;            fi        fi    done    echo $is_correct;}#########################  MAIN#######################OPTIND=1;getopts "fibh" force;shift $((OPTIND-1))if [ $force = 'h' ]; then    echo ""    echo -e "THIS SCRIPT WILL EXPAND A CIDR ADDRESS.\n\nSYNOPSIS\n  ./cidr-to-ip.sh [OPTION(only one)] [STRING/FILENAME]\nDESCRIPTION\n -h  Displays this help screen\n -f  Forces a check for network boundary when given a STRING(s)\n    -i  Will read from an Input file (no network boundary check)\n  -b  Will do the same as –i but with network boundary check\n\nEXAMPLES\n    ./cidr-to-ip.sh  192.168.0.1/24\n   ./cidr-to-ip.sh  192.168.0.1/24 10.10.0.0/28\n  ./cidr-to-ip.sh  -f 192.168.0.0/16\n    ./cidr-to-ip.sh  -i inputfile.txt\n ./cidr-to-ip.sh  -b inputfile.txt\n"    exitfiif [ $force = 'i' ] || [ $force = 'b' ]; then    old_IPS=$IPS    IPS=$'\n'    lines=($(cat $1)) # array    IPS=$old_IPS        else            lines=$@fifor ip in ${lines[@]}; do    net=$(echo $ip | cut -d '/' -f 1);    prefix=$(echo $ip | cut -d '/' -f 2);    do_processing=1;    bit_netmask=$(prefix_to_bit_netmask $prefix);    wildcard_mask=$(bit_netmask_to_wildcard_netmask "$bit_netmask");    is_net_boundary=$(check_net_boundary $net "$wildcard_mask");    if [ $force = 'f' ] && [ $is_net_boundary -ne 1 ] || [ $force = 'b' ] && [ $is_net_boundary -ne 1 ] ; then        read -p "Not a network boundary! Continue anyway (y/N)? " -n 1 -r        echo    ## move to a new line        if [[ $REPLY =~ ^[Yy]$ ]]; then            do_processing=1;        else            do_processing=0;        fi    fi      if [ $do_processing -eq 1 ]; then        str=        for (( i = 1; i <= 4; i++ )); do            range=$(echo $net | cut -d '.' -f $i)            mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)            if [ $mask_octet -gt 0 ]; then                range="{$range..$(( $range | $mask_octet ))}";            fi            str="${str} $range"        done        ips=$(echo $str | sed "s, ,\\.,g"); ## replace spaces with periods, a join...        eval echo $ips | tr ' ' '\n'elseexit    fidone


This short script will print all the IP addresses in a CIDR range in a few lines of Bash. (I named it prips after the Ubuntu command of the same name. Obviously, if that command is available, use that.)

prips() {  local cidr="$1" ; local lo hi a b c d e f g h  # range is bounded by network (-n) & broadcast (-b) addresses.  lo=$(ipcalc -n "$cidr" | cut -f2 -d=)  hi=$(ipcalc -b "$cidr" | cut -f2 -d=)  IFS=. read -r a b c d <<< "$lo"  IFS=. read -r e f g h <<< "$hi"  eval "echo {$a..$e}.{$b..$f}.{$c..$g}.{$d..$h}"}

Note that I assume the RedHat Linux (Erik Troan, Preston Brown) version of ipcalc, not the Krischan Jodies version that is installed on some platforms (e.g. Mac OS X).

Examples:

$ prips 10.0.0.128/2710.0.0.128 10.0.0.129 10.0.0.130 10.0.0.131 10.0.0.132 10.0.0.133 10.0.0.134 10.0.0.135 10.0.0.136 10.0.0.137 10.0.0.138 10.0.0.139 10.0.0.140 10.0.0.141 10.0.0.142 10.0.0.143 10.0.0.144 10.0.0.145 10.0.0.146 10.0.0.147 10.0.0.148 10.0.0.149 10.0.0.150 10.0.0.151 10.0.0.152 10.0.0.153 10.0.0.154 10.0.0.155 10.0.0.156 10.0.0.157 10.0.0.158 10.0.0.159

Calculates correct number of addresses in a /23 networks:

$ prips 10.0.0.0/23 | wc -w 512

Inspecting a few of those addresses using cut:

$ prips 10.0.0.0/23 | cut -f1-10,256-266 -d' '10.0.0.0 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 10.0.0.6 10.0.0.7 10.0.0.8 10.0.0.9 10.0.0.255 10.0.1.0 10.0.1.1 10.0.1.2 10.0.1.3 10.0.1.4 10.0.1.5 10.0.1.6 10.0.1.7 10.0.1.8 10.0.1.9

And maybe too slow but also correctly generates the 16 million addresses in a /8 network:

$ date ; prips 10.0.0.0/8 | wc -w ; date Sat May 20 18:06:00 AEST 201716777216Sat May 20 18:06:41 AEST 2017