using System.Collections; using System.Collections.Generic; using System.Numerics; namespace System.Net { public class IPNetworkCollection : IEnumerable, IEnumerator { 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 { BigInteger 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)); } BigInteger last = this._ipnetwork.AddressFamily == Sockets.AddressFamily.InterNetworkV6 ? this._lastUsable : this._broadcast; BigInteger increment = (last - this._network) / this.Count; BigInteger uintNetwork = this._network + ((increment + 1) * i); IPNetwork ipn = new IPNetwork(uintNetwork, this._ipnetwork.AddressFamily, this._cidrSubnet); return ipn; } } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return this; } IEnumerator IEnumerable.GetEnumerator() { return this; } #region IEnumerator 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 } }