/*! @brief IPアドレスを表すクラス @author OverTaker @date 2008/10/18 */ Namespace System Namespace Net Class IPAddress item As *Byte size As Long family As DWord Public /*! @brief アドレスをバイト配列で取得する @return アドレスを表したバイト列 @note このメソッドはライブラリ内のみで使用する目的で作られています。 */ Function Address() As *Byte Return item As *Byte End Function /*! @brief コンストラクタ */ Sub IPAddress() End Sub /*! @brief コンストラクタ @param IPアドレスを表した32bit値(ネットワークバイトオーダー) */ Sub IPAddress(ip As DWord) family = AF_INET size = SizeOf(in_addr) item = malloc(size) memcpy(item, VarPtr(ip), size) End Sub /*! @brief コンストラクタ @param SocketAddressクラスから作成 @note このコンストラクタはライブラリ内のみで使用する目的で作られています。 */ Sub IPAddress(addr As *sockaddr) family = addr.sa_family Select Case family Case AF_INET Dim addr4 = addr As *sockaddr_in size = SizeOf(in_addr) item = malloc(size) memcpy(item, VarPtr(addr4->sin_addr.s_addr), size) Case AF_INET6 Dim addr6 = addr As *sockaddr_in6 size = SizeOf(in6_addr) item = malloc(size) memcpy(item, VarPtr(addr6->sin6_addr.s6_addr), size) Case Else Throw New NotSupportedException("IPAddress: Not Supported AddressFamily.") End Select End Sub /*! @brief コンストラクタ @param IPアドレスを表したバイト列 @param IPアドレスの長さ @note このコンストラクタはライブラリ内のみで使用する目的で作られています。 */ Sub IPAddress(af As DWord, address As *Byte, len As Long) family = af size = len item = malloc(size) memcpy(item, address, size) End Sub /*! @brief デストラクタ */ Sub ~IPAddress() If item <> NULL Then free(item) End Sub Function Operator== (address As IPAddress) As Boolean Return Equals(address) End Function /*! @brief アドレスファミリを取得する。 @return アドレスファミリ */ Function AddressFamily() As Sockets.AddressFamily Return New System.Net.Sockets.AddressFamily(family, "AddressFamily") End Function /*! @brief スコープを取得する。 @return スコープ */ /* Function ScopeId() As DWord End Function */ /*! @brief リンクローカルアドレスかどうかを取得する。 @retval True リンクローカルアドレス @retval Flase リンクローカルアドレスではない */ Function IsIPv6LinkLocal() As Boolean If family = AF_INET6 Then Return (item[0] = &HFF) And (item[1] = &H00) Else Throw New System.Net.Sockets.SocketException("IPAddress.IsIPv6LinkLocal: AddressFamily is not IPv6.") End If End Function /*! @brief IPv6のマルチキャストアドレスかどうかを取得する。 @retval True IPv6のマルチキャストアドレス @retval Flase IPv6のマルチキャストアドレス */ Function IsIPv6Multicast() As Boolean If family = AF_INET6 Then Return (item[0] = &HFE) And (item[1] = &H80) Else Throw New System.Net.Sockets.SocketException("IPAddress.IsIPv6Multicast: AddressFamily is not IPv6.") End If End Function /*! @brief IPアドレスが等しいかどうかを取得する @retval True 等しい @retval Flase 等しくない */ Function Equals(ip As IPAddress) As Boolean If family = ip.family Then Dim i As Long For i = 0 To ELM(size) If item[i] <> ip.item[i] Then Return False Next Return True Else Return False End If End Function /*! @brief IPアドレスを文字列で取得する @return 文字列 */ Override Function ToString() As String Dim temp[ELM(64)] As TCHAR Dim ret As Long Select Case family Case AF_INET Dim addr4 As sockaddr_in addr4.sin_family = family As Integer addr4.sin_addr.s_addr = GetDWord(item) ret = WSAAddressToString(addr4 As sockaddr, SizeOf(sockaddr_in), ByVal 0, temp, Len(temp)) Case AF_INET6 Dim addr6 As sockaddr_in6 addr6.sin6_family = family As Word memcpy(addr6.sin6_addr.s6_addr, item, size) ret = WSAAddressToString(addr6 As sockaddr, SizeOf(sockaddr_in6), ByVal 0, temp, Len(temp)) Case Else Throw New NotSupportedException("IPAddress.ToString: Unknown Protocol.") End Select If ret Then Throw New System.Net.Sockets.SocketException(WSAGetLastError(), "IPAddress.ToString: Failed to WSAAddressToString.") Else Return New String(temp) End If End Function /*! @brief 文字列からIPAddressクラスを作成する @param 文字列で表したIPアドレス @return IPAddressクラス @exception 作成に失敗した場合 */ Static Function Parse(ip As String) As IPAddress Dim ipAddress = New IPAddress If TryParse(ip, ipAddress) Then Return ipAddress Else Throw New System.Net.Sockets.SocketException(WSAGetLastError(), "IPAddress.Parse: Failed to Parse.") End If End Function /*! @brief 文字列からIPAddressクラスを作成する @param[in] 文字列で表したIPアドレス @param[out] 作成したIPアドレスを格納するIPAddressクラス @retval True 成功 @retval False 失敗 */ Static Function TryParse(ip As String, ByRef address As IPAddress) As Boolean address = New IPAddress If ip.Contains(".") Then address.family = AF_INET address.item = Detail.CreateAddressFromIPv4String(ip) address.size = SizeOf(in_addr) ElseIf ip.Contains(":") Then address.family = AF_INET6 address.item = Detail.CreateAddressFromIPv6String(ip) address.size = SizeOf(in6_addr) Else Return False End If If address.item <> NULL Then Return True Else address = Nothing Return False End If End Function /*! @brief Anyアドレスを作成 @return IPAddressクラス */ Static Function Any() As IPAddress Return New IPAddress(0 As DWord) End Function /*! @brief ブロードキャストアドレスを作成 @return IPAddressクラス */ Static Function Broadcast() As IPAddress Return New IPAddress(&HFFFFFFFF) End Function /*! @brief ループバックアドレスを作成 @return IPAddressクラス */ Static Function Loopback() As IPAddress Return New IPAddress( HostToNetworkOrder(&H7F000001) ) End Function /*! @brief Noneアドレスを作成 @return IPAddressクラス */ Static Function None() As IPAddress Return New IPAddress(&HFFFFFFFF) End Function /*! @brief IPv6 Anyアドレスを作成 @return IPAddressクラス */ Static Function IPv6Any() As IPAddress Return IPAddress.Parse("::") End Function /*! @brief IPv6 ループバックアドレスを作成 @return IPAddressクラス */ Static Function IPv6Loopback() As IPAddress Return IPAddress.Parse("::1") End Function /*! @brief IPv6 Noneアドレスを作成 @return IPAddressクラス */ Static Function IPv6None() As IPAddress Return IPAddress.Parse("::") End Function /*! @brief 16bitのホストバイトオーダーをネットワークバイトオーダーに変換する @param ホストバイトオーダー @return ネットワークバイトオーダー */ Static Function HostToNetworkOrder(host As Word) As Word Return htons(host) End Function /*! @brief 32bitのホストバイトオーダーをネットワークバイトオーダーに変換する @param ホストバイトオーダー @return ネットワークバイトオーダー */ Static Function HostToNetworkOrder(host As DWord) As DWord Return htonl(host) End Function /*! @brief 16bitのネットワークバイトオーダーをホストバイトオーダーに変換する @param ネットワークバイトオーダー @return ホストバイトオーダー */ Static Function NetworkToHostOrder(network As Word) As Word Return ntohs(network) End Function /*! @brief 32bitのネットワークバイトオーダーをホストバイトオーダーに変換する @param ネットワークバイトオーダー @return ホストバイトオーダー */ Static Function NetworkToHostOrder(network As DWord) As DWord Return ntohl(network) End Function End Class Namespace Detail /*! @brief IPv4アドレスを表した文字列からアドレスを作成する @param IPv4アドレスを表したバイト列 @return バイト列 */ Function CreateAddressFromIPv4String(ip As String) As *Byte Dim addr4 As sockaddr_in If WSAStringToAddress(ToTCStr(ip), AF_INET, ByVal 0, addr4 As sockaddr, SizeOf(sockaddr_in)) Then Return NULL Else Dim item = malloc(SizeOf(in_addr)) As *Byte memcpy(item, VarPtr(addr4.sin_addr.s_addr), SizeOf(in_addr)) Return item End If End Function /*! @brief IPv6アドレスを表した文字列からアドレスを作成する @param IPv6アドレスを表したバイト列 @return バイト列 */ Function CreateAddressFromIPv6String(ip As String) As *Byte Dim addr6 As sockaddr_in6 If WSAStringToAddress(ToTCStr(ip), AF_INET6, ByVal 0, addr6 As sockaddr, SizeOf(sockaddr_in6)) Then Return NULL Else Dim item = malloc(SizeOf(in6_addr)) As *Byte memcpy(item, addr6.sin6_addr.s6_addr, SizeOf(in6_addr)) Return item End If End Function End Namespace End Namespace End Namespace