Ejemplo n.º 1
0
        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();
                    }
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }