残念なことに、この「4.2 IPv4 CIDR blocks」の表は素人には判りにくいものでした。そこで、Zshの練習を兼ねて、このテーブルを生成するスクリプト「table_ipv4」を制作したので紹介します。
実行結果
u1@MmM11[~/myZsh]% table_ipv4 21:30:34
---------------------------------------------------------------------------------------------------------
prefix low chg rem rem -----MASKv4---- Δ to last start addresses
bits bits oct bit value MK3.MK2.MK1.MK0 #Hosts IPv4/CIDR IP addr. of blocks
---------------------------------------------------------------------------------------------------------
32 0 0 0 0 255.255.255.255 1 a.b.c.d/32 000.000.000.000 d=(1)*{0..255}
31 1 0 1 1 255.255.255.254 2 a.b.c.d/31 000.000.000.001 d=(2)*{0..127}
30 2 0 2 3 255.255.255.252 4 a.b.c.d/30 000.000.000.003 d=(4)*{0..63}
29 3 0 3 7 255.255.255.248 8 a.b.c.d/29 000.000.000.007 d=(8)*{0..31}
28 4 0 4 15 255.255.255.240 16 a.b.c.d/28 000.000.000.015 d=(16)*{0..15}
27 5 0 5 31 255.255.255.224 32 a.b.c.d/27 000.000.000.031 d=(32)*{0..7}
26 6 0 6 63 255.255.255.192 64 a.b.c.d/26 000.000.000.063 d=(64)*{0..3}
25 7 0 7 127 255.255.255.128 128 a.b.c.d/25 000.000.000.127 d=(128)*{0..1}
---------------------------------------------------------------------------------------------------------
24 8 1 0 0 255.255.255.000 256 a.b.c.0/24 000.000.000.255 c=(1)*{0..255}
23 9 1 1 1 255.255.254.000 512 a.b.c.0/23 000.000.001.255 c=(2)*{0..127}
22 10 1 2 3 255.255.252.000 1024 a.b.c.0/22 000.000.003.255 c=(4)*{0..63}
21 11 1 3 7 255.255.248.000 2048 a.b.c.0/21 000.000.007.255 c=(8)*{0..31}
20 12 1 4 15 255.255.240.000 4096 a.b.c.0/20 000.000.015.255 c=(16)*{0..15}
19 13 1 5 31 255.255.224.000 8192 a.b.c.0/19 000.000.031.255 c=(32)*{0..7}
18 14 1 6 63 255.255.192.000 16384 a.b.c.0/18 000.000.063.255 c=(64)*{0..3}
17 15 1 7 127 255.255.128.000 32768 a.b.c.0/17 000.000.127.255 c=(128)*{0..1}
---------------------------------------------------------------------------------------------------------
16 16 2 0 0 255.255.000.000 65536 a.b.0.0/16 000.000.255.255 b=(1)*{0..255}
15 17 2 1 1 255.254.000.000 131072 a.b.0.0/15 000.001.255.255 b=(2)*{0..127}
14 18 2 2 3 255.252.000.000 262144 a.b.0.0/14 000.003.255.255 b=(4)*{0..63}
13 19 2 3 7 255.248.000.000 524288 a.b.0.0/13 000.007.255.255 b=(8)*{0..31}
12 20 2 4 15 255.240.000.000 1048576 a.b.0.0/12 000.015.255.255 b=(16)*{0..15}
11 21 2 5 31 255.224.000.000 2097152 a.b.0.0/11 000.031.255.255 b=(32)*{0..7}
10 22 2 6 63 255.192.000.000 4194304 a.b.0.0/10 000.063.255.255 b=(64)*{0..3}
9 23 2 7 127 255.128.000.000 8388608 a.b.0.0/09 000.127.255.255 b=(128)*{0..1}
---------------------------------------------------------------------------------------------------------
8 24 3 0 0 255.000.000.000 16777216 a.0.0.0/08 000.255.255.255 a=(1)*{0..255}
7 25 3 1 1 254.000.000.000 33554432 a.0.0.0/07 001.255.255.255 a=(2)*{0..127}
6 26 3 2 3 252.000.000.000 67108864 a.0.0.0/06 003.255.255.255 a=(4)*{0..63}
5 27 3 3 7 248.000.000.000 134217728 a.0.0.0/05 007.255.255.255 a=(8)*{0..31}
4 28 3 4 15 240.000.000.000 268435456 a.0.0.0/04 015.255.255.255 a=(16)*{0..15}
3 29 3 5 31 224.000.000.000 536870912 a.0.0.0/03 031.255.255.255 a=(32)*{0..7}
2 30 3 6 63 192.000.000.000 1073741824 a.0.0.0/02 063.255.255.255 a=(64)*{0..3}
1 31 3 7 127 128.000.000.000 2147483648 a.0.0.0/01 127.255.255.255 a=(128)*{0..1}
---------------------------------------------------------------------------------------------------------
0 32 4 0 0 000.000.000.000 4294967296 0.0.0.0/00 255.255.255.255 0
---------------------------------------------------------------------------------------------------------
u1@MmM11[~/myZsh]% 21:30:41
- 右端列「start addresses of blocks」を直裁的に示した点だ。
- 「routing prefix」がOctet(8bit)変化するごとに、相似した変化が観察できる。
- 「routing prefixが32,31」は「ホスト数が1,2」に対応しているので特殊である。
- 「4.2 IPv4 CIDR blocks」には、その論拠が引用されている
- MKSKv4と「Δ to last IP adde.」都の対応する成分を加えると「255」だ。例えば、「routing prefix」=17では;
- (255.255.128.0)+(0.0.127.255)=(255.255.255.255)
- 右端列「start addresses of blocks」は見やすい。{0..n}は(0~n)までの任意整数。
- 「routing prefix」がOctet(8bit)変化するごとに、相似した変化が観察できる。
- 「routing prefixが32,31」は「ホスト数が1,2」に対応しているので特殊である。
- 「4.2 IPv4 CIDR blocks」には、その論拠が引用されている。
スクリプト
#!/bin/zsh # table_ipv4 # reference: # Classless Inter-Domain Routing # http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing 4.2 IPv4 CIDR blocks IP_CIDR_Delta(){ # IP_CIDR_Delta ipv4 delta ddelta local PTipv4=$1 local ipc ipc=${(P)PTipv4} ipc=($(echo "$ipc")) local PTdelta=$2 local dlt dlt=${(P)PTdelta} dlt=($(echo "$dlt")) local PTddelta=$3 local ddlt ddlt=${(P)PTddelta} ddlt=($(echo "$ddlt")) local nn=$((1)) # array [1][2][3][4] local ocn=$((3)) # octet number 3 2 1 0 #echo "ipc=$ipc dlt=$dlt ddlt=$ddlt" #echo "cho=$cho rmv=$rmv" # Δ to last IP address for nn in {1..4}; do ocn=$((4-nn)) if [ $ocn -gt $cho ]; then # $choより左のoctet=0 dlt[$nn]=$((0)) elif [ $ocn -eq $cho ]; then # $choto同一のoctet=$rmvの値 dlt[$nn]=$(($rmv)) else # $choより右のoctet=255 dlt[$nn]=$((255)) fi done # IPv4 CIDR block notation # ipc: quad-dotted decimal notation: a.b.c.d/(routing prefix) 0<=a/b/c/d<=255 # ddlt: δΔ case $cho in 0) ddlt='d' ipc=('a' 'b' 'c' 'd');; 1) ddlt='c' ipc=('a' 'b' 'c' '0');; 2) ddlt='b' ipc=('a' 'b' '0' '0');; 3) ddlt='a' ipc=('a' '0' '0' '0');; 4) ddlt='0' ipc=('0' '0' '0' '0');; esac ipc=$(echo $ipc | tr ' ' '.') ### dlt=$(echo $dlt | tr ' ' '.') #echo "ipc=$ipc dlt=$dlt ddlt=$ddlt" #echo "ipc=$ipc" eval "$PTipv4='$ipc'" eval "$PTdelta='$dlt'" eval "$PTddelta='$ddlt'" } getMASKv4(){ #set -x #### getMASKv4 mk local PTmk=$1 # pointer of mk in the main local -a msk # local array,msk for MASKv4 msk=${(P)PTmk} # read msk as scalar msk=($(echo $msk)) # transfer scalar to array #echo "msk =$msk" # pfb="PreFix Bits" lb=$((32-$pfb)) # lb="LowBits" hts=$((2**$lb)) # Host addresses: including # 1. Network address, # 2. Router address, # 3. Broadcast address. cho=$((lb/8)) # CHanging Octal rem=$((lb%8)) # REMainder of octal rmv=$((2**$rem-1)) # ReMainder Vallue #echo "mid=$mid rem=$rem" local n=$((0)) # array number in the next for-loop # Main loop for msk[$n] with $cho for oc in {3..0}; do n=$((4-oc)) if [ $oc -gt $cho ]; then msk[$n]=$((255)) elif [ $oc -eq $cho ]; then msk[$n]=$((255-$rmv)) else msk[$n]=$((0)) fi done IP_CIDR_Delta ipv4 delta ddelta eval "$PTmk='$msk'" } #----------------- main ---------------------------------------------- pfb=$((0)) # pfb="PreFix Bits" lb=$((32)) # lb="LowBits" n=$((4)) # running parameter cho=$((0)) # CHanging Octal rem=$((0)) # REMainder of octal rmv=$((0)) # ReMainder Vallue hts=$((0)) # Host addresses mk=( 3 2 1 0 ) # array,mk for MASKv4 obtained at getMASKv4 #echo "mk=$mk #mk=$#mk" ipv4=('a' 'b' 'c' 'd') # obtained at IP_CIDR_Delta in getMASKv4 delta=(0 0 0 0) # same above ddelta='d' # same above # Header print echo --------------------------------------------------------------------------------------------------------- printf "prefix low chg rem rem -----MASKv4---- Δ to last start addresses\n" printf " bits bits oct bit value MK3.MK2.MK1.MK0 #Hosts IPv4/CIDR IP addr. of blocks\n" # Main Loop for pfb in {32..0}; do if [ $(($pfb%8)) -eq 0 ] ; then echo --------------------------------------------------------------------------------------------------------- fi getMASKv4 mk # call functions getMASKv4 and IP_CIDR_Delta mk=($(echo $mk)) # transform scalar to array delta=($(echo "$delta")) # transform scalar to array local eqlp='=(' local rpst0d=')*{0..' local ddelN=$(($rmv+1)) local last=$((255/ddelN)) local rponly='}' printf " %2d %3d %1d %1d %3d %.3d.%.3d.%.3d.%.3d %10d"\ $pfb $lb $cho $rem $rmv $mk[1] $mk[2] $mk[3] $mk[4] $hts printf " %s/%.2d %.3d.%.3d.%.3d.%.3d"\ $ipv4 $pfb $delta[1] $delta[2] $delta[3] $delta[4] if [ "$ddelta" = '0' ]; then echo " 0" else printf " %s%s%d%s%d%s\n"\ ${ddelta} $eqlp $ddelN $rpst0d $last $rponly fi done echo ---------------------------------------------------------------------------------------------------------
感想
CIDRブロックは素人には判りにくい。32ビットの2進数を8ビット毎に纏めて10進数にして、ドットで繋げ、その最後に「/」の後ろに「routing prefix」のだから。
寧ろ、あるプライベートIPv4ブロックのなかでの;
- Network address
- Host(PC, Printer, iPhone, iPad,TV, so on) address
- Router address
- Broadcast address
このページの履歴
- 開始 2015-01-08(木) 20:30
- 追加 2015-01-10(土) 18:15 table_ipv4での特徴