129 lines
3.1 KiB
C#
129 lines
3.1 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
|
|
namespace System.Net
|
|
{
|
|
public class IPNetworkCollection : IEnumerable<IPNetwork>, IEnumerator<IPNetwork>
|
|
{
|
|
|
|
private BigInteger _enumerator;
|
|
private byte _cidrSubnet;
|
|
private IPNetwork _ipnetwork;
|
|
|
|
private byte _cidr => this._ipnetwork.Cidr;
|
|
|
|
private BigInteger _broadcast => IPNetwork.ToBigInteger(this._ipnetwork.Broadcast);
|
|
|
|
private BigInteger _lastUsable => IPNetwork.ToBigInteger(this._ipnetwork.LastUsable);
|
|
private BigInteger _network => IPNetwork.ToBigInteger(this._ipnetwork.Network);
|
|
#if TRAVISCI
|
|
public
|
|
#else
|
|
internal
|
|
#endif
|
|
IPNetworkCollection(IPNetwork ipnetwork, byte cidrSubnet)
|
|
{
|
|
|
|
int maxCidr = ipnetwork.AddressFamily == Sockets.AddressFamily.InterNetwork ? 32 : 128;
|
|
if (cidrSubnet > maxCidr)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(cidrSubnet));
|
|
}
|
|
|
|
if (cidrSubnet < ipnetwork.Cidr)
|
|
{
|
|
throw new ArgumentException("cidr");
|
|
}
|
|
|
|
this._cidrSubnet = cidrSubnet;
|
|
this._ipnetwork = ipnetwork;
|
|
this._enumerator = -1;
|
|
}
|
|
|
|
#region Count, Array, Enumerator
|
|
|
|
public BigInteger Count
|
|
{
|
|
get
|
|
{
|
|
var count = BigInteger.Pow(2, this._cidrSubnet - this._cidr);
|
|
return count;
|
|
}
|
|
}
|
|
|
|
public IPNetwork this[BigInteger i]
|
|
{
|
|
get
|
|
{
|
|
if (i >= this.Count)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(i));
|
|
}
|
|
|
|
var last = this._ipnetwork.AddressFamily == Sockets.AddressFamily.InterNetworkV6
|
|
? this._lastUsable : this._broadcast;
|
|
var increment = (last - this._network) / this.Count;
|
|
var uintNetwork = this._network + ((increment + 1) * i);
|
|
var ipn = new IPNetwork(uintNetwork, this._ipnetwork.AddressFamily, this._cidrSubnet);
|
|
return ipn;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IEnumerable Members
|
|
|
|
IEnumerator<IPNetwork> IEnumerable<IPNetwork>.GetEnumerator()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
#region IEnumerator<IPNetwork> Members
|
|
|
|
public IPNetwork Current => this[this._enumerator];
|
|
|
|
#endregion
|
|
|
|
#region IDisposable Members
|
|
|
|
public void Dispose()
|
|
{
|
|
// nothing to dispose
|
|
return;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IEnumerator Members
|
|
|
|
object IEnumerator.Current => this.Current;
|
|
|
|
public bool MoveNext()
|
|
{
|
|
this._enumerator++;
|
|
if (this._enumerator >= this.Count)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
this._enumerator = -1;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|