VBAでIPv4アドレスを扱うコードの部品
概要
後で自分がコピペする用のメモ。
SWのACL絡みのチェック等をエクセル上で行うことが業務上増えたので、IPv4アドレスあたりに関するVBAのパーツをいくつか用意した。
人によっては何かに使えるかもしれない。
※元々は作成中のクラスのコードから抜き出したものなので、いきなり記載していないメンバ変数がコード中に現れているかもしれない。できる限りその影響はないように編集はしたものの、その状態で実行できるかは未確認。
コードの部品
・サブネットマスク32種類の情報を作る
'サブネットマスク構造体 Type subnetmask subnetmaskStr As String ' 文字列版サブネットマスク subnetmaskByte(4) As Byte End Type Dim subnetmaskList(32) As subnetmask ' サブネットマスク構造体の配列 。要素番号-1がそのままプレフィックスを示 Const base128 As Byte = 128 Dim mask As Byte, i As Long mask = 0 For i = 0 To 7 mask = mask + base128 ¥ (2 ^ i) subnetmaskList(i).subnetmaskByte(0) = mask subnetmaskList(i).subnetmaskByte(1) = 0 subnetmaskList(i).subnetmaskByte(2) = 0 subnetmaskList(i).subnetmaskByte(3) = 0 subnetmaskList(i).subnetmaskStr = subnetmaskList(i).subnetmaskByte(0) & "." & subnetmaskList(i).subnetmaskByte(1) & "." & subnetmaskList(i).subnetmaskByte(2) & "." & subnetmaskList(i).subnetmaskByte(3) subnetmaskList(i + 8).subnetmaskByte(0) = 255 subnetmaskList(i + 8).subnetmaskByte(1) = mask subnetmaskList(i + 8).subnetmaskByte(2) = 0 subnetmaskList(i + 8).subnetmaskByte(3) = 0 subnetmaskList(i + 8).subnetmaskStr = subnetmaskList(i).subnetmaskByte(0) & "." & subnetmaskList(i).subnetmaskByte(1) & "." & subnetmaskList(i).subnetmaskByte(2) & "." & subnetmaskList(i).subnetmaskByte(3) subnetmaskList(i + 16).subnetmaskByte(0) = 255 subnetmaskList(i + 16).subnetmaskByte(1) = 255 subnetmaskList(i + 16).subnetmaskByte(2) = mask subnetmaskList(i + 16).subnetmaskByte(3) = 0 subnetmaskList(i + 16).subnetmaskStr = subnetmaskList(i).subnetmaskByte(0) & "." & subnetmaskList(i).subnetmaskByte(1) & "." & subnetmaskList(i).subnetmaskByte(2) & "." & subnetmaskList(i).subnetmaskByte(3) subnetmaskList(i + 24).subnetmaskByte(0) = 255 subnetmaskList(i + 24).subnetmaskByte(1) = 255 subnetmaskList(i + 24).subnetmaskByte(2) = 255 subnetmaskList(i + 24).subnetmaskByte(3) = mask subnetmaskList(i + 24).subnetmaskStr = subnetmaskList(i).subnetmaskByte(0) & "." & subnetmaskList(i).subnetmaskByte(1) & "." & subnetmaskList(i).subnetmaskByte(2) & "." & subnetmaskList(i).subnetmaskByte(3) Next 'For i = 0 To 31 ' Debug.Print "eee " & subnetmaskList(i).subnetmaskByte(0) & "." & subnetmaskList(i).subnetmaskByte(1) & "." & subnetmaskList(i).subnetmaskByte(2) & "." & subnetmaskList(i).subnetmaskByte(3) & "." 'Next
・サブネットマスク(xxx.xxx.xxx.xxx)をプレフィックスに変換する。
戻り値は1〜32。
Function SubnetmaskToPrefix(subnet As String) As Long Dim aa As Long, bb As Long Dim tmp As Variant Const base128 As Byte = 128 Dim mask As Byte Dim countPrefix As Long ' 結果のプレフィックスを格納 Dim resAnd As Byte ' And を取ったときの結果を一時的に格納 Dim endFlag As Boolean ' ループを抜けるかどうかのフラグ tmp = Split(subnet, ".") num = UBound(tmp) If num <> 3 Then Exit Function End If countPrefix = 0 endFlag = False For aa = 0 To 3 ' オクテット毎ループ mask = 0 For bb = 0 To 7 '8bit 分ループ mask = mask + base128 ¥ (2 ^ bb) resAnd = mask And CByte(tmp(aa)) ' 今のビット位置でAndをとる。同じ位置のbitが立っていれば、次のIFの結果はイコールになる。 'Debug.Print "mask : " & mask & " , resAnd : " & resAnd If mask <> resAnd Then 'And の結果が違えばそこでループを抜ける endFlag = True Exit For End If countPrefix = countPrefix + 1 Next If endFlag = True Then Exit For End If Next 'Debug.Print "prefix: " & countPrefix SubnetmaskToPrefix = countPrefix End Function
・IPv4 の文字列を受け取り、引数(参照)の配列にByte型で格納する。
Sub AddressStrToByte(ipv4str As String, ByRef resultArr() As Byte) Dim tmp As Variant, num As Integer tmp = Split(ipv4str, ".") num = UBound(tmp) If num <> 3 Then Exit Sub End If resultArr(0) = CByte(tmp(0)) resultArr(1) = CByte(tmp(1)) resultArr(2) = CByte(tmp(2)) resultArr(3) = CByte(tmp(3)) End Sub
・あるNW内に、あるIPv4アドレスが含まれるかチェックする。
引数のdata()はIPv4アドレスの各オクテットの値を格納したByte型で要素数4の配列。
引数のprefixは、data()のアドレスのプレフィックス。1〜32。
ipv4strは、調べたいIPv4アドレスの文字列。
data()のNW内に、ipv4strのアドレスが含まれているかチェックする。含まれていればTrueを返す。
また、前述のサブネットマスク32種類の情報(subnetmaskList(32) As subnetmask)が既に存在して、この関数内からアクセスできる前提。
Function checkBelogToNetwork(ByRef data() As Byte, prefix As Long, ipv4str As String) As Boolean Dim nwaddress(4) As Byte nwaddress(0) = data(0) And subnetmaskList(prefix - 1).subnetmaskByte(0) nwaddress(1) = data(1) And subnetmaskList(prefix - 1).subnetmaskByte(1) nwaddress(2) = data(2) And subnetmaskList(prefix - 1).subnetmaskByte(2) nwaddress(3) = data(3) And subnetmaskList(prefix - 1).subnetmaskByte(3) Dim ckIPByte(4) As Byte Call AddressStrToByte(ipv4str, ckIPByte()) Dim nwad2(4) As Byte nwad2(0) = ckIPByte(0) And subnetmaskList(prefix - 1).subnetmaskByte(0) nwad2(1) = ckIPByte(1) And subnetmaskList(prefix - 1).subnetmaskByte(1) nwad2(2) = ckIPByte(2) And subnetmaskList(prefix - 1).subnetmaskByte(2) nwad2(3) = ckIPByte(3) And subnetmaskList(prefix - 1).subnetmaskByte(3) If nwaddress(0) = nwad2(0) And nwaddress(1) = nwad2(1) And nwaddress(2) = nwad2(2) And nwaddress(3) = nwad2(3) Then checkBelogToNetwork = True Else checkBelogToNetwork = False End If End Function