Home > Windows にまつわる e.t.c.

PowerShell で IPv4 アドレス計算


クラスフルなIPv4アドレスだと、サブネットマスク、CIDR、ネットワークID、ブロードキャストアドレスはパッとわかるのですが、これが /28 とか /14 だと簡単にはわからないです。

こいつを計算する PowerShell 関数作りました。(CIDR/サブネットマスクの両方に対応)

こんな感じに計算できます。(関数コピペした後に関数に引数渡します)

PS C:\> CalcNetworkAddressv4 192.168.53.43/28
Subnetmusk: 255.255.255.240
CIDR: /28
Network ID: 192.168.53.32
Broadcast Address: 192.168.53.47

 

PS C:\> CalcNetworkAddressv4 172.18.42.163 255.255.248.0
Subnetmusk: 255.255.248.0
CIDR: /21
Network ID: 172.18.40.0
Broadcast Address: 172.18.47.255

 

echo しているだけで戻り値はセットしていませんが、必要な値を戻り値にセットするようにすれば組み込みファンクションとして使えます。(そっち目的で作ったのを汎用化しました)

 

		
function CalcNetworkAddressv4( $IP, $Subnet ){

    # CIDR の時は サブネットマスクに変換する
    if( $Subnet -eq $null ){
        $Temp = $IP -split "/"
        $IP = $Temp[0]
        $CIDR = $Temp[1]
        $intCIDR = [int]$Temp[1]
        for( $i = 0 ; $i -lt 4 ; $i++ ){
            # all 1
            if( $intCIDR -ge 8 ){
                $Subnet += "255"
                $intCIDR -= 8
            }
            # all 0
            elseif($intCIDR -le 0){
                $Subnet += "0"
                $intCIDR = 0
            }
            else{
                # オクテット内 CIDR で表現できる最大数
                $intNumberOfNodes = [Math]::Pow(2,8 - $intCIDR)
                # サブネットマスクを求める
                $intSubnetOct = 256 - $intNumberOfNodes
                $Subnet += [string]$intSubnetOct
                $intCIDR = 0
            }
            
            # ラストオクテットにはピリオドを付けない
            if( $i -ne 3 ){
                $Subnet += "."
            }
        }
    }
    # サブネットマスクの時は CIDR を求める
    else{
        $SubnetOct = $Subnet -split "\."
        $intCIDR = 0
        for( $i = 0 ; $i -lt 4 ; $i++ ){
            # オクテット内のビットマスクを作る
            $intSubnetOct = $SubnetOct[$i]
            $strBitMask = [Convert]::ToString($intSubnetOct,2)
            
            # マスクのビット長カウント
            for( $j = 0 ; $j -lt 8; $j++ ){
                if( $strBitMask[$j] -eq "1" ){
                    $intCIDR++
                }
            }
        }
        $CIDR = [string]$intCIDR
    }

    echo "Subnetmusk:        $Subnet"
    echo "CIDR:              /$CIDR"
    
    $SubnetOct = $Subnet -split "\."
    $IPOct = $IP -split "\."

    # ネットワーク ID の算出
    $StrNetworkID = ""
    for( $i = 0 ; $i -lt 4 ; $i++ ){
        $intSubnetOct = [int]$SubnetOct[$i]
        $intIPOct = [int]$IPOct[$i]
        $intNetworkID = $intIPOct -band $intSubnetOct

        $StrNetworkID += [string]$intNetworkID

        if( $i -ne 3 ){
            $StrNetworkID += "."
        }
    }
    echo "Network ID:        $StrNetworkID"

    # ブロードキャストアドレスの算出
    $NetworkIDOct = $StrNetworkID  -split "\."
    for( $i = 0 ; $i -lt 4 ; $i++ ){
        $intSubnetOct = [int]$SubnetOct[$i]
        $intNetworkIDOct = [int]$NetworkIDOct[$i]
        $BitPattern = $intSubnetOct -bxor 255
        $intBroadcastAddress = $intNetworkIDOct -bxor $BitPattern
        $StrBroadcastAddress += [string]$intBroadcastAddress

        if( $i -ne 3 ){
            $StrBroadcastAddress += "."
        }
    }
    echo "Broadcast Address: $StrBroadcastAddress"
}


 

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.