/// <summary> /// Determines whether the given <paramref name="address"/> /// sa contained in this range. /// </summary> /// <param name="address">The IP address to check.</param> /// <returns><see langword="true"/> if <paramref name="address"/> /// is between <see cref="Start"/> and <see cref="End"/>, inclusive; /// otherwise, <see lamgword="false"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="address"/> is <see langword="null"/>.</exception> /// <remarks> /// <para>This method treats IPv4 addresses and their IPv6-mapped counterparts /// the same; that is, given a range obtained by parsing the string <c>192.168.1.0/24</c>, /// <c>Contains(IPAddress.Parse("192.168.1.55"))</c> will return <see langword="true"/>, /// as will <c>Contains(IPAddress.Parse("192.168.1.55").MapToIPv6())</c>. This is true /// as well if a range is initialized with IPv6 addresses.</para> /// </remarks> public bool Contains(IPAddress address) { if (address == null) { throw new ArgumentNullException(nameof(address)); } var addressValue = new IPAddressValue(address); return(addressValue.CompareTo(_start) >= 0 && addressValue.CompareTo(_end) <= 0); }
/// <summary> /// Initializes a new instance of the <see cref="IPAddressRange"/> class, /// representing a range of IP addresses between <paramref name="start"/> /// and <paramref name="end"/>, extremes included. /// </summary> /// <param name="start">The starting address of the range.</param> /// <param name="end">The ending address of the range.</param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="start"/> is <see langword="null"/>.</para> /// <para>- or -</para> /// <para><paramref name="end"/> is <see langword="null"/>.</para> /// </exception> /// <exception cref="ArgumentException"> /// <para><paramref name="end"/> has a different <see cref="IPAddress.AddressFamily">AddressFamily</see> /// from <paramref name="start"/>.</para> /// <para>- or -</para> /// <para><paramref name="end"/> is a lower address than <paramref name="start"/>, /// i.e. the binary representation of <paramref name="end"/> in network byte order /// is a lower number than the same representation of <paramref name="start"/>.</para> /// </exception> public IPAddressRange(IPAddress start, IPAddress end) { if (start == null) { throw new ArgumentNullException(nameof(start)); } if (end == null) { throw new ArgumentNullException(nameof(end)); } var startFamily = start.AddressFamily; _isV6 = startFamily == AddressFamily.InterNetworkV6; if (end.AddressFamily != startFamily) { throw MismatchedEndFamily(nameof(end)); } _start = new IPAddressValue(start); _end = new IPAddressValue(end); if (_end.CompareTo(_start) < 0) { throw EndLowerThanStart(nameof(end)); } _prefixLength = 0; }
private static Exception?TryParseStartEndFormat(string str, int separatorPos, out IPAddressRange result) { result = None; var s = str.Substring(0, separatorPos).Trim(); if (!IPAddressUtility.TryParse(s, out var startAddress)) { return(InvalidStartAddress()); } s = str.Substring(separatorPos + 1).Trim(); if (!IPAddressUtility.TryParse(s, out var endAddress)) { return(InvalidEndAddress()); } var addressFamily = startAddress.AddressFamily; if (endAddress.AddressFamily != addressFamily) { return(MismatchedStartEndFamily()); } var start = new IPAddressValue(startAddress); var end = new IPAddressValue(endAddress); if (end.CompareTo(start) < 0) { return(EndLowerThanStart()); } result = new IPAddressRange(start, end, addressFamily == AddressFamily.InterNetworkV6, 0); return(null); }
/// <inheritdoc/> /// <remarks> /// <para>The result of this method will be a string that, /// if passed to the <see cref="Parse"/> or <see cref="TryParse"/> method, /// will result in an instance identical to this one.</para> /// <para>If this instance has been created by means of the <see cref="Parse"/> /// or <see cref="TryParse"/> method, the returned string will not /// necessarily be identical to the parsed string. The possible differences /// include the following:</para> /// <list type="bullet"> /// <item>ranges consisting of just one IP address will result in a /// string representing that single address;</item> /// <item>addresses in the returned string are passed to the /// <see cref="IPAddress.ToString"/> method, resulting in standardized /// representations that may be different from the originally parsed /// strings;</item> /// <item>the returned string will contain no blank characters;</item> /// <item>address ranges parsed as <c>address/netmask</c> will be /// rendered as CIDR subnets: for example, /// <c>IPAddressRange.Parse("192.168.19.0/255.255.255.0").ToString()</c> /// will return <c>"192.168.19.0/24"</c>.</item> /// </list> /// </remarks> public override string ToString() => _prefixLength > 0 ? $"{Start}/{_prefixLength}" : _start.CompareTo(_end) == 0 ? Start.ToString() : $"{Start}-{End}";