public static unsafe uint Ipv6StringToAddress(string ipString, byte[] bytes, out uint scope) { Debug.Assert(ipString != null); Debug.Assert(bytes != null); Debug.Assert(bytes.Length == IPAddressParser.IPv6AddressBytes); string host, port; if (!TryPreprocessIPv6Address(ipString, out host, out port)) { scope = 0; return(unchecked ((uint)Interop.libc.EAI_NONAME)); } var hints = new Interop.libc.addrinfo { ai_flags = Interop.libc.AI_NUMERICHOST | Interop.libc.AI_NUMERICSERV, ai_family = Interop.libc.AF_INET6, ai_socktype = 0, ai_protocol = 0 }; Interop.libc.addrinfo *addrinfo = null; int err = Interop.libc.getaddrinfo(host, port, &hints, &addrinfo); if (err != 0) { Debug.Assert(addrinfo == null); scope = 0; return(unchecked ((uint)err)); } Debug.Assert(addrinfo != null); Debug.Assert(addrinfo->ai_addr != null); Debug.Assert(addrinfo->ai_addr->sa_family == Interop.libc.AF_INET6); Interop.libc.sockaddr_in6 *sockaddr = (Interop.libc.sockaddr_in6 *)addrinfo->ai_addr; Debug.Assert(sizeof(Interop.libc.in6_addr) == IPAddressParser.IPv6AddressBytes); for (int i = 0; i < IPAddressParser.IPv6AddressBytes; i++) { bytes[i] = sockaddr->sin6_addr.s6_addr[i]; } scope = sockaddr->sin6_scope_id; Interop.libc.freeaddrinfo(addrinfo); Debug.Assert(err == 0); return(0); }
public static unsafe uint Ipv4StringToAddress(string ipString, byte[] bytes, out ushort port) { Debug.Assert(ipString != null); Debug.Assert(bytes != null); Debug.Assert(bytes.Length == IPAddressParser.IPv4AddressBytes); port = 0; var hints = new Interop.libc.addrinfo { ai_flags = Interop.libc.AI_NUMERICHOST | Interop.libc.AI_NUMERICSERV, ai_family = Interop.libc.AF_INET, ai_socktype = 0, ai_protocol = 0 }; Interop.libc.addrinfo *addrinfo = null; int err = Interop.libc.getaddrinfo(ipString, null, &hints, &addrinfo); if (err != 0) { Debug.Assert(addrinfo == null); return(unchecked ((uint)err)); } Debug.Assert(addrinfo != null); Debug.Assert(addrinfo->ai_addr != null); Debug.Assert(addrinfo->ai_addr->sa_family == Interop.libc.AF_INET); Interop.libc.sockaddr_in *sockaddr = (Interop.libc.sockaddr_in *)addrinfo->ai_addr; sockaddr->sin_addr.s_addr.NetworkToNetworkBytes(bytes, 0); port = sockaddr->sin_port; Interop.libc.freeaddrinfo(addrinfo); Debug.Assert(err == 0); return(0); }
public static unsafe SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo, out int nativeErrorCode) { var hints = new Interop.libc.addrinfo { ai_family = Interop.libc.AF_UNSPEC, // Get all address families ai_flags = Interop.libc.AI_CANONNAME }; Interop.libc.addrinfo *addrinfo = null; string canonicalName = null; IPAddress[] ipAddresses; try { int errorCode = Interop.libc.getaddrinfo(name, null, &hints, &addrinfo); if (errorCode != 0) { hostinfo = NameResolutionUtilities.GetUnresolvedAnswer(name); nativeErrorCode = errorCode; return(GetSocketErrorForNativeError(errorCode)); } int numAddresses = 0; for (Interop.libc.addrinfo *ai = addrinfo; ai != null; ai = ai->ai_next) { if (canonicalName == null && ai->ai_canonname != null) { canonicalName = Marshal.PtrToStringAnsi((IntPtr)ai->ai_canonname); } if ((ai->ai_family != Interop.libc.AF_INET) && (ai->ai_family != Interop.libc.AF_INET6 || !SocketProtocolSupportPal.OSSupportsIPv6)) { continue; } numAddresses++; } if (numAddresses == 0) { ipAddresses = Array.Empty <IPAddress>(); } else { ipAddresses = new IPAddress[numAddresses]; Interop.libc.addrinfo *ai = addrinfo; for (int i = 0; i < numAddresses; ai = ai->ai_next) { Debug.Assert(ai != null); if ((ai->ai_family != Interop.libc.AF_INET) && (ai->ai_family != Interop.libc.AF_INET6 || !SocketProtocolSupportPal.OSSupportsIPv6)) { continue; } var sockaddr = new SocketAddress( ai->ai_family == Interop.libc.AF_INET ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6, checked ((int)ai->ai_addrlen)); for (int d = 0; d < ai->ai_addrlen; d++) { sockaddr[d] = ((byte *)ai->ai_addr)[d]; } if (ai->ai_family == Interop.libc.AF_INET) { ipAddresses[i] = ((IPEndPoint)IPEndPointStatics.Any.Create(sockaddr)).Address; } else { ipAddresses[i] = ((IPEndPoint)IPEndPointStatics.IPv6Any.Create(sockaddr)).Address; } i++; } } } finally { if (addrinfo != null) { Interop.libc.freeaddrinfo(addrinfo); } } hostinfo = new IPHostEntry { HostName = canonicalName ?? name, Aliases = Array.Empty <string>(), AddressList = ipAddresses }; nativeErrorCode = 0; return(SocketError.Success); }