Per passare da una netmask IPV4 a l'equivalente CIDR potrebbe venir in mente di fare la cosa più semplice ovvero utilizzare un blocco case o degli if annidati per ottenere il CIDR equivalente tanto i netmask o CIDR disponibili sono solo 32 e cioè
Netmask | Address/CIDR | Adresses |
255.255.255.255 | a.b.c.d/32 | 20 |
255.255.255.254 | a.b.c.d/31 | 20 |
255.255.255.252 | a.b.c.d/30 | 21 |
255.255.255.248 | a.b.c.d/29 | 22 |
255.255.255.240 | a.b.c.d/28 | 23 |
255.255.255.224 | a.b.c.d/27 | 24 |
255.255.255.192 | a.b.c.d/26 | 25 |
255.255.255.128 | a.b.c.d/25 | 26 |
255.255.255.0 | a.b.c.0/24 | 27 |
255.255.254.0 | a.b.c.0/23 | 28 |
255.255.252.0 | a.b.c.0/22 | 29 |
255.255.248.0 | a.b.c.0/21 | 210 |
255.255.240.0 | a.b.c.0/20 | 212 |
255.255.224.0 | a.b.c.0/19 | 213 |
255.255.192.0 | a.b.c.0/18 | 214 |
255.255.128.0 | a.b.c.0/17 | 215 |
255.255.0.0 | a.b.0.0/16 | 216 |
255.254.0.0 | a.b.0.0/15 | 217 |
255.252.0.0 | a.b.0.0/14 | 218 |
255.248.0.0 | a.b.0.0/13 | 219 |
255.240.0.0 | a.b.0.0/12 | 220 |
255.224.0.0 | a.b.0.0/11 | 221 |
255.192.0.0 | a.b.0.0/10 | 222 |
255.128.0.0 | a.b.0.0/9 | 223 |
255.0.0.0 | a.0.0.0/8 | 224 |
254.0.0.0 | a.0.0.0/7 | 225 |
252.0.0.0 | a.0.0.0/6 | 226 |
248.0.0.0 | a.0.0.0/5 | 227 |
240.0.0.0 | a.0.0.0/4 | 228 |
224.0.0.0 | a.0.0.0/3 | 229 |
192.0.0.0 | a.0.0.0/2 | 230 |
128.0.0.0 | a.0.0.0/1 | 231 |
0.0.0.0 | 0.0.0.0/0 | 232 |
Se vogliamo, invece, realizzare una funzione che converta il netmask in CIDR abbiamo bisogno di sapere come convertire un numero decimale in binario come prima cosa.
fromNetmaskToCidr() {
local netmask=$1
local bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
local b=''
local n
local cidr
for n in ${netmask//./ }; do
if [ $n -gt 255 ]; then
echo -e "\t[ERROR] netmask $netmask format error in '.$n'. I will use .255 insted of .$n"
n=255
fi
if [ $n -ne 0 -a $n -ne 128 -a $n -ne 192 -a $n -ne 224 -a $n -ne 240 -a $n -ne 248 -a $n -ne 252 -a $n -ne 254 -a $n -ne 255 ]; then
echo -e "\t[ERROR] netmask $netmask format error in '.$n' (it must be 0,128,192,224,240,248,252,254,255). I will use .255 insted of .$n"
n=255
fi
# $b is the binary of $netmask
b=${b}${bin[$n]}
done
# remove right "0" bits from $b
b=${b/%0*}
cidr=${#b}
echo $cidr
}
Quel che si fa è convertire i 4 ottetti del netmask in binario e metterli in serie nell'unica variabile "b" quindi rimuovere i bit a 0 presenti nella destra del numero binario complessivo.
Infine basta contare il numero dei bit rimasti per avere il CIDR che poi verrà restituito in uscita.