IPAddress.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / IPAddress.cs / 1 / IPAddress.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Net { 
    using System.Net.Sockets; 
    using System.Globalization;
    using System.Text; 
    using System.Security.Permissions;

    /// 
    ///    Provides an internet protocol (IP) address. 
    /// 
    [Serializable] 
    public class IPAddress { 

        public static readonly IPAddress Any = new IPAddress(0x0000000000000000); 
        public static readonly  IPAddress Loopback = new IPAddress(0x000000000100007F);
        public static readonly  IPAddress Broadcast = new IPAddress(0x00000000FFFFFFFF);
        public static readonly  IPAddress None = Broadcast;
 
        internal const long LoopbackMask = 0x000000000000007F;
        internal const string InaddrNoneString = "255.255.255.255"; 
        internal const string InaddrNoneStringHex = "0xff.0xff.0xff.0xff"; 
        internal const string InaddrNoneStringOct = "0377.0377.0377.0377";
 
        //
        // IPv6 Changes: make this internal so other NCL classes that understand about
        //               IPv4 and IPv4 can still access it rather than the obsolete property.
        // 
        internal long m_Address;
 
        [NonSerialized] 
        internal string m_ToString;
 
        public static readonly IPAddress IPv6Any      = new IPAddress(new byte[]{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },0);
        public static readonly IPAddress IPv6Loopback = new IPAddress(new byte[]{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },0);
        public static readonly IPAddress IPv6None     = new IPAddress(new byte[]{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },0);
 
        /// 
        ///    
        ///     Default to IPv4 address 
        ///   
        ///  
        private AddressFamily m_Family       = AddressFamily.InterNetwork;
        private ushort[]      m_Numbers      = new ushort[NumberOfLabels];
        private long          m_ScopeId      = 0;                             // really uint !
        private int           m_HashCode     = 0; 

        internal const int IPv4AddressBytes =  4; 
        internal const int IPv6AddressBytes = 16; 

        internal const int NumberOfLabels = IPv6AddressBytes / 2; 


        /// 
        ///     
        ///       Initializes a new instance of the 
        ///       class with the specified 
        ///       address. 
        ///    
        ///  
        public IPAddress(long newAddress) {
            if (newAddress<0 || newAddress>0x00000000FFFFFFFF) {
                throw new ArgumentOutOfRangeException("newAddress");
            } 
            m_Address = newAddress;
        } 
 

        ///  
        ///    
        ///       Constructor for an IPv6 Address with a specified Scope.
        ///    
        ///  
        public IPAddress(byte[] address,long scopeid) {
 
            if (address==null) { 
                throw new ArgumentNullException("address");
            } 

            if(address.Length != IPv6AddressBytes){
                throw new ArgumentException(SR.GetString(SR.dns_bad_ip_address), "address");
            } 

            m_Family = AddressFamily.InterNetworkV6; 
 
            for (int i = 0; i < NumberOfLabels; i++) {
                m_Numbers[i] = (ushort)(address[i * 2] * 256 + address[i * 2 + 1]); 
            }

            //
            // Consider: Since scope is only valid for link-local and site-local 
            //           addresses we could implement some more robust checking here
            // 
            if ( scopeid < 0 || scopeid > 0x00000000FFFFFFFF ) { 
                throw new ArgumentOutOfRangeException("scopeid");
            } 

            m_ScopeId = scopeid;
        }
        // 
        private IPAddress(ushort[] address, uint scopeid)
        { 
            m_Family = AddressFamily.InterNetworkV6; 
            m_Numbers = address;
            m_ScopeId = scopeid; 
        }


        ///  
        ///    
        ///       Constructor for IPv4 and IPv6 Address. 
        ///     
        /// 
        public IPAddress(byte[] address){ 
            if (address==null) {
                throw new ArgumentNullException("address");
            }
            if (address.Length != IPv4AddressBytes && address.Length != IPv6AddressBytes) 
            {
                throw new ArgumentException(SR.GetString(SR.dns_bad_ip_address), "address"); 
            } 

            if (address.Length == IPv4AddressBytes) 
            {
                m_Family = AddressFamily.InterNetwork;
                m_Address = ((address[3] << 24 | address[2] <<16 | address[1] << 8| address[0]) & 0x0FFFFFFFF);
            } 
            else {
                m_Family = AddressFamily.InterNetworkV6; 
 
                for (int i = 0; i < NumberOfLabels; i++) {
                    m_Numbers[i] = (ushort)(address[i * 2] * 256 + address[i * 2 + 1]); 
                }
            }
        }
 
        //
        // we need this internally since we need to interface with winsock 
        // and winsock only understands Int32 
        //
        internal IPAddress(int newAddress) { 
            m_Address = (long)newAddress & 0x00000000FFFFFFFF;
        }

 

        ///  
        /// Converts an IP address string to an  
        /// instance.
        ///  
        public static bool TryParse(string ipString, out IPAddress address) {
            address = InternalParse(ipString,true);
            return (address != null);
        } 

        public static IPAddress Parse(string ipString) { 
            return InternalParse(ipString,false); 
        }
 
        private static IPAddress InternalParse(string ipString, bool tryParse) {
            if (ipString == 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.IsValid(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); 
                }

                GlobalLog.Print("IPAddress::Parse() IPv6 ipString:[" + ValidationHelper.ToString(ipString) + "] errorCode: " + e.NativeErrorCode.ToString());
                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
            {
                // Cannot be an IPv6 address, so use the IPv4 routines to 
                // parse the string representation.  First check a heuristic to prevent the p/invoke as much as possible.  We
                // know the first character must be a digit (0 for the "0x" in hex), and the last character must be hex. 
                int address = -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(); 
                    address = UnsafeNclNativeMethods.OSSOCK.inet_addr(ipString);
                } 
#if BIGENDIAN 
                // OSSOCK.inet_addr always returns IP address as a byte array converted to int.
                // thus we need to convert the address into a uniform integer value. 
                address = (int)( ((uint)address << 24) | (((uint)address & 0x0000FF00) << 8) |
                (((uint)address >> 8) & 0x0000FF00) | ((uint)address >> 24) );
#endif
 
                GlobalLog.Print("IPAddress::Parse() ipString:" + ValidationHelper.ToString(ipString) + " inet_addr() returned address:" + address);
 
                if (address==-1 
                    && string.Compare(ipString, InaddrNoneString, StringComparison.Ordinal)!=0
                    && string.Compare(ipString, InaddrNoneStringHex, StringComparison.OrdinalIgnoreCase)!=0 
                    && string.Compare(ipString, InaddrNoneStringOct, StringComparison.Ordinal)!=0) {

                    if(tryParse){
                        return null; 
                    }
 
                    throw new FormatException(SR.GetString(SR.dns_bad_ip_address)); 
                }
 
                IPAddress returnValue = new IPAddress(address);

                return returnValue;
            } 
        } // Parse
 
 

        /** 
         * @deprecated IPAddress.Address is address family dependant, use Equals method for comparison.
         */
        /// 
        ///      
        ///         Mark this as deprecated.
        ///      
        ///  
        [Obsolete("This property has been deprecated. It is address family dependent. Please use IPAddress.Equals method to perform comparisons. http://go.microsoft.com/fwlink/?linkid=14202")]
        public long Address { 
            get {
                //
                // IPv6 Changes: Can't do this for IPv6, so throw an exception.
                // 
                //
                if ( m_Family == AddressFamily.InterNetworkV6 ) { 
                    throw new SocketException(SocketError.OperationNotSupported); 
                }
                else { 
                    return m_Address;
                }
            }
            set { 
                //
                // IPv6 Changes: Can't do this for IPv6 addresses 
                if ( m_Family == AddressFamily.InterNetworkV6 ) { 
                    throw new SocketException(SocketError.OperationNotSupported);
                } 
                else {
                    if (m_Address!=value) {
                        m_ToString = null;
                        m_Address = value; 
                    }
                } 
            } 
        }
 
        /// 
        /// 
        /// Provides a copy of the IPAddress internals as an array of bytes.
        ///  
        /// 
        public byte[] GetAddressBytes() { 
            byte[] bytes; 
            if (m_Family == AddressFamily.InterNetworkV6 ) {
                bytes = new byte[NumberOfLabels * 2]; 

                int j = 0;
                for ( int i = 0; i < NumberOfLabels; i++) {
                    bytes[j++] = (byte)((this.m_Numbers[i] >> 8) & 0xFF); 
                    bytes[j++] = (byte)((this.m_Numbers[i]     ) & 0xFF);
                } 
            } 
            else {
                bytes = new byte[IPv4AddressBytes]; 
                bytes[0] = (byte)(m_Address);
                bytes[1] = (byte)(m_Address >> 8);
                bytes[2] = (byte)(m_Address >> 16);
                bytes[3] = (byte)(m_Address >> 24); 
            }
            return bytes; 
        } 

        public AddressFamily AddressFamily { 
            get {
                return m_Family;
            }
        } 

        ///  
        ///     
        ///        IPv6 Scope identifier. This is really a uint32, but that isn't CLS compliant
        ///     
        /// 
        public long ScopeId {
            get {
                // 
                // Not valid for IPv4 addresses
                // 
                if ( m_Family == AddressFamily.InterNetwork ) { 
                    throw new SocketException(SocketError.OperationNotSupported);
                } 

                return m_ScopeId;
            }
            set { 
                //
                // Not valid for IPv4 addresses 
                // 
                if ( m_Family == AddressFamily.InterNetwork ) {
                    throw new SocketException(SocketError.OperationNotSupported); 
                }

                //
                // Consider: Since scope is only valid for link-local and site-local 
                //           addresses we could implement some more robust checking here
                // 
                if ( value < 0 || value > 0x00000000FFFFFFFF) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                if (m_ScopeId!=value) {
                    m_Address = value;
                    m_ScopeId = value;
                } 
            }
        } 
 
        /// 
        ///     
        ///       Converts the Internet address to either standard dotted quad format
        ///       or standard IPv6 representation.
        ///    
        ///  
        public override string ToString() {
            if (m_ToString==null) { 
                // 
                // IPv6 Changes: generate the IPV6 representation
                // 
                if ( m_Family == AddressFamily.InterNetworkV6 ) {

#if !FEATURE_PAL
                    int addressStringLength = 256; 
                    StringBuilder addressString = new StringBuilder(addressStringLength);
 
                    if(Socket.OSSupportsIPv6) 
                    {
                        SocketAddress saddr = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize); 
                        int j = 8;
                        for ( int i = 0; i < NumberOfLabels; i++) {
                            saddr[j++] = (byte)(this.m_Numbers[i] >> 8);
                            saddr[j++] = (byte)(this.m_Numbers[i]); 
                        }
                        if (m_ScopeId >0) { 
                            saddr[24] = (byte)m_ScopeId; 
                            saddr[25] = (byte)(m_ScopeId >> 8);
                            saddr[26] = (byte)(m_ScopeId >> 16); 
                            saddr[27] = (byte)(m_ScopeId >> 24);
                        }
                        SocketError errorCode =
                            UnsafeNclNativeMethods.OSSOCK.WSAAddressToString( 
                                saddr.m_Buffer,
                                saddr.m_Size, 
                                IntPtr.Zero, 
                                addressString,
                                ref addressStringLength); 
                        if (errorCode!=SocketError.Success) {
                            throw new SocketException();
                        }
                    } 
                    else
                    { 
                        const string numberFormat = "{0:x4}"; 
                        addressString.Append(String.Format(CultureInfo.InvariantCulture, numberFormat, m_Numbers[0])).Append(':');
                        addressString.Append(String.Format(CultureInfo.InvariantCulture, numberFormat, m_Numbers[1])).Append(':'); 
                        addressString.Append(String.Format(CultureInfo.InvariantCulture, numberFormat, m_Numbers[2])).Append(':');
                        addressString.Append(String.Format(CultureInfo.InvariantCulture, numberFormat, m_Numbers[3])).Append(':');
                        addressString.Append(String.Format(CultureInfo.InvariantCulture, numberFormat, m_Numbers[4])).Append(':');
                        addressString.Append(String.Format(CultureInfo.InvariantCulture, numberFormat, m_Numbers[5])).Append(':'); 
                        addressString.Append((m_Numbers[6]>>8)&0xFF).Append('.');
                        addressString.Append(m_Numbers[6]&0xFF).Append('.'); 
                        addressString.Append((m_Numbers[7]>>8)&0xFF).Append('.'); 
                        addressString.Append(m_Numbers[7]&0xFF);
                        if (m_ScopeId != 0) 
                        {
                            addressString.Append('%').Append((uint)m_ScopeId);
                        }
                    } 

                    m_ToString = addressString.ToString(); 
#else // !FEATURE_PAL 
                    // IPv6 addresses not supported for FEATURE_PAL
                    throw new SocketException(SocketError.OperationNotSupported); 
#endif // !FEATURE_PAL
                }
                else {
                    unsafe { 
                        const int MaxSize = 15;
                        int offset = MaxSize; 
                        char* addressString = stackalloc char[MaxSize]; 
                        int number = (int)((m_Address>>24)&0xFF);
                        do { 
                            addressString[--offset] = (char)('0' + number%10);
                            number = number/10;
                        } while (number>0);
                        addressString[--offset] = '.'; 
                        number = (int)((m_Address>>16)&0xFF);
                        do { 
                            addressString[--offset] = (char)('0' + number%10); 
                            number = number/10;
                        } while (number>0); 
                        addressString[--offset] = '.';
                        number = (int)((m_Address>>8)&0xFF);
                        do {
                            addressString[--offset] = (char)('0' + number%10); 
                            number = number/10;
                        } while (number>0); 
                        addressString[--offset] = '.'; 
                        number = (int)(m_Address&0xFF);
                        do { 
                            addressString[--offset] = (char)('0' + number%10);
                            number = number/10;
                        } while (number>0);
                        m_ToString = new string(addressString, offset, MaxSize-offset); 
                    }
                } 
            } 
            return m_ToString;
        } 

        public static long HostToNetworkOrder(long host) {
#if BIGENDIAN
            return host; 
#else
            return (((long)HostToNetworkOrder((int)host) & 0xFFFFFFFF) << 32) 
                    | ((long)HostToNetworkOrder((int)(host >> 32)) & 0xFFFFFFFF); 
#endif
        } 
        public static int HostToNetworkOrder(int host) {
#if BIGENDIAN
            return host;
#else 
            return (((int)HostToNetworkOrder((short)host) & 0xFFFF) << 16)
                    | ((int)HostToNetworkOrder((short)(host >> 16)) & 0xFFFF); 
#endif 
        }
        public static short HostToNetworkOrder(short host) { 
#if BIGENDIAN
            return host;
#else
            return (short)((((int)host & 0xFF) << 8) | (int)((host >> 8) & 0xFF)); 
#endif
        } 
        public static long NetworkToHostOrder(long network) { 
            return HostToNetworkOrder(network);
        } 
        public static int NetworkToHostOrder(int network) {
            return HostToNetworkOrder(network);
        }
        public static short NetworkToHostOrder(short network) { 
            return HostToNetworkOrder(network);
        } 
 
        public static bool IsLoopback(IPAddress address) {
            if ( address.m_Family == AddressFamily.InterNetworkV6 ) { 
                //
                // Do Equals test for IPv6 addresses
                //
                return address.Equals(IPv6Loopback); 
            }
            else { 
                return ((address.m_Address & IPAddress.LoopbackMask) == (IPAddress.Loopback.m_Address & IPAddress.LoopbackMask)); 
            }
        } 

        internal bool IsBroadcast {
            get {
                if ( m_Family == AddressFamily.InterNetworkV6 ) { 
                    //
                    // No such thing as a broadcast address for IPv6 
                    // 
                    return false;
                } 
                else {
                    return m_Address==Broadcast.m_Address;
                }
            } 
        }
 
        ///  
        ///    
        ///       V.Next: Determines if an address is an IPv6 Multicast address 
        ///    
        /// 
        public bool IsIPv6Multicast{
            get{ 
                return ( m_Family == AddressFamily.InterNetworkV6 ) &&
                    ( ( this.m_Numbers[0] & 0xFF00 ) == 0xFF00 ); 
            } 

        } 

        /*
        // Consider removing.
        ///  
        ///    
        ///       V.Next: Determines if an address is an IPv6 Multicast Node local address 
        ///     
        /// 
        internal bool IsIPv6MulticastNodeLocal() { 
            return ( IsIPv6Multicast ) &&
                   ( ( this.m_Numbers[0] & 0x000F ) == 1 );

        } 
        */
 
        ///  
        ///    
        ///       V.Next: Determines if an address is an IPv6 Multicast Link local address 
        ///    
        /// 
        /*
        // Consider removing. 
        internal bool IsIPv6MulticastLinkLocal() {
            return ( IsIPv6Multicast ) && 
                   ( ( this.m_Numbers[0] & 0x000F ) == 0x0002 ); 

        } 
        */

        /*
        // Consider removing. 
        /// 
        ///     
        ///       V.Next: Determines if an address is an IPv6 Multicast Site local address 
        ///    
        ///  
        internal bool IsIPv6MulticastSiteLocal() {
            return ( IsIPv6Multicast ) &&
                   ( ( this.m_Numbers[0] & 0x000F ) == 0x0005 );
 
        }
        */ 
 
        /// 
        ///     
        ///       V.Next: Determines if an address is an IPv6 Multicast Org local address
        ///    
        /// 
        /* 
        // Consider removing.
        internal bool IsIPv6MulticastOrgLocal() { 
            return ( IsIPv6Multicast ) && 
                   ( ( this.m_Numbers[0] & 0x000F ) == 0x0008 );
 
        }
        */

        /* 
        // Consider removing.
        ///  
        ///     
        ///       V.Next: Determines if an address is an IPv6 Multicast Global address
        ///     
        /// 
        internal bool IsIPv6MulticastGlobal() {
            return ( IsIPv6Multicast ) &&
                   ( ( this.m_Numbers[0] & 0x000F ) == 0x000E ); 

        } 
        */ 

        ///  
        ///    
        ///       V.Next: Determines if an address is an IPv6 Link Local address
        ///    
        ///  
        public bool IsIPv6LinkLocal {
            get{ 
                return ( m_Family == AddressFamily.InterNetworkV6 ) && 
                   ( ( this.m_Numbers[0] & 0xFFC0 ) == 0xFE80 );
            } 
        }

        /// 
        ///     
        ///       V.Next: Determines if an address is an IPv6 Site Local address
        ///     
        ///  
        public bool IsIPv6SiteLocal {
            get{ 
                return ( m_Family == AddressFamily.InterNetworkV6 ) &&
                   ( ( this.m_Numbers[0] & 0xFFC0 ) == 0xFEC0 );
            }
        } 

        /* 
        // Consider removing. 
        /// 
        ///     
        ///       V.Next: Determines if an address is an IPv4 Mapped Address
        ///    
        /// 
        internal bool IsIPv4Mapped() { 
            return ( m_Family == AddressFamily.InterNetworkV6 ) &&
                   ( m_Numbers[0] == 0x0000 ) && 
                   ( m_Numbers[1] == 0x0000 ) && 
                   ( m_Numbers[2] == 0x0000 ) &&
                   ( m_Numbers[3] == 0x0000 ) && 
                   ( m_Numbers[4] == 0x0000 ) &&
                   ( m_Numbers[5] == 0xffff );
        }
        */ 

        /* 
        // Consider removing. 
        /// 
        ///     
        ///       V.Next: Determines if an address is an IPv4 Compatible Address
        ///    
        /// 
        internal bool IsIPv4Compatible() { 
            return ( m_Family == AddressFamily.InterNetworkV6 ) &&
                   ( m_Numbers[0] == 0x0000 ) && 
                   ( m_Numbers[1] == 0x0000 ) && 
                   ( m_Numbers[2] == 0x0000 ) &&
                   ( m_Numbers[3] == 0x0000 ) && 
                   ( m_Numbers[4] == 0x0000 ) &&
                   ( m_Numbers[5] == 0x0000 ) &&
                   !( ( m_Numbers[6] == 0x0000 )              &&
                      ( ( m_Numbers[7] & 0xFF00 ) == 0x0000 ) && 
                      ( ( ( m_Numbers[7] & 0x00FF ) == 0x0000 ) || ( m_Numbers[7] & 0x00FF ) == 0x0001 ) );
        } 
        */ 

        internal bool Equals(object comparand, bool compareScopeId) { 
            if (!(comparand is IPAddress)) {
                return false;
            }
            // 
            // Compare families before address representations
            // 
            if ( m_Family != ((IPAddress)comparand).m_Family ) { 
                return false;
            } 
            if ( m_Family == AddressFamily.InterNetworkV6 ) {
                //
                // For IPv6 addresses, we must compare the full 128bit
                // representation. 
                //
                for ( int i = 0; i < NumberOfLabels; i++) { 
                    if ( ((IPAddress)comparand).m_Numbers[i] != this.m_Numbers[i] ) 
                        return false;
                } 
                //
                // In addition, the scope id's must match as well
                //
                if ( ((IPAddress)comparand).m_ScopeId == this.m_ScopeId ) 
                    return true;
                else 
                    return (compareScopeId? false : true); 
            }
            else { 
                //
                // For IPv4 addresses, compare the integer representation.
                //
                return ((IPAddress)comparand).m_Address==this.m_Address; 
            }
        } 
 
        /// 
        ///     
        ///       Compares two IP addresses.
        ///    
        /// 
        public override bool Equals(object comparand) { 
            return Equals(comparand, true);
        } 
 
        public override int GetHashCode() {
            // 
            // For IPv6 addresses, we cannot simply return the integer
            // representation as the hashcode. Instead, we calculate
            // the hashcode from the string representation of the address.
            // 
            if ( m_Family == AddressFamily.InterNetworkV6 ) {
                if ( m_HashCode == 0 ) 
                    m_HashCode = Uri.CalculateCaseInsensitiveHashCode(ToString()); 

                return m_HashCode; 
            }
            else {
                //
                // For IPv4 addresses, we can simply use the integer 
                // representation.
                // 
                return unchecked((int)m_Address); 
            }
        } 

        // For security, we need to be able to take an IPAddress and make a copy that's immutable and not derived.
        internal IPAddress Snapshot()
        { 
            switch (m_Family)
            { 
                case AddressFamily.InterNetwork: 
                    return new IPAddress(m_Address);
 
                case AddressFamily.InterNetworkV6:
                    return new IPAddress(m_Numbers, (uint) m_ScopeId);
            }
 
            throw new InternalException();
        } 
    } // class IPAddress 
} // namespace System.Net


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK