我真的很喜歡這個問題,我昨晚看了一眼,決定試一試。在這一點上,我有一個概念shell腳本工作的證明。
免責聲明:
- 這是概念只
- 我有種又徹底改造了車輪這裏我沒有使用任何TCP/IP庫
- 我沒有實現的證明輸入驗證
- 如果使用編程語言而不是bash編寫代碼,該代碼可能會快得多,但對於此特定網絡範圍並不那麼慢
另一件事值得一提的是,我的理解:
IPv4 networks should have as short subnet-mask as possible.
是,我們應該試着從保留到網點達提供最大的CIDR 位,在這種情況下。
OK,讓我們看到了正在運行的腳本:
[[email protected] tmp]# time bash ip.sh 10.11.3.64/25 10.11.52.0/24
10.11.3.128/25
10.11.4.0/22
10.11.8.0/21
10.11.16.0/20
10.11.32.0/20
10.11.48.0/22
real 0m48.376s
user 0m6.174s
sys 0m34.644s
代碼如下:
#! /bin/bash
function split_octet {
sed -re "s/\./ /g" <<< "$1"
}
function dec2bin {
perl -e 'printf "%0'"$1"'b\n",'"$2"';'
}
function bin2dec {
perl -le 'print 0b'"$1"';'
}
function ip2bin {
str=""
for octet in $(split_octet $1); do
str="${str}$(dec2bin 8 $octet)"
done
echo "$str"
}
function bin2ip {
str=""
for octet in $(grep -Eo '.{8}' <<< $1); do
dec=$(bin2dec $octet)
str="${str}.${dec}"
done
echo "$str" | sed -re 's/^\.|\.$//g'
}
function ip2dec {
ip=$1
bin2dec $(ip2bin $ip)
}
function dec2ip {
dec=$1
bin2ip $(dec2bin 32 $dec)
}
function AND {
perl -e ' $a=0b'"$1"' & 0b'"$2"';
printf "%032b\n",$a
'
}
function OR {
perl -e ' $a=0b'"$1"' | 0b'"$2"';
printf "%032b\n",$a
'
}
function NOT {
perl -le ' $a= (~ 0b'"$1"') & 0xFFFFFFFF;
printf "%032b\n",$a
'
}
function get_network {
ip=$1; mask=$2;
if [ -n "$ip" -a -n "$mask" ];then
echo $(bin2ip $(AND $(ip2bin $ip) $(ip2bin $mask)))
return
fi
grep -qP "\d+\.\d+\.\d+.\d+/\d+" <<< "$ip"
if [ "$?" == 0 ];then
ip=$(get_ip_from_cidr $1)
mask=$(get_mask_from_cidr $1)
echo $(bin2ip $(AND $(ip2bin $ip) $(ip2bin $mask)))
fi
}
function get_broadcast {
ip=$1; mask=$2;
if [ -n "$ip" -a -n "$mask" ];then
echo $(bin2ip $(OR $(ip2bin $ip) $(NOT $(ip2bin $mask))))
return
fi
grep -qP "\d+\.\d+\.\d+.\d+/\d+" <<< "$ip"
if [ "$?" == 0 ];then
ip=$(get_ip_from_cidr $1)
mask=$(get_mask_from_cidr $1)
echo $(bin2ip $(OR $(ip2bin $ip) $(NOT $(ip2bin $mask))))
fi
}
function get_ip_from_cidr {
awk -F/ '{print $1}' <<< "$1"
}
function get_mask_from_cidr {
mask=$(awk -F/ '{print $2}' <<< "$1")
mask=$(cidr $mask)
mask=$(bin2ip $mask)
echo $mask
}
function cidr {
perl -e '
$n='"$1"';
$diff=32-$n;
print "1"x$n . "0"x$diff;
'
}
snet_cidr=$1
enet_cidr=$2
largest_cidr=$(echo -e "$snet_cidr\n$enet_cidr"| awk -F/ '{print $2}' | sort -rn | head -1)
snet_dec=$(ip2dec $(get_ip_from_cidr $snet_cidr))
enet_dec=$(ip2dec $(get_ip_from_cidr $enet_cidr))
sbc_ip=$(get_broadcast $snet_cidr)
ebc_ip=$(get_broadcast $enet_cidr)
sbc_dec=$(ip2dec $sbc_ip)
ebc_dec=$(ip2dec $ebc_ip)
counter=$sbc_dec
while [ $counter -lt $enet_dec ];do
tip=$(dec2ip $counter)
for cidr in $(seq 8 $largest_cidr) ; do
tnet_ip=$(get_network $tip/$cidr)
tnet_cidr=$tnet_ip/$cidr
tbc_ip=$(get_broadcast $tnet_cidr)
tnet_dec=$(ip2dec $(get_ip_from_cidr $tnet_cidr))
tbc_dec=$(ip2dec $tbc_ip)
if [ $sbc_dec -lt $tnet_dec -a $enet_dec -gt $tbc_dec ];then
echo $tnet_cidr
counter=$tbc_dec
break
fi
done
let counter++
done
編輯這可能是一個好主意,解釋這些變量是:
- snet_cidr:以cidr符號開始網絡
個
- enet_cidr:年底淨CIDR
- snet_dec:十進制
- enet_dec開始網:年底淨十進制
- sbc_ip:開始廣播IP
- ebc_ip:高端廣播IP
- sbc_dec:開始廣播IP
- ebc_dec:高端廣播IP
何地,你看到TNET或TBC是臨時網,廣播溫度,溫度,因爲它是insid循環。
解釋'IPv4網絡應儘可能使用短子網掩碼。' – hek2mgl 2014-09-19 14:03:01
@ hek2mgl這意味着IPv4前綴應該儘可能大。例如,網絡範圍'10.11.3.128-10.11.51.255'可以用'10.11.3.128/25'的CIDR表示法,然後用'24前綴的'10.11.4.0/24'表示爲'10.11.51.0/24'。實際上這些'/ 24'可以被聚合。 – Martin 2014-09-19 14:26:07
或從10.11.3.128/0到10.11.51.255/0使用32位的前綴,這實際上是IPV4最大可能的前綴..這就是爲什麼我問.. – hek2mgl 2014-09-19 14:50:15