J'essaie de créer un script permettant de saisir un ensemble de préfixes, qui répertoriera ensuite toutes les adresses IP contenues dans les préfixes (y compris réseau/hôte/diffusion).
Un exemple serait:
./convert-prefix-to-IPs.sh 192.168.0.0/23 203.20.0.0/16
192.168.0.0
192.168.0.1
...
192.168.0.255
192.168.1.0
..
192.168.1.255
203.20.0.0
..
203.20.255.255
Certains scripts python/Perl peuvent le faire, mais j'espère avoir un script bash simple, car il peut être utilisé sur des systèmes sans Perl/python (oui… je sais…)
Voici ce que j'utilise pour générer toutes les adresses IP dans un bloc CIDR donné
nmap -sL 10.10.64.0/27 | grep "Nmap scan report" | awk '{print $NF}'
Aussi simple que cela
La commande ci-dessus affiche cette
10.10.64.0
10.10.64.1
10.10.64.2
10.10.64.3
10.10.64.4
10.10.64.5
10.10.64.6
10.10.64.7
10.10.64.8
10.10.64.9
10.10.64.10
10.10.64.11
10.10.64.12
10.10.64.13
10.10.64.14
10.10.64.15
10.10.64.16
10.10.64.17
10.10.64.18
10.10.64.19
10.10.64.20
10.10.64.21
10.10.64.22
10.10.64.23
10.10.64.24
10.10.64.25
10.10.64.26
10.10.64.27
10.10.64.28
10.10.64.29
10.10.64.30
10.10.64.31
Moi aussi, je cherchais cette solution et j'ai constaté que le script @scherand fonctionnait très bien. J'ai également ajouté à ce script pour vous donner plus d'options. Fichier d'aide ci-dessous.
CET ÉCRIT DÉVELOPPEMENT UNECIDRADDRESS.
./cidr-to-ip.sh [OPTION(only one)] [STRING/FILENAME]
-h Affiche cet écran d'aide
-f Force une vérification des limites du réseau quand on leur donne une ou plusieurs chaînes.
-i lit un fichier d'entrée (le fichier doit contenir un CIDR par ligne) (pas de vérification des limites du réseau)
-b Fera la même chose que –i mais avec vérification des limites du réseau
./cidr-to-ip.sh 192.168.0.1/24
./cidr-to-ip.sh 192.168.0.1/24 10.10.0.0/28
./cidr-to-ip.sh -f 192.168.0.0/16
./cidr-to-ip.sh -i inputfile.txt
./cidr-to-ip.sh -b fichier_entrée.txt
#!/bin/bash
############################
## Methods
############################
prefix_to_bit_netmask() {
prefix=$1;
shift=$(( 32 - prefix ));
bitmask=""
for (( i=0; i < 32; i++ )); do
num=0
if [ $i -lt $prefix ]; then
num=1
fi
space=
if [ $(( i % 8 )) -eq 0 ]; then
space=" ";
fi
bitmask="${bitmask}${space}${num}"
done
echo $bitmask
}
bit_netmask_to_wildcard_netmask() {
bitmask=$1;
wildcard_mask=
for octet in $bitmask; do
wildcard_mask="${wildcard_mask} $(( 255 - 2#$octet ))"
done
echo $wildcard_mask;
}
check_net_boundary() {
net=$1;
wildcard_mask=$2;
is_correct=1;
for (( i = 1; i <= 4; i++ )); do
net_octet=$(echo $net | cut -d '.' -f $i)
mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)
if [ $mask_octet -gt 0 ]; then
if [ $(( $net_octet&$mask_octet )) -ne 0 ]; then
is_correct=0;
fi
fi
done
echo $is_correct;
}
#######################
## MAIN
#######################
OPTIND=1;
getopts "fibh" force;
shift $((OPTIND-1))
if [ $force = 'h' ]; then
echo ""
echo -e "THIS SCRIPT WILL EXPAND A CIDR ADDRESS.\n\nSYNOPSIS\n ./cidr-to-ip.sh [OPTION(only one)] [STRING/FILENAME]\nDESCRIPTION\n -h Displays this help screen\n -f Forces a check for network boundary when given a STRING(s)\n -i Will read from an Input file (no network boundary check)\n -b Will do the same as –i but with network boundary check\n\nEXAMPLES\n ./cidr-to-ip.sh 192.168.0.1/24\n ./cidr-to-ip.sh 192.168.0.1/24 10.10.0.0/28\n ./cidr-to-ip.sh -f 192.168.0.0/16\n ./cidr-to-ip.sh -i inputfile.txt\n ./cidr-to-ip.sh -b inputfile.txt\n"
exit
fi
if [ $force = 'i' ] || [ $force = 'b' ]; then
old_IPS=$IPS
IPS=$'\n'
lines=($(cat $1)) # array
IPS=$old_IPS
else
lines=$@
fi
for ip in ${lines[@]}; do
net=$(echo $ip | cut -d '/' -f 1);
prefix=$(echo $ip | cut -d '/' -f 2);
do_processing=1;
bit_netmask=$(prefix_to_bit_netmask $prefix);
wildcard_mask=$(bit_netmask_to_wildcard_netmask "$bit_netmask");
is_net_boundary=$(check_net_boundary $net "$wildcard_mask");
if [ $force = 'f' ] && [ $is_net_boundary -ne 1 ] || [ $force = 'b' ] && [ $is_net_boundary -ne 1 ] ; then
read -p "Not a network boundary! Continue anyway (y/N)? " -n 1 -r
echo ## move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
do_processing=1;
else
do_processing=0;
fi
fi
if [ $do_processing -eq 1 ]; then
str=
for (( i = 1; i <= 4; i++ )); do
range=$(echo $net | cut -d '.' -f $i)
mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)
if [ $mask_octet -gt 0 ]; then
range="{$range..$(( $range | $mask_octet ))}";
fi
str="${str} $range"
done
ips=$(echo $str | sed "s, ,\\.,g"); ## replace spaces with periods, a join...
eval echo $ips | tr ' ' '\n'
else
exit
fi
done
Ce court script imprimera toutes les adresses IP d'une plage CIDR en quelques lignes de Bash. (Je l'ai nommée prips
après la commande Ubuntu du même nom . Évidemment, si cette commande est disponible, utilisez-la.)
prips() {
cidr=$1
# range is bounded by network (-n) & broadcast (-b) addresses.
lo=$(ipcalc -n $cidr | cut -f2 -d=)
hi=$(ipcalc -b $cidr | cut -f2 -d=)
read a b c d <<< $(echo $lo | tr . ' ')
read e f g h <<< $(echo $hi | tr . ' ')
eval "echo {$a..$e}.{$b..$f}.{$c..$g}.{$d..$h}"
}
Notez que je suppose que la version de ipcalc
sous RedHat Linux (Erik Troan, Preston Brown) est différente de celle de Krischan Jodies installée sur certaines plates-formes (Mac OS X, par exemple).
Exemples:
$ prips 10.0.0.128/27
10.0.0.128 10.0.0.129 10.0.0.130 10.0.0.131 10.0.0.132 10.0.0.133 10.0.0.134 10.0.0.135 10.0.0.136 10.0.0.137 10.0.0.138 10.0.0.139 10.0.0.140 10.0.0.141 10.0.0.142 10.0.0.143 10.0.0.144 10.0.0.145 10.0.0.146 10.0.0.147 10.0.0.148 10.0.0.149 10.0.0.150 10.0.0.151 10.0.0.152 10.0.0.153 10.0.0.154 10.0.0.155 10.0.0.156 10.0.0.157 10.0.0.158 10.0.0.159
Calcule le nombre correct d'adresses dans un réseau/23:
$ prips 10.0.0.0/23 |wc -w
512
Inspecter quelques-unes de ces adresses en utilisant cut:
$ prips 10.0.0.0/23 |cut -f1-10,256-266 -d' '
10.0.0.0 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 10.0.0.6 10.0.0.7 10.0.0.8 10.0.0.9 10.0.0.255 10.0.1.0 10.0.1.1 10.0.1.2 10.0.1.3 10.0.1.4 10.0.1.5 10.0.1.6 10.0.1.7 10.0.1.8 10.0.1.9
Et peut-être trop lentement, mais génère également correctement les 16 millions d'adresses dans un réseau/8:
$ date ; prips 10.0.0.0/8 |wc -w ; date
Sat May 20 18:06:00 AEST 2017
16777216
Sat May 20 18:06:41 AEST 2017
J'ai récemment écrit une fonction pour générer toutes les adresses IP à partir d'une adresse réseau donnée. La fonction prend l'adresse réseau en argument et accepte les masques CIDR et de sous-réseau. Le script stocke ensuite toutes les adresses IP dans la variable de tableau $ ips.
function network_address_to_ips() {
# define empty array to hold the ip addresses
ips=()
# create array containing network address and subnet
network=(${1//\// })
# split network address by dot
iparr=(${network[0]//./ })
# check for subnet mask or create subnet mask from CIDR notation
if [[ ${network[1]} =~ '.' ]]; then
netmaskarr=(${network[1]//./ })
else
if [[ $((8-${network[1]})) -gt 0 ]]; then
netmaskarr=($((256-2**(8-${network[1]}))) 0 0 0)
Elif [[ $((16-${network[1]})) -gt 0 ]]; then
netmaskarr=(255 $((256-2**(16-${network[1]}))) 0 0)
Elif [[ $((24-${network[1]})) -gt 0 ]]; then
netmaskarr=(255 255 $((256-2**(24-${network[1]}))) 0)
Elif [[ $((32-${network[1]})) -gt 0 ]]; then
netmaskarr=(255 255 255 $((256-2**(32-${network[1]}))))
fi
fi
# correct wrong subnet masks (e.g. 240.192.255.0 to 255.255.255.0)
[[ ${netmaskarr[2]} == 255 ]] && netmaskarr[1]=255
[[ ${netmaskarr[1]} == 255 ]] && netmaskarr[0]=255
# generate list of ip addresses
for i in $(seq 0 $((255-${netmaskarr[0]}))); do
for j in $(seq 0 $((255-${netmaskarr[1]}))); do
for k in $(seq 0 $((255-${netmaskarr[2]}))); do
for l in $(seq 1 $((255-${netmaskarr[3]}))); do
ips+=( $(( $i+$(( ${iparr[0]} & ${netmaskarr[0]})) ))"."$(( $j+$(( ${iparr[1]} & ${netmaskarr[1]})) ))"."$(($k+$(( ${iparr[2]} & ${netmaskarr[2]})) ))"."$(($l+$((${iparr[3]} & ${netmaskarr[3]})) )) )
done
done
done
done
}
network_address_to_ips 10.0.1.0/255.255.255.240
echo ${ips[@]}
network_address_to_ips 10.1.0.0/24
echo ${ips[@]}
nmap
est utile, mais excessif.
Vous pouvez utiliser prips
à la place. Vous évite d'avoir à extraire la sortie supplémentaire de nmap
et à utiliser awk
.
Appeler prips 192.168.0.0/23
imprimera ce dont vous avez besoin.
J'utilise les éléments suivants pour ignorer l'adresse réseau et la diffusion: prips "$subnet" | sed -e '1d; $d'
Les prips offrent également des options utiles, par exemple être en mesure de goûter chaque n-ème IP.
Je pense que ce petit script que j'ai piraté fait l'affaire. Sinon, c'est définitivement un point de départ! Bonne chance.
#!/bin/bash
############################
## Methods
############################
prefix_to_bit_netmask() {
prefix=$1;
shift=$(( 32 - prefix ));
bitmask=""
for (( i=0; i < 32; i++ )); do
num=0
if [ $i -lt $prefix ]; then
num=1
fi
space=
if [ $(( i % 8 )) -eq 0 ]; then
space=" ";
fi
bitmask="${bitmask}${space}${num}"
done
echo $bitmask
}
bit_netmask_to_wildcard_netmask() {
bitmask=$1;
wildcard_mask=
for octet in $bitmask; do
wildcard_mask="${wildcard_mask} $(( 255 - 2#$octet ))"
done
echo $wildcard_mask;
}
#######################
## MAIN
#######################
for ip in $@; do
net=$(echo $ip | cut -d '/' -f 1);
prefix=$(echo $ip | cut -d '/' -f 2);
bit_netmask=$(prefix_to_bit_netmask $prefix);
wildcard_mask=$(bit_netmask_to_wildcard_netmask "$bit_netmask");
str=
for (( i = 1; i <= 4; i++ )); do
range=$(echo $net | cut -d '.' -f $i)
mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)
if [ $mask_octet -gt 0 ]; then
range="{0..$mask_octet}";
fi
str="${str} $range"
done
ips=$(echo $str | sed "s, ,\\.,g"); ## replace spaces with periods, a join...
eval echo $ips | tr ' ' '\012'
done
Je voulais commenter une réponse ci-dessus mais je n'ai pas encore le représentant.
En utilisant la solution supérieure avec NMAP, j'ai ajouté ceci à mon .bashrc
expand-ip() {
nmap -sL -n -iL "$1" | grep "Nmap scan report" | awk '{print $NF}'
}
Maintenant, je peux l'utiliser avec seulement expand-ip targs
J'ai prolongé un peu le script @Rberg.
-f
pour ignorer la vérification)/24
Peut-être que cela est utile pour quelqu'un.
#!/bin/bash
############################
## Methods
############################
prefix_to_bit_netmask() {
prefix=$1;
shift=$(( 32 - prefix ));
bitmask=""
for (( i=0; i < 32; i++ )); do
num=0
if [ $i -lt $prefix ]; then
num=1
fi
space=
if [ $(( i % 8 )) -eq 0 ]; then
space=" ";
fi
bitmask="${bitmask}${space}${num}"
done
echo $bitmask
}
bit_netmask_to_wildcard_netmask() {
bitmask=$1;
wildcard_mask=
for octet in $bitmask; do
wildcard_mask="${wildcard_mask} $(( 255 - 2#$octet ))"
done
echo $wildcard_mask;
}
check_net_boundary() {
net=$1;
wildcard_mask=$2;
is_correct=1;
for (( i = 1; i <= 4; i++ )); do
net_octet=$(echo $net | cut -d '.' -f $i)
mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)
if [ $mask_octet -gt 0 ]; then
if [ $(( $net_octet&$mask_octet )) -ne 0 ]; then
is_correct=0;
fi
fi
done
echo $is_correct;
}
#######################
## MAIN
#######################
OPTIND=1;
getopts "f" force;
shift $(( OPTIND-1 ));
for ip in $@; do
net=$(echo $ip | cut -d '/' -f 1);
prefix=$(echo $ip | cut -d '/' -f 2);
do_processing=1;
bit_netmask=$(prefix_to_bit_netmask $prefix);
wildcard_mask=$(bit_netmask_to_wildcard_netmask "$bit_netmask");
is_net_boundary=$(check_net_boundary $net "$wildcard_mask");
if [ $force != 'f' ] && [ $is_net_boundary -ne 1 ]; then
read -p "Not a network boundary! Continue anyway (y/N)? " -n 1 -r
echo ## move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
do_processing=1;
else
do_processing=0;
fi
fi
if [ $do_processing -eq 1 ]; then
str=
for (( i = 1; i <= 4; i++ )); do
range=$(echo $net | cut -d '.' -f $i)
mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)
if [ $mask_octet -gt 0 ]; then
range="{$range..$(( $range | $mask_octet ))}";
fi
str="${str} $range"
done
ips=$(echo $str | sed "s, ,\\.,g"); ## replace spaces with periods, a join...
eval echo $ips | tr ' ' '\012'
fi
done
fping -Aaqgr 1 10.1.1.0/24
La simplicité fonctionne mieux
Vous pouvez utiliser ce script
(vous devez avoir "bc" installé sur votre système):
for ip in $@ ;do
net=$(echo $ip | cut -d '/' -f 1);
prefix=$(echo $ip | cut -d '/' -f 2);
o1=$(echo $net | cut -d '.' -f4);
o2=$(echo $net | cut -d '.' -f3);
o3=$(echo $net | cut -d '.' -f2);
o4=$(echo $net | cut -d '.' -f1);
len=$(echo "2^(32 - $prefix)"|bc);
for i in `seq $len`;do
echo "$o4.$o3.$o2.$o1";
o1=$(echo "$o1+1"|bc);
if [ $o1 -eq 256 ]; then
o1=0;
o2=$(echo "$o2+1"|bc);
if [ $o2 -eq 256 ]; then
o2=0;
o3=$(echo "$o3+1"|bc);
if [ $o3 -eq 256 ]; then
o3=0;
o4=$(echo "$o4+1"|bc);
fi
fi
fi
done
done