[639] | 1 |
|
---|
| 2 | /*!
|
---|
| 3 | @brief IPアドレスを表すクラス
|
---|
| 4 | @author OverTaker
|
---|
| 5 | @date 2008/10/05
|
---|
| 6 | */
|
---|
| 7 |
|
---|
| 8 |
|
---|
| 9 | Namespace System
|
---|
| 10 | Namespace Net
|
---|
| 11 |
|
---|
| 12 | Class IPAddress
|
---|
| 13 | Address As *sockaddr
|
---|
| 14 | Length As Long
|
---|
| 15 | Public
|
---|
| 16 |
|
---|
| 17 | /*!
|
---|
| 18 | @brief コンストラクタ
|
---|
| 19 | */
|
---|
| 20 | Sub IPAddress()
|
---|
| 21 | Address = NULL
|
---|
| 22 | End Sub
|
---|
| 23 |
|
---|
| 24 | /*!
|
---|
| 25 | @brief コンストラクタ
|
---|
| 26 | @param IPアドレスを表した32bit値(ネットワークバイトオーダー)
|
---|
| 27 | */
|
---|
| 28 | Sub IPAddress(ip As DWord)
|
---|
| 29 | Length = SizeOf(sockaddr_in)
|
---|
| 30 | Dim temp = calloc(Length) As *sockaddr_in
|
---|
| 31 | temp->sin_addr.s_addr = ip
|
---|
| 32 | temp->sin_family = AF_INET
|
---|
| 33 | Address = temp
|
---|
| 34 | End Sub
|
---|
| 35 |
|
---|
| 36 | /*!
|
---|
| 37 | @brief デストラクタ
|
---|
| 38 | */
|
---|
| 39 | Sub ~IPAddress()
|
---|
| 40 | If Address Then free(Address)
|
---|
| 41 | End Sub
|
---|
| 42 |
|
---|
| 43 | /*!
|
---|
| 44 | @brief アドレスファミリを取得する。
|
---|
| 45 | @return アドレスファミリ
|
---|
| 46 | */
|
---|
| 47 | Function AddressFamily() As Sockets.AddressFamily
|
---|
| 48 | Return New Sockets.AddressFamily(Address->sa_family, "AddressFamily")
|
---|
| 49 | End Function
|
---|
| 50 |
|
---|
| 51 | /*!
|
---|
| 52 | @brief スコープを取得する。
|
---|
| 53 | @return スコープ
|
---|
| 54 | */
|
---|
| 55 | Function ScopeId() As DWord
|
---|
| 56 | If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
|
---|
| 57 | Dim sock = Address As *sockaddr_in6
|
---|
| 58 | Return sock->sin6_scope_id
|
---|
| 59 | Else
|
---|
| 60 | Throw New System.Net.Sockets.SocketException("IPAddress.ScopeId: AddressFamily is not IPv6.")
|
---|
| 61 | End If
|
---|
| 62 | End Function
|
---|
| 63 |
|
---|
| 64 | /*!
|
---|
| 65 | @brief スコープを設定する。
|
---|
| 66 | @param スコープ
|
---|
| 67 | */
|
---|
| 68 | Sub ScopeId(id As DWord)
|
---|
| 69 | If id > &HFFFFFFFF Then
|
---|
| 70 | Throw New ArgumentOutOfRangeException("IPAddress.ScopeId", New Int32(id), "id")
|
---|
| 71 | End If
|
---|
| 72 |
|
---|
| 73 | If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
|
---|
| 74 | Dim sock = Address As *sockaddr_in6
|
---|
| 75 | sock->sin6_scope_id = id
|
---|
| 76 | Else
|
---|
| 77 | Throw New System.Net.Sockets.SocketException("IPAddress.ScopeId: AddressFamily is not IPv6.")
|
---|
| 78 | End If
|
---|
| 79 | End Sub
|
---|
| 80 |
|
---|
| 81 | /*!
|
---|
| 82 | @brief リンクローカルアドレスかどうかを取得する。
|
---|
| 83 | @retval True リンクローカルアドレス
|
---|
| 84 | @retval Flase リンクローカルアドレスではない
|
---|
| 85 | */
|
---|
| 86 | Function IsIPv6LinkLocal() As Boolean
|
---|
| 87 | If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
|
---|
| 88 | Dim sock = Address As *sockaddr_in6
|
---|
| 89 | Return (sock->sin6_addr.s6_addr[0] = &HFF) And (sock->sin6_addr.s6_addr[1] = &H00)
|
---|
| 90 | Else
|
---|
| 91 | Throw New System.Net.Sockets.SocketException("IPAddress.IsIPv6LinkLocal: AddressFamily is not IPv6.")
|
---|
| 92 | End If
|
---|
| 93 | End Function
|
---|
| 94 |
|
---|
| 95 | /*!
|
---|
| 96 | @brief IPv6のマルチキャストアドレスかどうかを取得する。
|
---|
| 97 | @retval True IPv6のマルチキャストアドレス
|
---|
| 98 | @retval Flase IPv6のマルチキャストアドレス
|
---|
| 99 | */
|
---|
| 100 | Function IsIPv6Multicast() As Boolean
|
---|
| 101 | If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
|
---|
| 102 | Dim sock = Address As *sockaddr_in6
|
---|
| 103 | Return (sock->sin6_addr.s6_addr[0] = &HFE) And (sock->sin6_addr.s6_addr[1] = &H80)
|
---|
| 104 | Else
|
---|
| 105 | Throw New System.Net.Sockets.SocketException("IPAddress.IsIPv6Multicast: AddressFamily is not IPv6.")
|
---|
| 106 | End If
|
---|
| 107 | End Function
|
---|
| 108 |
|
---|
| 109 | /*!
|
---|
| 110 | @brief IPアドレスが等しいかどうかを取得する
|
---|
| 111 | @retval True 等しい
|
---|
| 112 | @retval Flase 等しくない
|
---|
| 113 | @note 手抜き実装
|
---|
| 114 | */
|
---|
| 115 | Override Function Equals(ip As Object) As Boolean
|
---|
| 116 | Return This.ToString() = ip.ToString()
|
---|
| 117 | End Function
|
---|
| 118 |
|
---|
| 119 | /*!
|
---|
| 120 | @brief IPアドレスを文字列で取得する
|
---|
| 121 | @return 文字列
|
---|
| 122 | */
|
---|
| 123 | Override Function ToString() As String
|
---|
| 124 | Dim temp[ELM(64)] As TCHAR
|
---|
| 125 | If WSAAddressToString(Address As sockaddr, Length, ByVal 0, temp, Len(temp)) Then
|
---|
| 126 | Throw New System.Net.Sockets.SocketException(WSAGetLastError())
|
---|
| 127 | Else
|
---|
| 128 | Return New String(temp)
|
---|
| 129 | End If
|
---|
| 130 | End Function
|
---|
| 131 |
|
---|
| 132 |
|
---|
| 133 |
|
---|
| 134 |
|
---|
| 135 | /*!
|
---|
| 136 | @brief 文字列からIPAddressクラスを作成する
|
---|
| 137 | @param 文字列で表したIPアドレス
|
---|
| 138 | @return IPAddressクラス
|
---|
| 139 | @exception 作成に失敗した場合
|
---|
| 140 | */
|
---|
| 141 | Static Function Parse(ip As String) As IPAddress
|
---|
| 142 | Dim address = New IPAddress
|
---|
| 143 | If TryParse(ip, address) Then
|
---|
| 144 | Return address
|
---|
| 145 | Else
|
---|
| 146 | Throw New System.Net.Sockets.SocketException(WSAGetLastError())
|
---|
| 147 | End If
|
---|
| 148 | End Function
|
---|
| 149 |
|
---|
| 150 | /*!
|
---|
| 151 | @brief 文字列からIPAddressクラスを作成する
|
---|
| 152 | @param[in] 文字列で表したIPアドレス
|
---|
| 153 | @param[out] 作成したIPアドレスを格納するIPAddressクラス
|
---|
| 154 | @retval True 成功
|
---|
| 155 | @retval False 失敗
|
---|
| 156 | */
|
---|
| 157 | Static Function TryParse(ip As String, ByRef ipAddress As IPAddress) As Boolean
|
---|
| 158 | If ipAddress.Address Then free(ipAddress.Address)
|
---|
| 159 |
|
---|
| 160 | If ip.Contains(".") Then
|
---|
| 161 | ipAddress.Address = Detail.CreateAddressFromIPv4String(ip)
|
---|
| 162 | ipAddress.Length = SizeOf(sockaddr_in)
|
---|
| 163 | ElseIf ip.Contains(":") Then
|
---|
| 164 | ipAddress.Address = Detail.CreateAddressFromIPv6String(ip)
|
---|
| 165 | ipAddress.Length = SizeOf(sockaddr_in6)
|
---|
| 166 | Else
|
---|
| 167 | Return False
|
---|
| 168 | End If
|
---|
| 169 |
|
---|
| 170 | If ipAddress.Address Then
|
---|
| 171 | Return True
|
---|
| 172 | Else
|
---|
| 173 | Return False
|
---|
| 174 | End If
|
---|
| 175 | End Function
|
---|
| 176 |
|
---|
| 177 | /*!
|
---|
| 178 | @brief Anyアドレスを作成
|
---|
| 179 | @return IPAddressクラス
|
---|
| 180 | */
|
---|
| 181 | Static Function Any() As IPAddress
|
---|
| 182 | Return New IPAddress(0)
|
---|
| 183 | End Function
|
---|
| 184 |
|
---|
| 185 | /*!
|
---|
| 186 | @brief ブロードキャストアドレスを作成
|
---|
| 187 | @return IPAddressクラス
|
---|
| 188 | */
|
---|
| 189 | Static Function Broadcast() As IPAddress
|
---|
| 190 | Return New IPAddress(&HFFFFFFFF)
|
---|
| 191 | End Function
|
---|
| 192 |
|
---|
| 193 | /*!
|
---|
| 194 | @brief ループバックアドレスを作成
|
---|
| 195 | @return IPAddressクラス
|
---|
| 196 | */
|
---|
| 197 | Static Function Loopback() As IPAddress
|
---|
| 198 | Return New IPAddress( HostToNetworkOrder(&HFF000000) )
|
---|
| 199 | End Function
|
---|
| 200 |
|
---|
| 201 | /*!
|
---|
| 202 | @brief Noneアドレスを作成
|
---|
| 203 | @return IPAddressクラス
|
---|
| 204 | */
|
---|
| 205 | Static Function None() As IPAddress
|
---|
| 206 | Return New IPAddress(&HFFFFFFFF)
|
---|
| 207 | End Function
|
---|
| 208 |
|
---|
| 209 | /*!
|
---|
| 210 | @brief IPv6 Anyアドレスを作成
|
---|
| 211 | @return IPAddressクラス
|
---|
| 212 | */
|
---|
| 213 | Static Function IPv6Any() As IPAddress
|
---|
| 214 | Return IPAddress.Parse("::")
|
---|
| 215 | End Function
|
---|
| 216 |
|
---|
| 217 | /*!
|
---|
| 218 | @brief IPv6 ループバックアドレスを作成
|
---|
| 219 | @return IPAddressクラス
|
---|
| 220 | */
|
---|
| 221 | Static Function IPv6Loopback() As IPAddress
|
---|
| 222 | Return IPAddress.Parse("::1")
|
---|
| 223 | End Function
|
---|
| 224 |
|
---|
| 225 | /*!
|
---|
| 226 | @brief IPv6 Noneアドレスを作成
|
---|
| 227 | @return IPAddressクラス
|
---|
| 228 | */
|
---|
| 229 | Static Function IPv6None() As IPAddress
|
---|
| 230 | Return IPAddress.Parse("::")
|
---|
| 231 | End Function
|
---|
| 232 |
|
---|
| 233 |
|
---|
| 234 |
|
---|
| 235 | /*!
|
---|
| 236 | @brief 16bitのホストバイトオーダーをネットワークバイトオーダーに変換する
|
---|
| 237 | @param ホストバイトオーダー
|
---|
| 238 | @return ネットワークバイトオーダー
|
---|
| 239 | */
|
---|
| 240 | Static Function HostToNetworkOrder(host As Word) As Word
|
---|
| 241 | Return htons(host)
|
---|
| 242 | End Function
|
---|
| 243 |
|
---|
| 244 | /*!
|
---|
| 245 | @brief 32bitのホストバイトオーダーをネットワークバイトオーダーに変換する
|
---|
| 246 | @param ホストバイトオーダー
|
---|
| 247 | @return ネットワークバイトオーダー
|
---|
| 248 | */
|
---|
| 249 | Static Function HostToNetworkOrder(host As DWord) As DWord
|
---|
| 250 | Return htonl(host)
|
---|
| 251 | End Function
|
---|
| 252 |
|
---|
| 253 | /*!
|
---|
| 254 | @brief 16bitのネットワークバイトオーダーをホストバイトオーダーに変換する
|
---|
| 255 | @param ネットワークバイトオーダー
|
---|
| 256 | @return ホストバイトオーダー
|
---|
| 257 | */
|
---|
| 258 | Static Function NetworkToHostOrder(network As Word) As Word
|
---|
| 259 | Return ntohs(network)
|
---|
| 260 | End Function
|
---|
| 261 |
|
---|
| 262 | /*!
|
---|
| 263 | @brief 32bitのネットワークバイトオーダーをホストバイトオーダーに変換する
|
---|
| 264 | @param ネットワークバイトオーダー
|
---|
| 265 | @return ホストバイトオーダー
|
---|
| 266 | */
|
---|
| 267 | Static Function NetworkToHostOrder(network As DWord) As DWord
|
---|
| 268 | Return ntohl(network)
|
---|
| 269 | End Function
|
---|
| 270 | End Class
|
---|
| 271 |
|
---|
| 272 | Namespace Detail
|
---|
| 273 |
|
---|
| 274 | /*!
|
---|
| 275 | @brief IPv4アドレスを表した文字列から、IPアドレスが設定されたsockaddr構造体を作成します
|
---|
| 276 | @param IPv4アドレスを表した文字列
|
---|
| 277 | @return sockaddr構造体を示すアドレス
|
---|
| 278 | */
|
---|
| 279 | Function CreateAddressFromIPv4String(ip As String) As *sockaddr
|
---|
| 280 | Dim address = malloc(SizeOf(sockaddr_in)) As *sockaddr_in
|
---|
| 281 | If WSAStringToAddress(ToTCStr(ip), AF_INET, ByVal 0, address As sockaddr, SizeOf(sockaddr_in)) Then
|
---|
| 282 | Return NULL
|
---|
| 283 | Else
|
---|
| 284 | Return address
|
---|
| 285 | End If
|
---|
| 286 | End Function
|
---|
| 287 |
|
---|
| 288 | /*!
|
---|
| 289 | @brief IPv6アドレスを表した文字列からIPアドレスが設定されたsockaddr構造体を作成します
|
---|
| 290 | @param IPv6アドレスを表した文字列
|
---|
| 291 | @return sockaddr構造体を示すアドレス
|
---|
| 292 | */
|
---|
| 293 | Function CreateAddressFromIPv6String(ip As String) As *sockaddr
|
---|
| 294 | Dim address = malloc(SizeOf(sockaddr_in6)) As *sockaddr_in6
|
---|
| 295 | If WSAStringToAddress(ToTCStr(ip), AF_INET6, ByVal 0, address As sockaddr, SizeOf(sockaddr_in6)) Then
|
---|
| 296 | Return NULL
|
---|
| 297 | Else
|
---|
| 298 | Return address
|
---|
| 299 | End If
|
---|
| 300 | End Function
|
---|
| 301 |
|
---|
| 302 | End Namespace
|
---|
| 303 |
|
---|
| 304 | End Namespace
|
---|
| 305 | End Namespace
|
---|