Ich versuche, ein Skript zu erstellen, mit dem ich eine Reihe von Präfixen eingeben kann, die dann alle IP-Adressen innerhalb der Präfixe auflisten (einschließlich Netzwerk/Host/Broadcast).
Ein Beispiel wäre:
./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
Es gibt einige Python/Perl-Skripte, die dies tun können, aber ich hoffe auf ein einfaches Bash-Skript, da es auf Systemen ohne Perl/Python (ja .. ich weiß ..) verwendet werden kann.
So generiere ich alle IP-Adressen in einem bestimmten CIDR-Block
nmap -sL 10.10.64.0/27 | grep "Nmap scan report" | awk '{print $NF}'
Einfach so einfach
Der obige Befehl gibt dies aus
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
Auch ich suchte nach dieser Lösung und fand, dass das @scherand-Skript gut funktionierte. Ich habe auch dieses Skript hinzugefügt, um Ihnen mehr Optionen zu geben. Hilfedatei unten.
DIESES SCRIPT ERWEITERT ACIDRADDRESS.
./cidr-to-ip.sh [OPTION(only one)] [STRING/FILENAME]
-h Zeigt diesen Hilfebildschirm an
-f Erzwingt eine Überprüfung der Netzwerkgrenze, wenn ein STRING (s) gegeben wird.
-i Liest aus einer Eingabedatei (Datei sollte eine CIDR pro Zeile enthalten) (keine Überprüfung der Netzwerkgrenzen)
-b macht dasselbe wie –i, jedoch mit Netzwerkgrenzprüfung
./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 Eingabedatei.txt
./cidr-to-ip.sh -b Eingabedatei.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
[email protected]
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
Dieses kurze Skript druckt alle IP-Adressen in einem CIDR-Bereich in wenigen Zeilen von Bash. (Ich habe den Namen prips
nach dem Ubuntu-Befehl mit demselben Namen benannt. Wenn dieser Befehl verfügbar ist, verwenden Sie diesen natürlich.)
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}"
}
Ich nehme an, dass die RedHat Linux-Version (Erik Troan, Preston Brown) von ipcalc
nicht die Krischan Jodies-Version ist, die auf einigen Plattformen (z. B. Mac OS X) installiert ist.
Beispiele:
$ 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
Berechnet die korrekte Anzahl von Adressen in a/23-Netzwerken:
$ prips 10.0.0.0/23 |wc -w
512
Einige dieser Adressen mit cut prüfen:
$ 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
Und vielleicht zu langsam, aber auch korrekt generiert die 16 Millionen Adressen in einem/8-Netzwerk:
$ 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
Ich habe kürzlich eine Funktion geschrieben, um alle IP-Adressen aus einer bestimmten Netzwerkadresse zu generieren. Die Funktion nimmt die Netzwerkadresse als Argument und akzeptiert CIDR- und Subnetzmasken. Das Skript speichert dann alle IP-Adressen in der Array-Variablen $ 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
ist nützlich, aber ein Overkill.
Sie können stattdessen prips
verwenden. Spart Ihnen den Aufwand, die zusätzliche Ausgabe von nmap
herauszufiltern und awk
zu verwenden.
Wenn Sie prips 192.168.0.0/23
aufrufen, wird gedruckt, was Sie benötigen.
Ich verwende Folgendes, um die Netzwerkadresse und die Übertragung zu überspringen: prips "$subnet" | sed -e '1d; $d'
Prips haben auch einige nützliche Optionen, z. in der Lage, jede n-te IP zu testen.
Ich denke, dieses kleine Skript, das ich zusammen gehackt habe, ist der Trick. Wenn nicht, ist es definitiv ein Ausgangspunkt! Viel Glück.
#!/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 [email protected]; 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
Wollte zu einer Antwort oben einen Kommentar abgeben, habe aber noch keinen Vertreter.
Mit der Top-Lösung mit NMAP habe ich dies zu meinem .bashrc
hinzugefügt.
expand-ip() {
nmap -sL -n -iL "$1" | grep "Nmap scan report" | awk '{print $NF}'
}
Jetzt kann ich dies nur mit expand-ip targs
verwenden.
@Rberg-Skript habe ich etwas erweitert.
-f
, um die Überprüfung zu überspringen)/24
Vielleicht ist das für jemanden von Nutzen.
#!/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 [email protected]; 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
Einfachheit funktioniert am besten
Sie können dieses Skript verwenden
(Sie müssen "bc" auf Ihrem System installiert haben):
for ip in [email protected] ;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