Convertendo um intervalo de endereços IPv4 em máscaras de rede usando o bash

10

Eu tenho um arquivo de entrada com endereços IPv4:

94.228.16.0 - 94.228.25.255
94.241.136.0/24
94.241.136.0 - 94.241.136.255
94.29.128.0/17
94.29.128.0 - 94.29.191.0
94.29.192.0 - 94.29.255.0
94.74.181.0/24
94.74.181.0 - 94.74.181.31
94.74.181.128 - 94.74.181.255

Como posso converter os intervalos de endereços em máscaras de rede? O resultado deve ser:

94.228.16.0/21
94.241.136.0/24
94.241.136.0/24
94.29.128.0/17
94.29.128.0/19
94.29.192.0/19
94.74.181.0/24
94.74.181.0/27
94.74.181.128/25
Oleksii
fonte
3
Vários dos resultados solicitados estão incorretos, portanto, nenhum script bash válido os produzirá. Por exemplo, o primeiro intervalo não é expressável usando uma máscara de rede: 94.228.16.0/21 fornece 94.228.16.0 - 94.228.23.255 e o próximo mais amplo 94.228.16.0/20 fornece 94.228.16.0 - 94.228.31.255. Além disso, os intervalos que terminam em .0 não podem ser produzidos por nenhuma máscara de rede.
Zwets
@ Zanna, você está trapaceando, perguntou o pôster usando o bash . Meu bash não tem ipcalcbuiltin. ;-)
zwets 31/01
ah ah @zwets eu descobri isso! Mas você está certo, o shell precisa de muita ajuda hahaha
Zanna

Respostas:

14

Primeiro você precisará instalar um pacote para fazer a conversão

sudo apt install ipcalc

Agora você pode fazer isso com este pequeno script (observe que ele não funciona se você citar a variável):

$ while read line; do if [[ $line = *-* ]]; then (ipcalc $line | sed '2!d'); else echo $line; fi; done < file
94.228.16.0/21
94.241.136.0/24
94.241.136.0/24
94.29.128.0/17
94.29.128.0/19
94.29.192.0/19
94.74.181.0/24
94.74.181.0/27
94.74.181.128/25

ou mais facilmente

while read line; do
   if [[ $line = *-* ]]; then 
     (ipcalc $line | sed '2!d')
   else echo $line
   fi
done < file
Zanna
fonte
@Oleksii sempre um prazer :)
Zanna
3

Talvez não seja de surpreender que exista um módulo CPAN perl Net :: CIDR para isso.

Então, por exemplo:

$ perl -MNet::CIDR=range2cidr -lne 'print for range2cidr $_' yourfile
94.228.16.0/21
94.228.24.0/23
94.241.136.0/24
94.241.136.0/24
94.29.128.0/17
94.29.191.0/32
94.29.128.0/19
94.29.160.0/20
94.29.176.0/21
94.29.184.0/22
94.29.188.0/23
94.29.190.0/24
94.29.255.0/32
94.29.192.0/19
94.29.224.0/20
94.29.240.0/21
94.29.248.0/22
94.29.252.0/23
94.29.254.0/24
94.74.181.0/24
94.74.181.0/27
94.74.181.128/25

O módulo está disponível no Ubuntu instalando o libnet-cidr-perlpacote.

NB : Não validei sua entrada ou os resultados.

chave de aço
fonte