Esempio n. 1
0
        internal static StringBuilder IPv6AddressToStringHelper(ushort[] address, uint scopeId)
        {
            const int     INET6_ADDRSTRLEN = 65;
            StringBuilder buffer           = StringBuilderCache.Acquire(INET6_ADDRSTRLEN);

            if (IPv6AddressHelper.ShouldHaveIpv4Embedded(address))
            {
                // We need to treat the last 2 ushorts as a 4-byte IPv4 address,
                // so output the first 6 ushorts normally, followed by the IPv4 address.
                AppendSections(address, 0, 6, buffer);
                if (buffer[buffer.Length - 1] != ':')
                {
                    buffer.Append(':');
                }
                buffer.Append(IPAddressParser.IPv4AddressToString(ExtractIPv4Address(address)));
            }
            else
            {
                // No IPv4 address.  Output all 8 sections as part of the IPv6 address
                // with normal formatting rules.
                AppendSections(address, 0, 8, buffer);
            }

            // If there's a scope ID, append it.
            if (scopeId != 0)
            {
                buffer.Append('%').Append(scopeId);
            }

            return(buffer);
        }
Esempio n. 2
0
        public static unsafe bool Ipv6StringToAddress(ReadOnlySpan <char> ipSpan, ushort *numbers, int numbersLength, out uint scope)
        {
            Debug.Assert(numbers != null);
            Debug.Assert(numbersLength >= IPAddressParserStatics.IPv6AddressShorts);

            int end = ipSpan.Length;

            bool isValid = false;

            fixed(char *ipStringPtr = &MemoryMarshal.GetReference(ipSpan))
            {
                isValid = IPv6AddressHelper.IsValidStrict(ipStringPtr, 0, ref end);
            }

            if (isValid || (end != ipSpan.Length))
            {
                string scopeId = null;
                IPv6AddressHelper.Parse(ipSpan, numbers, 0, ref scopeId);

                long result = 0;
                if (!string.IsNullOrEmpty(scopeId))
                {
                    if (scopeId.Length < 2)
                    {
                        scope = 0;
                        return(false);
                    }

                    for (int i = 1; i < scopeId.Length; i++)
                    {
                        char c = scopeId[i];
                        if (c < '0' || c > '9')
                        {
                            scope = 0;
#if MONO // zoneId can be a string, see https://github.com/dotnet/corefx/issues/27529
                            return(true);
#else
                            return(false);
#endif
                        }
                        result = (result * 10) + (c - '0');
                        if (result > uint.MaxValue)
                        {
                            scope = 0;
                            return(false);
                        }
                    }
                }

                scope = (uint)result;
                return(true);
            }

            scope = 0;
            return(false);
        }
Esempio n. 3
0
        public static unsafe bool Ipv6StringToAddress(ReadOnlySpan <char> ipSpan, ushort *numbers, int numbersLength, out uint scope)
        {
            Debug.Assert(numbers != null);
            Debug.Assert(numbersLength >= IPAddressParserStatics.IPv6AddressShorts);

            int end = ipSpan.Length;

            bool isValid = false;

            fixed(char *ipStringPtr = &ipSpan.DangerousGetPinnableReference())
            {
                isValid = IPv6AddressHelper.IsValidStrict(ipStringPtr, 0, ref end);
            }

            if (isValid || (end != ipSpan.Length))
            {
                string scopeId = null;
                IPv6AddressHelper.Parse(ipSpan, numbers, 0, ref scopeId);

                long result = 0;
                if (!string.IsNullOrEmpty(scopeId))
                {
                    if (scopeId.Length < 2)
                    {
                        scope = 0;
                        return(false);
                    }

                    for (int i = 1; i < scopeId.Length; i++)
                    {
                        char c = scopeId[i];
                        if (c < '0' || c > '9')
                        {
                            scope = 0;
                            return(false);
                        }
                        result = (result * 10) + (c - '0');
                        if (result > uint.MaxValue)
                        {
                            scope = 0;
                            return(false);
                        }
                    }
                }

                scope = (uint)result;
                return(true);
            }

            scope = 0;
            return(false);
        }
