public string sortIpAddressList(string IPAddressList) { //--------------------------------------------------------------- //If the input is nothing, return nothing //--------------------------------------------------------------- if (IPAddressList == null || IPAddressList.Length == 0) { return(string.Empty); } //--------------------------------------------------------------- //The input string is supposed to be a list of IPAddress strings //separated by a semicolon //--------------------------------------------------------------- string[] IPAddressStrings = IPAddressList.Split(new char[] { ';' }); if (IPAddressStrings.Length > MAX_IPADDRESS_LIST_LENGTH) { throw new ArgumentException(string.Format( SR.GetString(SR.net_max_ip_address_list_length_exceeded), MAX_IPADDRESS_LIST_LENGTH), "IPAddressList"); } //---------------------------------------------------------------- //If there are no separators, just return the original string //---------------------------------------------------------------- if (IPAddressStrings.Length == 1) { return(IPAddressList); } //---------------------------------------------------------------- //Parse the strings into Socket Address buffers //---------------------------------------------------------------- SocketAddress[] SockAddrIn6List = new SocketAddress[IPAddressStrings.Length]; for (int i = 0; i < IPAddressStrings.Length; i++) { //Trim leading and trailing spaces IPAddressStrings[i] = IPAddressStrings[i].Trim(); if (IPAddressStrings[i].Length == 0) { throw new ArgumentException(SR.GetString(SR.dns_bad_ip_address), "IPAddressList"); } SocketAddress saddrv6 = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize); //Parse the string to a v6 address structure SocketError errorCode = UnsafeNclNativeMethods.OSSOCK.WSAStringToAddress( IPAddressStrings[i], AddressFamily.InterNetworkV6, IntPtr.Zero, saddrv6.m_Buffer, ref saddrv6.m_Size); if (errorCode != SocketError.Success) { //Could not parse this into a SOCKADDR_IN6 //See if we can parse this into s SOCKEADDR_IN SocketAddress saddrv4 = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize); errorCode = UnsafeNclNativeMethods.OSSOCK.WSAStringToAddress( IPAddressStrings[i], AddressFamily.InterNetwork, IntPtr.Zero, saddrv4.m_Buffer, ref saddrv4.m_Size); if (errorCode != SocketError.Success) { //This address is neither IPv4 nor IPv6 string throw throw new ArgumentException(SR.GetString(SR.dns_bad_ip_address), "IPAddressList"); } else { //This is a valid IPv4 address. We need to map this to a mapped v6 address IPEndPoint dummy = new IPEndPoint(IPAddress.Any, 0); IPEndPoint IPv4EndPoint = (IPEndPoint)dummy.Create(saddrv4); byte[] IPv4AddressBytes = IPv4EndPoint.Address.GetAddressBytes(); byte[] IPv6MappedAddressBytes = new byte[16]; //IPv6 is 16 bytes address for (int j = 0; j < 10; j++) { IPv6MappedAddressBytes[j] = 0x00; } IPv6MappedAddressBytes[10] = 0xFF; IPv6MappedAddressBytes[11] = 0xFF; IPv6MappedAddressBytes[12] = IPv4AddressBytes[0]; IPv6MappedAddressBytes[13] = IPv4AddressBytes[1]; IPv6MappedAddressBytes[14] = IPv4AddressBytes[2]; IPv6MappedAddressBytes[15] = IPv4AddressBytes[3]; IPAddress v6Address = new IPAddress(IPv6MappedAddressBytes); IPEndPoint IPv6EndPoint = new IPEndPoint(v6Address, IPv4EndPoint.Port); saddrv6 = IPv6EndPoint.Serialize(); } } //At this point,we have SOCKADDR_IN6 buffer //add them to the list SockAddrIn6List[i] = saddrv6; } //---------------------------------------------------------------- //All the IPAddress strings are parsed into //either a native v6 address or mapped v6 address //The Next step is to prepare for calling the WSAIOctl //By creating a SOCKET_ADDRESS_LIST //---------------------------------------------------------------- int cbRequiredBytes = Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS_LIST)) + (SockAddrIn6List.Length - 1) * Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS)); Dictionary <IntPtr, KeyValuePair <SocketAddress, string> > UnmanagedToManagedMapping = new Dictionary <IntPtr, KeyValuePair <SocketAddress, string> >(); GCHandle[] GCHandles = new GCHandle[SockAddrIn6List.Length]; for (int i = 0; i < SockAddrIn6List.Length; i++) { GCHandles[i] = GCHandle.Alloc(SockAddrIn6List[i].m_Buffer, GCHandleType.Pinned); } IntPtr pSocketAddressList = Marshal.AllocHGlobal(cbRequiredBytes); try { //--------------------------------------------------- //Create a socket address list structure //and set the pointers to the pinned sock addr buffers //--------------------------------------------------- unsafe { UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS_LIST *pList = (UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS_LIST *)pSocketAddressList; pList->iAddressCount = SockAddrIn6List.Length; //Set the number of addresses UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS *pSocketAddresses = &pList->Addresses; for (int i = 0; i < pList->iAddressCount; i++) { pSocketAddresses[i].iSockaddrLength = SocketAddress.IPv6AddressSize; pSocketAddresses[i].lpSockAddr = GCHandles[i].AddrOfPinnedObject(); UnmanagedToManagedMapping[pSocketAddresses[i].lpSockAddr] = new KeyValuePair <SocketAddress, string>(SockAddrIn6List[i], IPAddressStrings[i]); } //--------------------------------------------------- //Create a socket and ask it to sort the list //--------------------------------------------------- Socket s = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); int cbProcessed = s.IOControl( IOControlCode.AddressListSort, pSocketAddressList, //Input buffer cbRequiredBytes, //Buffer size pSocketAddressList, //Outbuffer - same as in buffer cbRequiredBytes //out buffer size - same as in buffer size ); //--------------------------------------------------- //At this point The sorting is complete //--------------------------------------------------- StringBuilder sb = new StringBuilder(); for (int i = 0; i < pList->iAddressCount; i++) { IntPtr lpSockAddr = pSocketAddresses[i].lpSockAddr; KeyValuePair <SocketAddress, string> kv = UnmanagedToManagedMapping[lpSockAddr]; sb.Append(kv.Value); if (i != pList->iAddressCount - 1) { sb.Append(";"); } } return(sb.ToString()); } } finally { if (pSocketAddressList != IntPtr.Zero) { Marshal.FreeHGlobal(pSocketAddressList); } for (int i = 0; i < GCHandles.Length; i++) { if (GCHandles[i].IsAllocated) { GCHandles[i].Free(); } } } }
public unsafe string sortIpAddressList(string IPAddressList) { string str; if ((IPAddressList == null) || (IPAddressList.Length == 0)) { return(string.Empty); } string[] strArray = IPAddressList.Split(new char[] { ';' }); if (strArray.Length > MAX_IPADDRESS_LIST_LENGTH) { throw new ArgumentException(string.Format(SR.GetString("net_max_ip_address_list_length_exceeded"), MAX_IPADDRESS_LIST_LENGTH), "IPAddressList"); } if (strArray.Length == 1) { return(IPAddressList); } SocketAddress[] addressArray = new SocketAddress[strArray.Length]; for (int i = 0; i < strArray.Length; i++) { strArray[i] = strArray[i].Trim(); if (strArray[i].Length == 0) { throw new ArgumentException(SR.GetString("dns_bad_ip_address"), "IPAddressList"); } SocketAddress address = new SocketAddress(AddressFamily.InterNetworkV6, 0x1c); if (UnsafeNclNativeMethods.OSSOCK.WSAStringToAddress(strArray[i], AddressFamily.InterNetworkV6, IntPtr.Zero, address.m_Buffer, ref address.m_Size) != SocketError.Success) { SocketAddress socketAddress = new SocketAddress(AddressFamily.InterNetwork, 0x10); if (UnsafeNclNativeMethods.OSSOCK.WSAStringToAddress(strArray[i], AddressFamily.InterNetwork, IntPtr.Zero, socketAddress.m_Buffer, ref socketAddress.m_Size) != SocketError.Success) { throw new ArgumentException(SR.GetString("dns_bad_ip_address"), "IPAddressList"); } IPEndPoint point = new IPEndPoint(IPAddress.Any, 0); IPEndPoint point2 = (IPEndPoint)point.Create(socketAddress); byte[] addressBytes = point2.Address.GetAddressBytes(); byte[] buffer2 = new byte[0x10]; for (int k = 0; k < 10; k++) { buffer2[k] = 0; } buffer2[10] = 0xff; buffer2[11] = 0xff; buffer2[12] = addressBytes[0]; buffer2[13] = addressBytes[1]; buffer2[14] = addressBytes[2]; buffer2[15] = addressBytes[3]; IPAddress address3 = new IPAddress(buffer2); address = new IPEndPoint(address3, point2.Port).Serialize(); } addressArray[i] = address; } int cb = Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS_LIST)) + ((addressArray.Length - 1) * Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS))); Dictionary <IntPtr, KeyValuePair <SocketAddress, string> > dictionary = new Dictionary <IntPtr, KeyValuePair <SocketAddress, string> >(); GCHandle[] handleArray = new GCHandle[addressArray.Length]; for (int j = 0; j < addressArray.Length; j++) { handleArray[j] = GCHandle.Alloc(addressArray[j].m_Buffer, GCHandleType.Pinned); } IntPtr optionInValue = Marshal.AllocHGlobal(cb); try { UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS_LIST *socket_address_listPtr = (UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS_LIST *)optionInValue; socket_address_listPtr->iAddressCount = addressArray.Length; UnsafeNclNativeMethods.OSSOCK.SOCKET_ADDRESS *socket_addressPtr = &socket_address_listPtr->Addresses; for (int m = 0; m < socket_address_listPtr->iAddressCount; m++) { socket_addressPtr[m].iSockaddrLength = 0x1c; socket_addressPtr[m].lpSockAddr = handleArray[m].AddrOfPinnedObject(); dictionary[socket_addressPtr[m].lpSockAddr] = new KeyValuePair <SocketAddress, string>(addressArray[m], strArray[m]); } new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp).IOControl(IOControlCode.AddressListSort, optionInValue, cb, optionInValue, cb); StringBuilder builder = new StringBuilder(); for (int n = 0; n < socket_address_listPtr->iAddressCount; n++) { IntPtr lpSockAddr = socket_addressPtr[n].lpSockAddr; KeyValuePair <SocketAddress, string> pair = dictionary[lpSockAddr]; builder.Append(pair.Value); if (n != (socket_address_listPtr->iAddressCount - 1)) { builder.Append(";"); } } str = builder.ToString(); } finally { if (optionInValue != IntPtr.Zero) { Marshal.FreeHGlobal(optionInValue); } for (int num7 = 0; num7 < handleArray.Length; num7++) { if (handleArray[num7].IsAllocated) { handleArray[num7].Free(); } } } return(str); }