Last active
December 11, 2020 04:50
-
-
Save thom-nic/2556a6cc3865fba6330f61b802438c05 to your computer and use it in GitHub Desktop.
Generate all IPv4 addresses in bash from a CIDR or netmask
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -ue | |
# Modified "CIDR to IP range" function taken from https://stackoverflow.com/a/18120519/213983 | |
# use like `cidr_iter "192.168.1.1/24"` | |
cidr_iter() { | |
# create array containing network address and subnet | |
local network=(${1//\// }) | |
# split network address by dot | |
local iparr=(${network[0]//./ }) | |
# if no mask given it's the same as /32 | |
local mask=32 | |
[[ $((${#network[@]})) -gt 1 ]] && mask=${network[1]} | |
# convert dot-notation subnet mask or convert CIDR to an array like (255 255 255 0) | |
local maskarr | |
if [[ ${mask} = '\.' ]]; then # already mask format like 255.255.255.0 | |
maskarr=(${mask//./ }) | |
else # assume CIDR like /24, convert to mask | |
if [[ $((mask)) -lt 8 ]]; then | |
maskarr=($((256-2**(8-mask))) 0 0 0) | |
elif [[ $((mask)) -lt 16 ]]; then | |
maskarr=(255 $((256-2**(16-mask))) 0 0) | |
elif [[ $((mask)) -lt 24 ]]; then | |
maskarr=(255 255 $((256-2**(24-mask))) 0) | |
elif [[ $((mask)) -lt 32 ]]; then | |
maskarr=(255 255 255 $((256-2**(32-mask)))) | |
elif [[ ${mask} == 32 ]]; then | |
maskarr=(255 255 255 255) | |
fi | |
fi | |
# correct wrong subnet masks (e.g. 240.192.255.0 to 255.255.255.0) | |
[[ ${maskarr[2]} == 255 ]] && maskarr[1]=255 | |
[[ ${maskarr[1]} == 255 ]] && maskarr[0]=255 | |
# generate list of ip addresses | |
local bytes=(0 0 0 0) | |
for i in $(seq 0 $((255-maskarr[0]))); do | |
bytes[0]="$(( i+(iparr[0] & maskarr[0]) ))" | |
for j in $(seq 0 $((255-maskarr[1]))); do | |
bytes[1]="$(( j+(iparr[1] & maskarr[1]) ))" | |
for k in $(seq 0 $((255-maskarr[2]))); do | |
bytes[2]="$(( k+(iparr[2] & maskarr[2]) ))" | |
for l in $(seq 1 $((255-maskarr[3]))); do | |
bytes[3]="$(( l+(iparr[3] & maskarr[3]) ))" | |
printf "%d.%d.%d.%d\n" "${bytes[@]}" | |
done | |
done | |
done | |
done} | |
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then | |
set -o pipefail | |
cidr_iter "$@" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment