web-dev-qa-db-fra.com

Étant donné l'adresse IP et le masque de réseau, comment puis-je calculer l'adresse réseau à l'aide de bash?

Dans un script bash, j'ai une adresse IP telle que 192.168.1.15 et un masque de réseau tel que 255.255.0.0. Je veux maintenant calculer l’adresse de départ de ce réseau, c’est-à-dire utiliser l’opérateur & sur les deux adresses. Dans l'exemple, le résultat serait 192.168.0.0. Quelqu'un a-t-il quelque chose comme ça prêt? Je cherche un moyen élégant de gérer les adresses IP de bash

15
Christian

Utilisez l'opérateur binaire & (AND):

$ IFS=. read -r i1 i2 i3 i4 <<< "192.168.1.15"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.0.0"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
192.168.0.0

Exemple avec une autre adresse IP et masque:

$ IFS=. read -r i1 i2 i3 i4 <<< "10.0.14.97"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.255.248"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
10.0.14.96
37
kamituel

Certaines fonctions Bash résument toutes les autres réponses.

ip2int()
{
    local a b c d
    { IFS=. read a b c d; } <<< $1
    echo $(((((((a << 8) | b) << 8) | c) << 8) | d))
}

int2ip()
{
    local ui32=$1; shift
    local ip n
    for n in 1 2 3 4; do
        ip=$((ui32 & 0xff))${ip:+.}$ip
        ui32=$((ui32 >> 8))
    done
    echo $ip
}

netmask()
{
    local mask=$((0xffffffff << (32 - $1))); shift
    int2ip $mask
}


broadcast()
{
    local addr=$(ip2int $1); shift
    local mask=$((0xffffffff << (32 -$1))); shift
    int2ip $((addr | ~mask))
}

network()
{
    local addr=$(ip2int $1); shift
    local mask=$((0xffffffff << (32 -$1))); shift
    int2ip $((addr & mask))
}
10
ceving

Ajoutez simplement une alternative si vous ne disposez que du préfixe réseau (pas de masque de réseau):

IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
IFS=. read -r xx m1 m2 m3 m4 <<< $(for a in $(seq 1 32); do if [ $(((a - 1) % 8)) -eq 0 ]; then echo -n .; fi; if [ $a -le $PREFIX ]; then echo -n 1; else echo -n 0; fi; done)
printf "%d.%d.%d.%d\n" "$((i1 & (2#$m1)))" "$((i2 & (2#$m2)))" "$((i3 & (2#$m3)))" "$((i4 & (2#$m4)))"
3
Janci

Excellente réponse, bien que faute de frappe mineure dans la réponse ci-dessus.

$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$(($i2  <-- $i2 should be i2

Si quelqu'un sait comment calculer l'adresse de diffusion (réseau XOR), puis calculer les nœuds utilisables entre le réseau et la diffusion, je serais intéressé par les prochaines étapes. Je dois trouver des adresses dans une liste dans un/23.

2
user3126740

En plus de @Janci answer

IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
binIP=${D2B[$i1]}${D2B[$i2]}${D2B[$i3]}${D2B[$i4]}
binIP0=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((32-$PREFIX))))
# binIP1=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((31-$PREFIX))))1
echo $((2#${binIP0::8})).$((2#${binIP0:8:8})).$((2#${binIP0:16:8})).$((2#${binIP0:24:8}))
0
Mikhail