< Summary

Line coverage
22%
Covered lines: 84
Uncovered lines: 297
Coverable lines: 381
Total lines: 788
Line coverage: 22%
Branch coverage
10%
Covered branches: 12
Total branches: 110
Branch coverage: 10.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)100%11100%
.ctor(...)0%220%
.ctor(...)0%220%
.ctor(...)100%11100%
.ctor(...)100%110%
.ctor(...)0%220%
.ctor(...)0%440%
ReadUInt16NumbersFromBytes(...)0%660%
IsValid(...)100%11100%
IsValidUtf8(...)100%11100%
TryParse(...)50%2262.5%
TryParse(...)100%11100%
TryParse(...)100%11100%
System.IUtf8SpanParsable<System.Net.IPAddress>.TryParse(...)100%110%
System.IParsable<System.Net.IPAddress>.TryParse(...)100%110%
System.ISpanParsable<System.Net.IPAddress>.TryParse(...)100%110%
Parse(...)100%110%
Parse(...)100%110%
Parse(...)100%110%
System.IUtf8SpanParsable<System.Net.IPAddress>.Parse(...)100%110%
System.ISpanParsable<System.Net.IPAddress>.Parse(...)100%110%
System.IParsable<System.Net.IPAddress>.Parse(...)100%110%
TryWriteBytes(...)0%660%
WriteIPv6Bytes(...)0%880%
WriteIPv4Bytes(...)100%110%
GetAddressBytes()0%440%
ToString()75%44100%
System.IFormattable.ToString(...)100%110%
TryFormat(...)100%110%
TryFormat(...)100%110%
System.ISpanFormattable.TryFormat(...)100%110%
System.IUtf8SpanFormattable.TryFormat(...)100%110%
TryFormatCore(...)0%10100%
HostToNetworkOrder(...)0%220%
HostToNetworkOrder(...)50%22100%
HostToNetworkOrder(...)0%220%
NetworkToHostOrder(...)100%110%
NetworkToHostOrder(...)100%11100%
NetworkToHostOrder(...)100%110%
IsLoopback(...)0%440%
Equals(...)50%22100%
Equals(...)66.66%6685.71%
GetHashCode()0%440%
MapToIPv6()0%220%
MapToIPv4()0%220%
ThrowAddressNullException()100%110%
ThrowSocketOperationNotSupported()100%110%
ThrowSocketOperationNotSupportedReadOnly()100%110%
.ctor(...)100%110%
.ctor(...)100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Buffers.Binary;
 5using System.Diagnostics;
 6using System.Diagnostics.CodeAnalysis;
 7using System.Net.Sockets;
 8using System.Numerics;
 9using System.Runtime.CompilerServices;
 10using System.Runtime.InteropServices;
 11using System.Runtime.Intrinsics;
 12
 13namespace System.Net
 14{
 15    /// <devdoc>
 16    ///   <para>
 17    ///     Provides an Internet Protocol (IP) address.
 18    ///   </para>
 19    /// </devdoc>
 20    public class IPAddress : ISpanFormattable, ISpanParsable<IPAddress>, IUtf8SpanFormattable, IUtf8SpanParsable<IPAddre
 21    {
 022        public static readonly IPAddress Any = new ReadOnlyIPAddress([0, 0, 0, 0]);
 023        public static readonly IPAddress Loopback = new ReadOnlyIPAddress([127, 0, 0, 1]);
 024        public static readonly IPAddress Broadcast = new ReadOnlyIPAddress([255, 255, 255, 255]);
 025        public static readonly IPAddress None = Broadcast;
 26
 27        internal const uint LoopbackMaskHostOrder = 0xFF000000;
 28
 029        public static readonly IPAddress IPv6Any = new ReadOnlyIPAddress([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 030        public static readonly IPAddress IPv6Loopback = new ReadOnlyIPAddress([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 031        public static readonly IPAddress IPv6None = IPv6Any;
 32
 033        private static readonly IPAddress s_loopbackMappedToIPv6 = new ReadOnlyIPAddress([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 34
 35        /// <summary>
 36        /// For IPv4 addresses, this field stores the Address.
 37        /// For IPv6 addresses, this field stores the ScopeId.
 38        /// Instead of accessing this field directly, use the <see cref="PrivateAddress"/> or <see cref="PrivateScopeId"
 39        /// </summary>
 40        private uint _addressOrScopeId;
 41
 42        /// <summary>
 43        /// This field is only used for IPv6 addresses. A null value indicates that this instance is an IPv4 address.
 44        /// </summary>
 45        private readonly ushort[]? _numbers;
 46
 47        /// <summary>
 48        /// A lazily initialized cache of the result of calling <see cref="ToString"/>.
 49        /// </summary>
 50        private string? _toString;
 51
 52        /// <summary>
 53        /// A lazily initialized cache of the <see cref="GetHashCode"/> value.
 54        /// </summary>
 55        private int _hashCode;
 56
 57        internal const int NumberOfLabels = IPAddressParserStatics.IPv6AddressBytes / 2;
 58
 59        [MemberNotNullWhen(false, nameof(_numbers))]
 60        private bool IsIPv4
 61        {
 1212962            get { return _numbers == null; }
 63        }
 64
 65        [MemberNotNullWhen(true, nameof(_numbers))]
 66        private bool IsIPv6
 67        {
 1365068            get { return _numbers != null; }
 69        }
 70
 71        internal uint PrivateAddress
 72        {
 73            get
 49274            {
 49275                Debug.Assert(IsIPv4);
 49276                return _addressOrScopeId;
 49277            }
 78            private set
 24679            {
 24680                Debug.Assert(IsIPv4);
 24681                _toString = null;
 24682                _hashCode = 0;
 24683                _addressOrScopeId = value;
 24684            }
 85        }
 86
 87        internal uint PrivateIPv4Address
 88        {
 89            get
 090            {
 091                Debug.Assert(IsIPv4 || IsIPv4MappedToIPv6);
 092                if (IsIPv4)
 093                {
 094                    return _addressOrScopeId;
 95                }
 096                uint address = (uint)_numbers[6] << 16 | (uint)_numbers[7];
 097                return (uint)HostToNetworkOrder(unchecked((int)address));
 098            }
 99        }
 100
 101        private uint PrivateScopeId
 102        {
 103            get
 2152104            {
 2152105                Debug.Assert(IsIPv6);
 2152106                return _addressOrScopeId;
 2152107            }
 108            set
 1076109            {
 1076110                Debug.Assert(IsIPv6);
 1076111                _toString = null;
 1076112                _hashCode = 0;
 1076113                _addressOrScopeId = value;
 1076114            }
 115        }
 116
 117        /// <devdoc>
 118        ///   <para>
 119        ///     Initializes a new instance of the <see cref='System.Net.IPAddress'/>
 120        ///     class with the specified address.
 121        ///   </para>
 122        /// </devdoc>
 246123        public IPAddress(long newAddress)
 246124        {
 246125            ArgumentOutOfRangeException.ThrowIfGreaterThan((ulong)newAddress, 0x00000000FFFFFFFF, nameof(newAddress));
 126
 246127            PrivateAddress = (uint)newAddress;
 246128        }
 129
 130        /// <devdoc>
 131        ///   <para>
 132        ///     Constructor for an IPv6 Address with a specified Scope.
 133        ///   </para>
 134        /// </devdoc>
 135        public IPAddress(byte[] address, long scopeid) :
 0136            this(new ReadOnlySpan<byte>(address ?? ThrowAddressNullException()), scopeid)
 0137        {
 0138        }
 139
 0140        public IPAddress(ReadOnlySpan<byte> address, long scopeid)
 0141        {
 0142            if (address.Length != IPAddressParserStatics.IPv6AddressBytes)
 0143            {
 0144                throw new ArgumentException(SR.dns_bad_ip_address, nameof(address));
 145            }
 146
 147            // Consider: Since scope is only valid for link-local and site-local
 148            //           addresses we could implement some more robust checking here
 0149            ArgumentOutOfRangeException.ThrowIfGreaterThan((ulong)scopeid, 0x00000000FFFFFFFF, nameof(scopeid));
 150
 0151            _numbers = ReadUInt16NumbersFromBytes(address);
 0152            PrivateScopeId = (uint)scopeid;
 0153        }
 154
 1076155        internal IPAddress(ReadOnlySpan<ushort> numbers, uint scopeid)
 1076156        {
 1076157            Debug.Assert(numbers.Length == NumberOfLabels);
 158
 1076159            _numbers = numbers.ToArray();
 1076160            PrivateScopeId = scopeid;
 1076161        }
 162
 0163        private IPAddress(ushort[] numbers, uint scopeid)
 0164        {
 0165            Debug.Assert(numbers != null);
 0166            Debug.Assert(numbers.Length == NumberOfLabels);
 167
 0168            _numbers = numbers;
 0169            PrivateScopeId = scopeid;
 0170        }
 171
 172        /// <devdoc>
 173        ///   <para>
 174        ///     Constructor for IPv4 and IPv6 Address.
 175        ///   </para>
 176        /// </devdoc>
 177        public IPAddress(byte[] address) :
 0178            this(new ReadOnlySpan<byte>(address ?? ThrowAddressNullException()))
 0179        {
 0180        }
 181
 0182        public IPAddress(ReadOnlySpan<byte> address)
 0183        {
 0184            if (address.Length == IPAddressParserStatics.IPv4AddressBytes)
 0185            {
 0186                PrivateAddress = BitConverter.ToUInt32(address);
 0187            }
 0188            else if (address.Length == IPAddressParserStatics.IPv6AddressBytes)
 0189            {
 0190                _numbers = ReadUInt16NumbersFromBytes(address);
 0191            }
 192            else
 0193            {
 0194                throw new ArgumentException(SR.dns_bad_ip_address, nameof(address));
 195            }
 0196        }
 197
 198        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 199        private static ushort[] ReadUInt16NumbersFromBytes(ReadOnlySpan<byte> address)
 0200        {
 0201            ushort[] numbers = new ushort[NumberOfLabels];
 0202            if (Vector128.IsHardwareAccelerated && BitConverter.IsLittleEndian)
 0203            {
 0204                Vector128<ushort> ushorts = Vector128.Create(address).AsUInt16();
 205                // Reverse endianness of each ushort
 0206                ushorts = (ushorts << 8) | (ushorts >> 8);
 0207                ushorts.CopyTo(numbers);
 0208            }
 209            else
 0210            {
 0211                for (int i = 0; i < numbers.Length; i++)
 0212                {
 0213                    numbers[i] = BinaryPrimitives.ReadUInt16BigEndian(address.Slice(i * 2));
 0214                }
 0215            }
 216
 0217            return numbers;
 0218        }
 219
 220        // We need this internally since we need to interface with winsock,
 221        // and winsock only understands Int32.
 222        internal IPAddress(int newAddress)
 223        {
 224            PrivateAddress = (uint)newAddress;
 225        }
 226
 227        /// <summary>Determines whether the provided span contains a valid <see cref="IPAddress"/>.</summary>
 228        /// <param name="ipSpan">The text to parse.</param>
 2757229        public static bool IsValid(ReadOnlySpan<char> ipSpan) => IPAddressParser.IsValid(ipSpan);
 230
 231        /// <summary>Determines whether the provided span contains a valid <see cref="IPAddress"/>.</summary>
 232        /// <param name="utf8Text">The text to parse.</param>
 233        /// <returns><see langword="true"/> if <paramref name="utf8Text"/> contains a valid IP address; otherwise, <see 
 1435234        public static bool IsValidUtf8(ReadOnlySpan<byte> utf8Text) => IPAddressParser.IsValid(utf8Text);
 235
 236        /// <devdoc>
 237        ///   <para>
 238        ///     Converts an IP address string to an <see cref='System.Net.IPAddress'/> instance.
 239        ///   </para>
 240        /// </devdoc>
 241        public static bool TryParse([NotNullWhen(true)] string? ipString, [NotNullWhen(true)] out IPAddress? address)
 661242        {
 661243            if (ipString == null)
 0244            {
 0245                address = null;
 0246                return false;
 247            }
 248
 661249            address = IPAddressParser.Parse(ipString.AsSpan(), tryParse: true);
 661250            return (address != null);
 661251        }
 252
 253        /// <summary>
 254        /// Tries to parse a span of UTF-8 characters into a value.
 255        /// </summary>
 256        /// <param name="utf8Text">The span of UTF-8 characters to parse.</param>
 257        /// <param name="result">On return, contains the result of successfully parsing <paramref name="utf8Text"/> or a
 258        /// <returns><c>true</c> if <paramref name="utf8Text"/> was successfully parsed; otherwise, <c>false</c>.</retur
 259        public static bool TryParse(ReadOnlySpan<byte> utf8Text, [NotNullWhen(true)] out IPAddress? result)
 1445260        {
 1445261            result = IPAddressParser.Parse(utf8Text, tryParse: true);
 1445262            return (result != null);
 1445263        }
 264
 265        public static bool TryParse(ReadOnlySpan<char> ipSpan, [NotNullWhen(true)] out IPAddress? address)
 1425266        {
 1425267            address = IPAddressParser.Parse(ipSpan, tryParse: true);
 1425268            return (address != null);
 1425269        }
 270
 271        /// <inheritdoc/>
 272        static bool IUtf8SpanParsable<IPAddress>.TryParse(ReadOnlySpan<byte> utf8Text, IFormatProvider? provider, [NotNu
 0273            TryParse(utf8Text, out result);
 274
 275        /// <inheritdoc/>
 276        static bool IParsable<IPAddress>.TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [NotNullWhen
 277            // provider is explicitly ignored
 0278            TryParse(s, out result);
 279
 280        /// <inheritdoc/>
 281        static bool ISpanParsable<IPAddress>.TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, [NotNullWhen(true
 282            // provider is explicitly ignored
 0283            TryParse(s, out result);
 284
 285        public static IPAddress Parse(string ipString)
 0286        {
 0287            ArgumentNullException.ThrowIfNull(ipString);
 288
 0289            return IPAddressParser.Parse(ipString.AsSpan(), tryParse: false)!;
 0290        }
 291
 292        /// <summary>
 293        /// Parses a span of UTF-8 characters into a value.
 294        /// </summary>
 295        /// <param name="utf8Text">The span of UTF-8 characters to parse.</param>
 296        /// <returns>The result of parsing <paramref name="utf8Text"/>.</returns>
 297        public static IPAddress Parse(ReadOnlySpan<byte> utf8Text)
 0298        {
 0299            return IPAddressParser.Parse(utf8Text, tryParse: false)!;
 0300        }
 301
 302        public static IPAddress Parse(ReadOnlySpan<char> ipSpan)
 0303        {
 0304            return IPAddressParser.Parse(ipSpan, tryParse: false)!;
 0305        }
 306
 307        /// <inheritdoc/>
 308        static IPAddress IUtf8SpanParsable<IPAddress>.Parse(ReadOnlySpan<byte> utf8Text, IFormatProvider? provider) =>
 309            // provider is explicitly ignored
 0310            Parse(utf8Text);
 311
 312        /// <inheritdoc/>
 313        static IPAddress ISpanParsable<IPAddress>.Parse(ReadOnlySpan<char> s, IFormatProvider? provider) =>
 314            // provider is explicitly ignored
 0315            Parse(s);
 316
 317        /// <inheritdoc/>
 318        static IPAddress IParsable<IPAddress>.Parse(string s, IFormatProvider? provider) =>
 319            // provider is explicitly ignored
 0320            Parse(s);
 321
 322        public bool TryWriteBytes(Span<byte> destination, out int bytesWritten)
 0323        {
 0324            if (IsIPv6)
 0325            {
 0326                if (destination.Length < IPAddressParserStatics.IPv6AddressBytes)
 0327                {
 0328                    bytesWritten = 0;
 0329                    return false;
 330                }
 331
 0332                WriteIPv6Bytes(destination);
 0333                bytesWritten = IPAddressParserStatics.IPv6AddressBytes;
 0334            }
 335            else
 0336            {
 0337                if (destination.Length < IPAddressParserStatics.IPv4AddressBytes)
 0338                {
 0339                    bytesWritten = 0;
 0340                    return false;
 341                }
 342
 0343                WriteIPv4Bytes(destination);
 0344                bytesWritten = IPAddressParserStatics.IPv4AddressBytes;
 0345            }
 346
 0347            return true;
 0348        }
 349
 350        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 351        private void WriteIPv6Bytes(Span<byte> destination)
 0352        {
 0353            ushort[]? numbers = _numbers;
 0354            Debug.Assert(numbers is { Length: NumberOfLabels });
 355
 0356            if (BitConverter.IsLittleEndian)
 0357            {
 0358                if (Vector128.IsHardwareAccelerated)
 0359                {
 0360                    Vector128<ushort> ushorts = Vector128.Create(numbers).AsUInt16();
 0361                    ushorts = (ushorts << 8) | (ushorts >> 8);
 0362                    ushorts.AsByte().CopyTo(destination);
 0363                }
 364                else
 0365                {
 0366                    for (int i = 0; i < numbers.Length; i++)
 0367                    {
 0368                        BinaryPrimitives.WriteUInt16BigEndian(destination.Slice(i * 2), numbers[i]);
 0369                    }
 0370                }
 0371            }
 372            else
 0373            {
 0374                MemoryMarshal.AsBytes<ushort>(numbers).CopyTo(destination);
 0375            }
 0376        }
 377
 378        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 379        private void WriteIPv4Bytes(Span<byte> destination)
 0380        {
 0381            uint address = PrivateAddress;
 0382            MemoryMarshal.Write(destination, in address);
 0383        }
 384
 385        /// <devdoc>
 386        ///   <para>
 387        ///     Provides a copy of the IPAddress internals as an array of bytes.
 388        ///   </para>
 389        /// </devdoc>
 390        public byte[] GetAddressBytes()
 0391        {
 0392            if (IsIPv6)
 0393            {
 0394                Debug.Assert(_numbers is { Length: NumberOfLabels });
 0395                byte[] bytes = new byte[IPAddressParserStatics.IPv6AddressBytes];
 0396                WriteIPv6Bytes(bytes);
 0397                return bytes;
 398            }
 399            else
 0400            {
 0401                byte[] bytes = new byte[IPAddressParserStatics.IPv4AddressBytes];
 0402                WriteIPv4Bytes(bytes);
 0403                return bytes;
 404            }
 0405        }
 406
 407        public AddressFamily AddressFamily
 408        {
 409            get
 2644410            {
 2644411                return IsIPv4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6;
 2644412            }
 413        }
 414
 415        /// <devdoc>
 416        ///   <para>
 417        ///     IPv6 Scope identifier. This is really a uint32, but that isn't CLS compliant
 418        ///   </para>
 419        /// </devdoc>
 420        public long ScopeId
 421        {
 422            get
 0423            {
 424                // Not valid for IPv4 addresses
 0425                if (IsIPv4)
 0426                {
 0427                    ThrowSocketOperationNotSupported();
 428                }
 429
 0430                return PrivateScopeId;
 0431            }
 432            set
 0433            {
 434                // Not valid for IPv4 addresses
 0435                if (IsIPv4)
 0436                {
 0437                    ThrowSocketOperationNotSupported();
 438                }
 439
 0440                if (this is ReadOnlyIPAddress)
 0441                {
 0442                    ThrowSocketOperationNotSupportedReadOnly();
 443                }
 444
 445                // Consider: Since scope is only valid for link-local and site-local
 446                //           addresses we could implement some more robust checking here
 0447                ArgumentOutOfRangeException.ThrowIfNegative(value);
 0448                ArgumentOutOfRangeException.ThrowIfGreaterThan(value, 0x00000000FFFFFFFF);
 449
 0450                PrivateScopeId = (uint)value;
 0451            }
 452        }
 453
 454        /// <devdoc>
 455        ///   <para>
 456        ///     Converts the Internet address to either standard dotted quad format
 457        ///     or standard IPv6 representation.
 458        ///   </para>
 459        /// </devdoc>
 460        public override unsafe string ToString()
 661461        {
 661462            string? toString = _toString;
 661463            if (toString is null)
 661464            {
 661465                Span<char> span = stackalloc char[IPAddressParser.MaxIPv6StringLength];
 661466                int length = IsIPv4 ?
 661467                    IPAddressParser.FormatIPv4Address(_addressOrScopeId, span) :
 661468                    IPAddressParser.FormatIPv6Address(_numbers, _addressOrScopeId, span);
 661469                _toString = toString = new string(span.Slice(0, length));
 661470            }
 471
 661472            return toString;
 661473        }
 474
 475        /// <inheritdoc/>
 476        string IFormattable.ToString(string? format, IFormatProvider? formatProvider) =>
 477            // format and provider are explicitly ignored
 0478            ToString();
 479
 480        public bool TryFormat(Span<char> destination, out int charsWritten) =>
 0481            TryFormatCore(destination, out charsWritten);
 482
 483        /// <summary>Tries to format the current IP address into the provided span.</summary>
 484        /// <param name="utf8Destination">When this method returns, the IP address as a span of UTF-8 bytes.</param>
 485        /// <param name="bytesWritten">When this method returns, the number of bytes written into the <paramref name="ut
 486        /// <returns><see langword="true" /> if the formatting was successful; otherwise, <see langword="false" />.</ret
 487        public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten) =>
 0488            TryFormatCore(utf8Destination, out bytesWritten);
 489
 490        /// <inheritdoc/>
 491        bool ISpanFormattable.TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormat
 492            // format and provider are explicitly ignored
 0493            TryFormatCore(destination, out charsWritten);
 494
 495        /// <inheritdoc/>
 496        bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format,
 497            // format and provider are explicitly ignored
 0498            TryFormatCore(utf8Destination, out bytesWritten);
 499
 500        private unsafe bool TryFormatCore<TChar>(Span<TChar> destination, out int charsWritten) where TChar : unmanaged,
 0501        {
 0502            if (IsIPv4)
 0503            {
 0504                if (destination.Length >= IPAddressParser.MaxIPv4StringLength)
 0505                {
 0506                    charsWritten = IPAddressParser.FormatIPv4Address(_addressOrScopeId, destination);
 0507                    return true;
 508                }
 0509            }
 510            else
 0511            {
 0512                if (destination.Length >= IPAddressParser.MaxIPv6StringLength)
 0513                {
 0514                    charsWritten = IPAddressParser.FormatIPv6Address(_numbers, _addressOrScopeId, destination);
 0515                    return true;
 516                }
 0517            }
 518
 0519            Span<TChar> tmpDestination = stackalloc TChar[IPAddressParser.MaxIPv6StringLength];
 0520            Debug.Assert(tmpDestination.Length >= IPAddressParser.MaxIPv4StringLength);
 521
 0522            int written = IsIPv4 ?
 0523                IPAddressParser.FormatIPv4Address(PrivateAddress, tmpDestination) :
 0524                IPAddressParser.FormatIPv6Address(_numbers, PrivateScopeId, tmpDestination);
 525
 0526            if (tmpDestination.Slice(0, written).TryCopyTo(destination))
 0527            {
 0528                charsWritten = written;
 0529                return true;
 530            }
 531
 0532            charsWritten = 0;
 0533            return false;
 0534        }
 535
 536        public static long HostToNetworkOrder(long host)
 0537        {
 0538            return BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(host) : host;
 0539        }
 540
 541        public static int HostToNetworkOrder(int host)
 539542        {
 539543            return BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(host) : host;
 539544        }
 545
 546        public static short HostToNetworkOrder(short host)
 0547        {
 0548            return BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(host) : host;
 0549        }
 550
 551        public static long NetworkToHostOrder(long network)
 0552        {
 0553            return HostToNetworkOrder(network);
 0554        }
 555
 556        public static int NetworkToHostOrder(int network)
 208557        {
 208558            return HostToNetworkOrder(network);
 208559        }
 560
 561        public static short NetworkToHostOrder(short network)
 0562        {
 0563            return HostToNetworkOrder(network);
 0564        }
 565
 566        public static bool IsLoopback(IPAddress address)
 0567        {
 0568            ArgumentNullException.ThrowIfNull(address);
 569
 0570            if (address.IsIPv6)
 0571            {
 572                // Do Equals test for IPv6 addresses
 0573                return address.Equals(IPv6Loopback) || address.Equals(s_loopbackMappedToIPv6);
 574            }
 575            else
 0576            {
 0577                long LoopbackMask = (uint)HostToNetworkOrder(unchecked((int)LoopbackMaskHostOrder));
 0578                return ((address.PrivateAddress & LoopbackMask) == (Loopback.PrivateAddress & LoopbackMask));
 579            }
 0580        }
 581
 582        /// <devdoc>
 583        ///   <para>
 584        ///     Determines if an address is an IPv6 Multicast address
 585        ///   </para>
 586        /// </devdoc>
 587        public bool IsIPv6Multicast
 588        {
 589            get
 0590            {
 0591                return IsIPv6 && ((_numbers[0] & 0xFF00) == 0xFF00);
 0592            }
 593        }
 594
 595        /// <devdoc>
 596        ///   <para>
 597        ///     Determines if an address is an IPv6 Link Local address
 598        ///   </para>
 599        /// </devdoc>
 600        public bool IsIPv6LinkLocal
 601        {
 602            get
 0603            {
 0604                return IsIPv6 && ((_numbers[0] & 0xFFC0) == 0xFE80);
 0605            }
 606        }
 607
 608        /// <devdoc>
 609        ///   <para>
 610        ///     Determines if an address is an IPv6 Site Local address
 611        ///   </para>
 612        /// </devdoc>
 613        public bool IsIPv6SiteLocal
 614        {
 615            get
 0616            {
 0617                return IsIPv6 && ((_numbers[0] & 0xFFC0) == 0xFEC0);
 0618            }
 619        }
 620
 621        public bool IsIPv6Teredo
 622        {
 623            get
 0624            {
 0625                return IsIPv6 &&
 0626                       (_numbers[0] == 0x2001) &&
 0627                       (_numbers[1] == 0);
 0628            }
 629        }
 630
 631        /// <summary>Gets whether the address is an IPv6 Unique Local address.</summary>
 632        public bool IsIPv6UniqueLocal
 633        {
 634            get
 0635            {
 0636                return IsIPv6 && ((_numbers[0] & 0xFE00) == 0xFC00);
 0637            }
 638        }
 639
 640        // 0:0:0:0:0:FFFF:x.x.x.x
 641        public bool IsIPv4MappedToIPv6
 642        {
 643            get
 0644            {
 0645                return !IsIPv4 && _numbers.AsSpan(0, 6).SequenceEqual((ReadOnlySpan<ushort>)[0, 0, 0, 0, 0, 0xFFFF]);
 0646            }
 647        }
 648
 649        [Obsolete("IPAddress.Address is address family dependent and has been deprecated. Use IPAddress.Equals to perfor
 650        public long Address
 651        {
 652            get
 0653            {
 0654                if (AddressFamily == AddressFamily.InterNetworkV6)
 0655                {
 0656                    ThrowSocketOperationNotSupported();
 657                }
 658
 0659                return PrivateAddress;
 0660            }
 661            set
 0662            {
 0663                if (AddressFamily == AddressFamily.InterNetworkV6)
 0664                {
 0665                    ThrowSocketOperationNotSupported();
 666                }
 667
 0668                if (PrivateAddress != value)
 0669                {
 0670                    if (this is ReadOnlyIPAddress)
 0671                    {
 0672                        ThrowSocketOperationNotSupportedReadOnly();
 673                    }
 674
 0675                    PrivateAddress = unchecked((uint)value);
 0676                }
 0677            }
 678        }
 679
 680        /// <summary>Compares two IP addresses.</summary>
 681        public override bool Equals([NotNullWhen(true)] object? comparand)
 1322682        {
 1322683            return comparand is IPAddress address && Equals(address);
 1322684        }
 685
 686        internal bool Equals(IPAddress comparand)
 1322687        {
 1322688            Debug.Assert(comparand != null);
 689
 690            // Compare families before address representations
 1322691            if (AddressFamily != comparand.AddressFamily)
 0692            {
 0693                return false;
 694            }
 695
 1322696            if (IsIPv6)
 1076697            {
 698                // For IPv6 addresses, we must compare the full 128-bit representation and the scope IDs.
 699                // We give JIT a hint that the arrays are always of length IPv6AddressShorts, so it
 700                // can unroll the comparison. JIT probably could do it on its own, but that requires
 701                // complex inter-procedural optimizations.
 1076702                Debug.Assert(_numbers.Length == IPAddressParserStatics.IPv6AddressShorts);
 1076703                Debug.Assert(comparand._numbers!.Length == IPAddressParserStatics.IPv6AddressShorts);
 704
 1076705                ReadOnlySpan<ushort> left = _numbers.AsSpan(0, IPAddressParserStatics.IPv6AddressShorts);
 1076706                ReadOnlySpan<ushort> right = comparand._numbers.AsSpan(0, IPAddressParserStatics.IPv6AddressShorts);
 1076707                return left.SequenceEqual(right) && PrivateScopeId == comparand.PrivateScopeId;
 708            }
 709
 710            // For IPv4 addresses, compare the integer representation.
 246711            return comparand.PrivateAddress == PrivateAddress;
 1322712        }
 713
 714        public override int GetHashCode()
 0715        {
 0716            if (_hashCode == 0)
 0717            {
 718                // For IPv4 addresses, we calculate the hashcode based on address bytes.
 719                // For IPv6 addresses, we also factor in scope ID.
 0720                if (IsIPv6)
 0721                {
 0722                    ReadOnlySpan<byte> numbers = MemoryMarshal.AsBytes<ushort>(_numbers).Slice(0, 16);
 0723                    _hashCode = HashCode.Combine(
 0724                        BitConverter.ToUInt32(numbers),
 0725                        BitConverter.ToUInt32(numbers.Slice(4)),
 0726                        BitConverter.ToUInt32(numbers.Slice(8)),
 0727                        BitConverter.ToUInt32(numbers.Slice(12)),
 0728                        _addressOrScopeId);
 0729                }
 730                else
 0731                {
 0732                    _hashCode = HashCode.Combine(_addressOrScopeId);
 0733                }
 0734            }
 735
 0736            return _hashCode;
 0737        }
 738
 739        // IPv4 192.168.1.1 maps as ::FFFF:192.168.1.1
 740        public IPAddress MapToIPv6()
 0741        {
 0742            if (IsIPv6)
 0743            {
 0744                return this;
 745            }
 746
 0747            uint address = (uint)NetworkToHostOrder(unchecked((int)PrivateAddress));
 0748            ushort[] labels = new ushort[NumberOfLabels];
 0749            labels[5] = 0xFFFF;
 0750            labels[6] = (ushort)(address >> 16);
 0751            labels[7] = (ushort)address;
 0752            return new IPAddress(labels, 0);
 0753        }
 754
 755        // Takes the last 4 bytes of an IPv6 address and converts it to an IPv4 address.
 756        // This does not restrict to address with the ::FFFF: prefix because other types of
 757        // addresses display the tail segments as IPv4 like Terado.
 758        public IPAddress MapToIPv4()
 0759        {
 0760            if (IsIPv4)
 0761            {
 0762                return this;
 763            }
 764
 0765            uint address = (uint)_numbers[6] << 16 | (uint)_numbers[7];
 0766            return new IPAddress((uint)HostToNetworkOrder(unchecked((int)address)));
 0767        }
 768
 769        [DoesNotReturn]
 0770        private static byte[] ThrowAddressNullException() => throw new ArgumentNullException("address");
 771
 772        [DoesNotReturn]
 0773        private void ThrowSocketOperationNotSupported() => throw new SocketException(SocketError.OperationNotSupported, 
 774
 775        [DoesNotReturn]
 0776        private static void ThrowSocketOperationNotSupportedReadOnly() => throw new SocketException(SocketError.Operatio
 777
 778        private sealed class ReadOnlyIPAddress : IPAddress
 779        {
 0780            public ReadOnlyIPAddress(ReadOnlySpan<byte> newAddress) : base(newAddress)
 0781            { }
 782
 0783            public ReadOnlyIPAddress(ReadOnlySpan<byte> address, long scopeid) : base(address, scopeid)
 0784            { }
 785        }
 786    }
 787}
 788

Methods/Properties

.cctor()
IsIPv4()
IsIPv6()
PrivateAddress()
PrivateAddress(System.UInt32)
PrivateIPv4Address()
PrivateScopeId()
PrivateScopeId(System.UInt32)
.ctor(System.Int64)
.ctor(System.Byte[],System.Int64)
.ctor(System.ReadOnlySpan`1<System.Byte>,System.Int64)
.ctor(System.ReadOnlySpan`1<System.UInt16>,System.UInt32)
.ctor(System.UInt16[],System.UInt32)
.ctor(System.Byte[])
.ctor(System.ReadOnlySpan`1<System.Byte>)
ReadUInt16NumbersFromBytes(System.ReadOnlySpan`1<System.Byte>)
IsValid(System.ReadOnlySpan`1<System.Char>)
IsValidUtf8(System.ReadOnlySpan`1<System.Byte>)
TryParse(System.String,System.Net.IPAddress&)
TryParse(System.ReadOnlySpan`1<System.Byte>,System.Net.IPAddress&)
TryParse(System.ReadOnlySpan`1<System.Char>,System.Net.IPAddress&)
System.IUtf8SpanParsable<System.Net.IPAddress>.TryParse(System.ReadOnlySpan`1<System.Byte>,System.IFormatProvider,System.Net.IPAddress&)
System.IParsable<System.Net.IPAddress>.TryParse(System.String,System.IFormatProvider,System.Net.IPAddress&)
System.ISpanParsable<System.Net.IPAddress>.TryParse(System.ReadOnlySpan`1<System.Char>,System.IFormatProvider,System.Net.IPAddress&)
Parse(System.String)
Parse(System.ReadOnlySpan`1<System.Byte>)
Parse(System.ReadOnlySpan`1<System.Char>)
System.IUtf8SpanParsable<System.Net.IPAddress>.Parse(System.ReadOnlySpan`1<System.Byte>,System.IFormatProvider)
System.ISpanParsable<System.Net.IPAddress>.Parse(System.ReadOnlySpan`1<System.Char>,System.IFormatProvider)
System.IParsable<System.Net.IPAddress>.Parse(System.String,System.IFormatProvider)
TryWriteBytes(System.Span`1<System.Byte>,System.Int32&)
WriteIPv6Bytes(System.Span`1<System.Byte>)
WriteIPv4Bytes(System.Span`1<System.Byte>)
GetAddressBytes()
AddressFamily()
ScopeId()
ScopeId(System.Int64)
ToString()
System.IFormattable.ToString(System.String,System.IFormatProvider)
TryFormat(System.Span`1<System.Char>,System.Int32&)
TryFormat(System.Span`1<System.Byte>,System.Int32&)
System.ISpanFormattable.TryFormat(System.Span`1<System.Char>,System.Int32&,System.ReadOnlySpan`1<System.Char>,System.IFormatProvider)
System.IUtf8SpanFormattable.TryFormat(System.Span`1<System.Byte>,System.Int32&,System.ReadOnlySpan`1<System.Char>,System.IFormatProvider)
TryFormatCore(System.Span`1<TChar>,System.Int32&)
HostToNetworkOrder(System.Int64)
HostToNetworkOrder(System.Int32)
HostToNetworkOrder(System.Int16)
NetworkToHostOrder(System.Int64)
NetworkToHostOrder(System.Int32)
NetworkToHostOrder(System.Int16)
IsLoopback(System.Net.IPAddress)
IsIPv6Multicast()
IsIPv6LinkLocal()
IsIPv6SiteLocal()
IsIPv6Teredo()
IsIPv6UniqueLocal()
IsIPv4MappedToIPv6()
Address()
Address(System.Int64)
Equals(System.Object)
Equals(System.Net.IPAddress)
GetHashCode()
MapToIPv6()
MapToIPv4()
ThrowAddressNullException()
ThrowSocketOperationNotSupported()
ThrowSocketOperationNotSupportedReadOnly()
.ctor(System.ReadOnlySpan`1<System.Byte>)
.ctor(System.ReadOnlySpan`1<System.Byte>,System.Int64)