/// <summary>
        ///   Overrides System.Object.ToString to return
        ///   this object rendered in a quad-dotted notation
        /// </summary>
        public override string ToString()
        {
            if (m_Family == AddressFamily.InterNetwork)
            {
                return(ToString(m_Address));
            }
            else
            {
                ushort[] numbers = m_Numbers.Clone() as ushort[];

                for (int i = 0; i < numbers.Length; i++)
                {
                    numbers[i] = (ushort)NetworkToHostOrder((short)numbers[i]);
                }

                IPv6Address v6 = new IPv6Address(numbers);
                v6.ScopeId = ScopeId;
                return(v6.ToString());
            }
        }
Exemple #2
0
        public static bool TryParse(string ipString, out IPv6Address result)
        {
            result = null;
            if (ipString == null)
            {
                return(false);
            }

            if (ipString.Length > 2 &&
                ipString [0] == '[' &&
                ipString [ipString.Length - 1] == ']')
            {
                ipString = ipString.Substring(1, ipString.Length - 2);
            }

            if (ipString.Length < 2)
            {
                return(false);
            }

            int prefixLen = 0;
            int scopeId   = 0;
            int pos       = ipString.LastIndexOf('/');

            if (pos != -1)
            {
                string prefix = ipString.Substring(pos + 1);
                if (!TryParse(prefix, out prefixLen))
                {
                    prefixLen = -1;
                }
                if (prefixLen < 0 || prefixLen > 128)
                {
                    return(false);
                }
                ipString = ipString.Substring(0, pos);
            }
            else
            {
                pos = ipString.LastIndexOf('%');
                if (pos != -1)
                {
                    string prefix = ipString.Substring(pos + 1);
                    if (!TryParse(prefix, out scopeId))
                    {
                        scopeId = 0;
                    }
                    ipString = ipString.Substring(0, pos);
                }
            }

            //
            // At this point the prefix/suffixes have been removed
            // and we only have to deal with the ipv4 or ipv6 addressed
            //
            ushort [] addr = new ushort [8];

            //
            // Is there an ipv4 address at the end?
            //
            bool ipv4 = false;
            int  pos2 = ipString.LastIndexOf(':');

            if (pos2 == -1)
            {
                return(false);
            }

            int slots = 0;

            if (pos2 < (ipString.Length - 1))
            {
                string ipv4Str = ipString.Substring(pos2 + 1);
                if (ipv4Str.IndexOf('.') != -1)
                {
                    IPAddress ip;

                    if (!IPAddress.TryParse(ipv4Str, out ip))
                    {
                        return(false);
                    }

                    long a = ip.InternalIPv4Address;
                    addr [6] = (ushort)(((int)(a & 0xff) << 8) + ((int)((a >> 8) & 0xff)));
                    addr [7] = (ushort)(((int)((a >> 16) & 0xff) << 8) + ((int)((a >> 24) & 0xff)));
                    if (pos2 > 0 && ipString [pos2 - 1] == ':')
                    {
                        ipString = ipString.Substring(0, pos2 + 1);
                    }
                    else
                    {
                        ipString = ipString.Substring(0, pos2);
                    }
                    ipv4  = true;
                    slots = 2;
                }
            }

            //
            // Only an ipv6 block remains, either:
            // "hexnumbers::hexnumbers", "hexnumbers::" or "hexnumbers"
            //
            int c = ipString.IndexOf("::", StringComparison.Ordinal);

            if (c != -1)
            {
                int right_slots = Fill(addr, ipString.Substring(c + 2));
                if (right_slots == -1)
                {
                    return(false);
                }

                if (right_slots + slots > 8)
                {
                    return(false);
                }

                int d = 8 - slots - right_slots;
                for (int i = right_slots; i > 0; i--)
                {
                    addr [i + d - 1] = addr [i - 1];
                    addr [i - 1]     = 0;
                }

                int left_slots = Fill(addr, ipString.Substring(0, c));
                if (left_slots == -1)
                {
                    return(false);
                }

                if (left_slots + right_slots + slots > 7)
                {
                    return(false);
                }
            }
            else
            {
                if (Fill(addr, ipString) != 8 - slots)
                {
                    return(false);
                }
            }

            // Now check the results in the ipv6-address range only
            bool ipv6 = false;

            for (int i = 0; i < slots; i++)
            {
                if (addr [i] != 0 || i == 5 && addr [i] != 0xffff)
                {
                    ipv6 = true;
                }
            }

            // check IPv4 validity
            if (ipv4 && !ipv6)
            {
                for (int i = 0; i < 5; i++)
                {
                    if (addr [i] != 0)
                    {
                        return(false);
                    }
                }

                if (addr [5] != 0 && addr [5] != 0xffff)
                {
                    return(false);
                }
            }

            result = new IPv6Address(addr, prefixLen, scopeId);
            return(true);
        }