Esempio n. 4
0
        public static unsafe bool Ipv6StringToAddress(string ipString, ushort *numbers, int numbersLength, out uint scope)
        {
            Debug.Assert(ipString != null);
            Debug.Assert(numbers != null);
            Debug.Assert(numbersLength >= IPAddressParserStatics.IPv6AddressShorts);

            int end = ipString.Length;

            fixed(char *name = ipString)
            {
                if (IPv6AddressHelper.IsValidStrict(name, 0, ref end) || (end != ipString.Length))
                {
                    string scopeId = null;
                    IPv6AddressHelper.Parse(ipString, numbers, 0, ref scopeId);

                    long result = 0;
                    if (!string.IsNullOrEmpty(scopeId))
                    {
                        if (scopeId.Length < 2)
                        {
                            scope = 0;
                            return(false);
                        }

                        for (int i = 1; i < scopeId.Length; i++)
                        {
                            char c = scopeId[i];
                            if (c < '0' || c > '9')
                            {
                                scope = 0;
                                return(false);
                            }
                            result = (result * 10) + (c - '0');
                            if (result > uint.MaxValue)
                            {
                                scope = 0;
                                return(false);
                            }
                        }
                    }

                    scope = (uint)result;
                    return(true);
                }
            }

            scope = 0;
            return(false);
        }
Esempio n. 5
0
        public static unsafe bool Ipv6StringToAddress(ReadOnlySpan <char> ipSpan, Span <ushort> numbers, int numbersLength, out uint scope)
        {
            Debug.Assert(numbers != null);
            Debug.Assert(numbersLength >= IPAddressParserStatics.IPv6AddressShorts);

            int end = ipSpan.Length;

            bool isValid = false;

            fixed(char *ipStringPtr = &MemoryMarshal.GetReference(ipSpan))
            {
                isValid = IPv6AddressHelper.IsValidStrict(ipStringPtr, 0, ref end);
            }

            if (isValid || (end != ipSpan.Length))
            {
                string scopeId = null;
                IPv6AddressHelper.Parse(ipSpan, numbers, 0, ref scopeId);

                if (scopeId?.Length > 1)
                {
                    if (uint.TryParse(scopeId.AsSpan(1), NumberStyles.None, CultureInfo.InvariantCulture, out scope))
                    {
                        return(true); // scopeId is a numeric value
                    }
                    uint interfaceIndex = InterfaceInfoPal.InterfaceNameToIndex(scopeId);
                    if (interfaceIndex > 0)
                    {
                        scope = interfaceIndex;
                        return(true); // scopeId is a known interface name
                    }
                    // scopeId is an unknown interface name
                }
                // scopeId is not presented
                scope = 0;
                return(true);
            }

            scope = 0;
            return(false);
        }
Esempio n. 6
0
        /// <summary>
        /// Appends each of the numbers in address in indexed range [fromInclusive, toExclusive),
        /// while also replacing the longest sequence of 0s found in that range with "::", as long
        /// as the sequence is more than one 0.
        /// </summary>
        private static void AppendSections(ushort[] address, int fromInclusive, int toExclusive, StringBuilder buffer)
        {
            // Find the longest sequence of zeros to be combined into a "::"
            ReadOnlySpan <ushort> addressSpan = new ReadOnlySpan <ushort>(address, fromInclusive, toExclusive - fromInclusive);

            (int zeroStart, int zeroEnd) = IPv6AddressHelper.FindCompressionRange(addressSpan);
            bool needsColon = false;

            // Output all of the numbers before the zero sequence
            for (int i = fromInclusive; i < zeroStart; i++)
            {
                if (needsColon)
                {
                    buffer.Append(':');
                }
                needsColon = true;
                AppendHex(address[i], buffer);
            }

            // Output the zero sequence if there is one
            if (zeroStart >= 0)
            {
                buffer.Append("::");
                needsColon    = false;
                fromInclusive = zeroEnd;
            }

            // Output everything after the zero sequence
            for (int i = fromInclusive; i < toExclusive; i++)
            {
                if (needsColon)
                {
                    buffer.Append(':');
                }
                needsColon = true;
                AppendHex(address[i], buffer);
            }
        }
