IPアドレスとネットマスク値からネットワーク情報を表示する

スクリプト名: ipaddr.sh
書式: ipaddr.sh IPアドレス ネットマスク値
目的: IPアドレスとネットマスク値からネットワーク情報を表示する
戻り値: 成功:0 失敗:1

#!/bin/sh
. Error_Msg.sh && . Arg_Nums.sh && . Char_Type.sh || exit 9
Arg_Nums -eq 2 "$@"

#IPアドレスとネットマスク値をオクテット単位に分割するための関数
Split_IPAddress () {
    _IFS_ORIG=$IFS; IFS="."; _COUNT=0
    for _OC in $1; do
        IFS=$_IFS_ORIG
        Char_Type "$_OC"
        [ $? = 1 ] || { Error_Msg "$0" "Characters must be numeric."; exit 1    ; }
        _COUNT=$(($_COUNT + 1))
        eval _OC${_COUNT}="$_OC"
        IFS="."
    done
    IFS=$_IFS_ORIG
}

#各オクテットの値が空でないことを確認してから空にする関数
Reset_Octet () {
    [ "$_OC2" = "" -o "$_OC3" = "" -o "$_OC4" = "" ]\
        && { Error_Msg "$0" "The number of Octet was lacking."; exit 1; }
    _OC1=; _OC2=; _OC3=; _OC4=
}

#IPアドレスの分割
Split_IPAddress $1
_OC_AD1=$_OC1; _OC_AD2=$_OC2; _OC_AD3=$_OC3; _OC_AD4=$_OC4
Reset_Octet

#ネットマスク値の書式判定
echo "$2" | grep -q "\."

#IPアドレス形式の場合
if [ $? = 0 ]; then
    Split_IPAddress "$2"
    _OC_MS1=$_OC1; _OC_MS2=$_OC2; _OC_MS3=$_OC3; _OC_MS4=$_OC4; _OC=
    Reset_Octet
    for _OC in $_OC_MS1 $_OC_MS2 $_OC_MS3 $_OC_MS4; do
        _BIT8=$(echo "obase=2; $_OC" | bc)
        while [ ${#_BIT8} != 8 ]; do _BIT8=0$_BIT8; done
        _BIT32=$_BIT32$_BIT8
    done
    echo $_BIT32 | grep -q "01"
    [ $? = 0 ] && { Error_Msg "$0" "Netmask value was wrong."; exit 1; }
    _CIDR=$(( $(echo $_BIT32 | sed s/0*$// | wc -c ) - 1 ))

#CIDR形式の場合
else
    Char_Type "$2"
    [ $? = 1 ] || { Error_Msg "$0" "Characters must be numeric."; exit 1; }
    _CIDR=$2; _COUNT=1; _OC=
    while [ $_COUNT -le 32 ]; do
        [ $_COUNT -le $2 ] && _OC=${_OC}1 || _OC=${_OC}0
        if [ $(( $_COUNT % 8 )) = 0 ]; then
            _OC=$(echo "ibase=2; $_OC" | bc)
            eval _OC_MS$(( $_COUNT / 8 ))=$_OC
            _OC=
        fi
        _COUNT=$(( $_COUNT + 1 ))
    done
fi

#ネットワークアドレスとブロードキャストアドレスの生成
_OC_NW1=$(( $_OC_AD1 & $_OC_MS1 )); _OC_BC1=$(( $_OC_AD1 | $_OC_MS1 ^ 255 )) 
_OC_NW2=$(( $_OC_AD2 & $_OC_MS2 )); _OC_BC2=$(( $_OC_AD2 | $_OC_MS2 ^ 255 )) 
_OC_NW3=$(( $_OC_AD3 & $_OC_MS3 )); _OC_BC3=$(( $_OC_AD3 | $_OC_MS3 ^ 255 )) 
_OC_NW4=$(( $_OC_AD4 & $_OC_MS4 )); _OC_BC4=$(( $_OC_AD4 | $_OC_MS4 ^ 255 ))

#表示
echo "IP_ADDRESS        = $_OC_AD1.$_OC_AD2.$_OC_AD3.$_OC_AD4"
echo "NETMASK(IPADDR)   = $_OC_MS1.$_OC_MS2.$_OC_MS3.$_OC_MS4"
echo "NETMASK(CIDR)     = $_CIDR"
echo "NETWORK_ADDRESS   = $_OC_NW1.$_OC_NW2.$_OC_NW3.$_OC_NW4"
echo "BROADCAST_ADDRESS = $_OC_BC1.$_OC_BC2.$_OC_BC3.$_OC_BC4"