How to break down CIDR subnets in Bash
I was playing around with subnets in bash recently and needed an elegant/easy way to split up a subnet into smaller subnets. First I used 2 functions I found on stackoverflow.com to convert an IP addresse to and from an integer. After that it was just a bit of math in bash to split up any networks too big.
Any network larger than $maxSubnet gets split up.
Here the useful code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/bin/bash
. functions_ip2long.sh
input='10.1.4.0/22 10.2.2.0/24 10.3.3.128/25'
output=
maxSubnet=24
for pair in ${input}
do
# split up the network and netmask
network=${pair%/*}
netmask=${pair#*/}
if [[ ${netmask} -ge ${maxSubnet} ]]
then # network is smaller than max. size. add it to the array
output="${output} ${network}/${netmask}"
else # network is too big. split it up into smaller chunks and add them to the array
for i in $(seq 0 $(( $(( 2 ** (${maxSubnet} - ${netmask}) )) - 1 )) )
do # convert network to long integer, add n * ${maxSubnet} and then convert back to string
output="${output} $( INET_NTOA $(( $( INET_ATON ${network} ) + $(( 2 ** ( 32 - ${maxSubnet} ) * ${i} )) )) )/${maxSubnet}"
done
fi
done
echo ${output}|tr ' ' '\n'
|
Output of script:
1
2
3
4
5
6
|
10.1.4.0/24
10.1.5.0/24
10.1.6.0/24
10.1.7.0/24
10.2.2.0/24
10.3.3.128/25
|