Esempio n. 7
0
        private static IPAddress InternalParse(string ipString, bool tryParse)
        {
            if (ipString == null)
            {
                if (tryParse)
                {
                    return(null);
                }
                throw new ArgumentNullException("ipString");
            }

            //
            // IPv6 Changes: Detect probable IPv6 addresses and use separate
            //               parse method.
            //
            if (ipString.IndexOf(':') != -1)
            {
#if !FEATURE_PAL
                //
                // If the address string contains the colon character
                // then it can only be an IPv6 address. Use a separate
                // parse method to unpick it all. Note: we don't support
                // port specification at the end of address and so can
                // make this decision.
                //
                // We need to make sure that Socket is initialized for this
                // call !
                //
                SocketException e     = null;
                long            scope = 0;
                if (Socket.OSSupportsIPv6)
                {
                    byte[]        bytes = new byte[IPv6AddressBytes];
                    SocketAddress saddr = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);

                    SocketError errorCode =
                        UnsafeNclNativeMethods.OSSOCK.WSAStringToAddress(
                            ipString,
                            AddressFamily.InterNetworkV6,
                            IntPtr.Zero,
                            saddr.m_Buffer,
                            ref saddr.m_Size);

                    if (errorCode == SocketError.Success)
                    {
                        //
                        // We have to set up the address by hand now, to avoid initialization
                        // recursion problems that we get if we use IPEndPoint.Create.
                        //
                        for (int i = 0; i < IPv6AddressBytes; i++)
                        {
                            bytes[i] = saddr[i + 8];
                        }
                        //
                        // Scope
                        //
                        scope = (long)((saddr[27] << 24) + (saddr[26] << 16) + (saddr[25] << 8) + (saddr[24]));
                        return(new IPAddress(bytes, scope));
                    }

                    if (tryParse)
                    {
                        return(null);
                    }

                    e = new SocketException();
                }
                else
                {
                    unsafe
                    {
                        int offset = 0;
                        if (ipString[0] != '[')
                        {
                            ipString = ipString + ']'; //for Uri parser to find the terminator.
                        }
                        else
                        {
                            offset = 1;
                        }

                        int end = ipString.Length;
                        fixed(char *name = ipString)
                        {
                            if (IPv6AddressHelper.IsValidStrict(name, offset, ref end) || (end != ipString.Length))
                            {
                                ushort[] numbers = new ushort[NumberOfLabels];
                                string   scopeId = null;
                                fixed(ushort *numbPtr = numbers)
                                {
                                    IPv6AddressHelper.Parse(ipString, numbPtr, 0, ref scopeId);
                                }

                                //
                                // Scope
                                //
                                if (scopeId == null || scopeId.Length == 0)
                                {
                                    return(new IPAddress(numbers, 0));
                                }

                                uint result;
                                scopeId = scopeId.Substring(1);
                                if (UInt32.TryParse(scopeId, NumberStyles.None, null, out result))
                                {
                                    return(new IPAddress(numbers, result));
                                }
                            }
                        }
                    }
                    if (tryParse)
                    {
                        return(null);
                    }
                    e = new SocketException(SocketError.InvalidArgument);
                }

                throw new FormatException(SR.GetString(SR.dns_bad_ip_address), e);
#else // !FEATURE_PAL
                // IPv6 addresses not supported for FEATURE_PAL
                throw new SocketException(SocketError.OperationNotSupported);
#endif // !FEATURE_PAL
            }
            else
            // The new IPv4 parser is better than the native one, it can parse 0xFFFFFFFF. (It's faster too).
            {
                // App-Compat: The .NET 4.0 parser used Winsock.  When we removed this initialization in 4.5 it
                // uncovered bugs in IIS's management APIs where they failed to initialize Winsock themselves.
                // DDCC says we need to keep this for an in place release, but to remove it in the next SxS release.
                Socket.InitializeSockets();
                ///////////////////////////

                int  end = ipString.Length;
                long result;
                unsafe
                {
                    fixed(char *name = ipString)
                    {
                        result = IPv4AddressHelper.ParseNonCanonical(name, 0, ref end, true);
                    }
                }

                if (result == IPv4AddressHelper.Invalid || end != ipString.Length)
                {
                    if (tryParse)
                    {
                        return(null);
                    }

                    throw new FormatException(SR.GetString(SR.dns_bad_ip_address));
                }

                // IPv4AddressHelper always returns IP address in a format that we need to reverse.
                result = (((result & 0x000000FF) << 24) | (((result & 0x0000FF00) << 8)
                                                           | (((result & 0x00FF0000) >> 8) | ((result & 0xFF000000) >> 24))));

                return(new IPAddress(result));
            }
        } // Parse
        private static unsafe IPAddress InternalParse(string ipString, bool tryParse)
        {
            if (ipString == null)
            {
                throw new ArgumentNullException("ipString");
            }
            if (ipString.IndexOf(':') != -1)
            {
                SocketException innerException = null;
                if (Socket.OSSupportsIPv6)
                {
                    byte[]        buffer  = new byte[0x10];
                    SocketAddress address = new SocketAddress(System.Net.Sockets.AddressFamily.InterNetworkV6, 0x1c);
                    if (UnsafeNclNativeMethods.OSSOCK.WSAStringToAddress(ipString, System.Net.Sockets.AddressFamily.InterNetworkV6, IntPtr.Zero, address.m_Buffer, ref address.m_Size) == SocketError.Success)
                    {
                        for (int i = 0; i < 0x10; i++)
                        {
                            buffer[i] = address[i + 8];
                        }
                        return(new IPAddress(buffer, (((address[0x1b] << 0x18) + (address[0x1a] << 0x10)) + (address[0x19] << 8)) + address[0x18]));
                    }
                    if (tryParse)
                    {
                        return(null);
                    }
                    innerException = new SocketException();
                }
                else
                {
                    int start = 0;
                    if (ipString[0] != '[')
                    {
                        ipString = ipString + ']';
                    }
                    else
                    {
                        start = 1;
                    }
                    int length = ipString.Length;
                    fixed(char *str2 = ((char *)ipString))
                    {
                        char *name = str2;

                        if (IPv6AddressHelper.IsValidStrict(name, start, ref length) || (length != ipString.Length))
                        {
                            uint     num5;
                            ushort[] numArray = new ushort[8];
                            string   scopeId  = null;
                            fixed(ushort *numRef = numArray)
                            {
                                IPv6AddressHelper.Parse(ipString, numRef, 0, ref scopeId);
                            }

                            if ((scopeId == null) || (scopeId.Length == 0))
                            {
                                return(new IPAddress(numArray, 0));
                            }
                            if (uint.TryParse(scopeId.Substring(1), NumberStyles.None, null, out num5))
                            {
                                return(new IPAddress(numArray, num5));
                            }
                        }
                    }

                    if (tryParse)
                    {
                        return(null);
                    }
                    innerException = new SocketException(SocketError.InvalidArgument);
                }
                throw new FormatException(SR.GetString("dns_bad_ip_address"), innerException);
            }
            int newAddress = -1;

            if ((((ipString.Length > 0) && (ipString[0] >= '0')) && (ipString[0] <= '9')) && ((((ipString[ipString.Length - 1] >= '0') && (ipString[ipString.Length - 1] <= '9')) || ((ipString[ipString.Length - 1] >= 'a') && (ipString[ipString.Length - 1] <= 'f'))) || ((ipString[ipString.Length - 1] >= 'A') && (ipString[ipString.Length - 1] <= 'F'))))
            {
                Socket.InitializeSockets();
                newAddress = UnsafeNclNativeMethods.OSSOCK.inet_addr(ipString);
            }
            if (((newAddress == -1) && (string.Compare(ipString, "255.255.255.255", StringComparison.Ordinal) != 0)) && ((string.Compare(ipString, "0xff.0xff.0xff.0xff", StringComparison.OrdinalIgnoreCase) != 0) && (string.Compare(ipString, "0377.0377.0377.0377", StringComparison.Ordinal) != 0)))
            {
                if (!tryParse)
                {
                    throw new FormatException(SR.GetString("dns_bad_ip_address"));
                }
                return(null);
            }
            return(new IPAddress(newAddress));
        }