1 #!/bin/sh 2 # iptool.sh 3 4 #------------------------- ip 转 num 5 ip2num() 6 { 7 # 所有用到的命令全是bash内建命令 8 IP_ADDR=$1 9 [[ "$IP_ADDR" =~ "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" ]] || { echo "ip format error."; exit 1; } 10 IP_LIST=${IP_ADDR//./ }; 11 # 把点分十进制地址拆成数组(read的-a选项表示把输入读入到数组, 下标从0开始) 12 read -a IP_ARRAY <<<${IP_LIST}; 13 # bash的$(()) 支持位运算 14 echo $(( ${IP_ARRAY[0]}<<24 | ${IP_ARRAY[1]}<<16 | ${IP_ARRAY[2]}<<8 | ${IP_ARRAY[3]} )); 15 # 这里演示另外一种不使用位运算的方法 16 HEX_STRING=$(printf "0X%02X%02X%02X%02X\n" ${IP_ARRAY[0]} ${IP_ARRAY[1]} ${IP_ARRAY[2]} ${IP_ARRAY[3]}); 17 printf "%d\n" ${HEX_STRING}; 18 # 参考自:http://hi.baidu.com/test/blog/item/8af8513da98b72eb3d6d9740.html 19 } 20 21 #------------------------- num 转 ip 22 num2ip_1() 23 { 24 N=$1 25 H1=$(($N & 0x000000ff)) 26 H2=$((($N & 0x0000ff00) >> 8)) 27 L1=$((($N & 0x00ff0000) >> 16)) 28 L2=$((($N & 0xff000000) >> 24)) 29 echo $L2.$L1.$H2.$H1 30 } 31 32 num2ip_2() 33 { 34 N=$1 35 declare -i H1="$N & 0x000000ff" 36 declare -i H2="($N & 0x0000ff00) >> 8" 37 declare -i L1="($N & 0x00ff0000) >> 16" 38 declare -i L2="($N & 0xff000000) >> 24" 39 echo "$L2.$L1.$H2.$H1" 40 } 41 42 #------------------------- 掩码长度转掩码 43 lentomask() 44 { 45 declare -i FULL_MASK_INT=4294967295 46 declare -i MASK_LEN=$1 47 declare -i LEFT_MOVE="32 - ${MASK_LEN}" 48 declare -i N="${FULL_MASK_INT} << ${LEFT_MOVE}" 49 declare -i H1="$N & 0x000000ff" 50 declare -i H2="($N & 0x0000ff00) >> 8" 51 declare -i L1="($N & 0x00ff0000) >> 16" 52 declare -i L2="($N & 0xff000000) >> 24" 53 echo "$L2.$L1.$H2.$H1" 54 } 55 56 #------------------------- 计算网络地址和广播地址 57 all=(${@//[!0-9]/ }) # 將參數值裡的非數字全部換成空白鑑 58 # 要是處理過的參數量不是 8 個的話... 送出錯誤信息,告知命令可接受的參數格式。並退出。 59 [ "${#all[@]}" != "8" ] && { 60 echo "Usage: " 61 echo "${0##*/} ip.ip.ip.ip/mask.mask.mask.mask" 62 exit 1 63 } 64 # 定義一個 get_add 的 function 65 get_addr () { 66 # 要是讀進的第一個 function 參數為 -b ,則設定 op, op1, 與 arg 的變量,以供後面的 $(( $1 $op ($5 $op1 $arg) )) 計算用。 67 if [ "$1" = "-b" ]; then 68 # 其結則為 $(( $1 | ($5 ^ 255) )),也就是逐個算出 broadcast address 。 69 op='|'; op1='^'; arg='255' 70 shift # 然後用 shift 拿掉這個 -b 。 71 else # 若沒有 -b 參數,則只定義 op 變量。然則,$(( $1 $op ($5 $op1 $arg) )) 的實際算式就變成 $(( $1 & $5)),這會逐個算出 network address 。 72 op='&' 73 fi 74 unset address # 取消變量 address ,以免影嚮其後於 while loop 的運算。 75 while [ "$5" ]; do # 假如能讀到第 5 個參數,才進入 while loop,否則離開。 76 # 跟據前面的 -b 參數,來決定要算出 broadcast 還是 network 。因為前 4 個參數是 ip 後 4 個是 mask ,因此第一個參數跟第五個參數來算就能得出第一組 ip/mask 的計算結果。 77 num=$(( $1 $op ($5 $op1 $arg) )) 78 shift # 再拿掉第一個參數,這可讓下一次 looping 計算下一組 ip/mask 。當 shift 4 次之後,while loop 就可結束。 79 address="$address.$num" # 將每次的計算結果擴充在 address 變量中。(注意:如此的話,最後結果前面會有一個小數點,我們後面再處理) 80 done 81 } 82 #========================== 83 get_addr ${all[@]} # 跑 function 來計算 network address : 84 echo -e "network:\t${address#.}" # echo -e 可以用 \t 送出一個 <tab> 鍵。${address#.} 則是拿掉最前面的小點。 85 get_addr -b ${all[@]} # 跑 function 來計算 broadcast address : 86 echo -e "broadcast:\t${address#.}"
ref: http://blog.chinaunix.net/uid-20788470-id-1841646.html