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 |