#pragma warning disable CA1062 // Validate arguments of public methods using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Runtime.CompilerServices; using NetCollection = System.Collections.ObjectModel.Collection; namespace MediaBrowser.Common.Net { /// /// Defines the . /// public static class NetworkExtensions { /// /// Add an address to the collection. /// /// The . /// Item to add. public static void AddItem(this NetCollection source, IPAddress ip) { if (!source.ContainsAddress(ip)) { source.Add(new IPNetAddress(ip, 32)); } } /// /// Add multiple items to the collection. /// /// The . /// Item to add. /// Return the collection. public static NetCollection AddRange(this NetCollection destination, IEnumerable source) { foreach (var item in source) { destination.Add(item); } return destination; } /// /// Adds a network to the collection. /// /// The . /// Item to add. public static void AddItem(this NetCollection source, IPObject item) { if (!source.ContainsAddress(item)) { source.Add(item); } } /// /// Converts this object to a string. /// /// The . /// Returns a string representation of this object. public static string Readable(this NetCollection source) { string output = "["; if (source.Count > 0) { foreach (var i in source) { output += $"{i},"; } output = output[0..^1]; } return $"{output}]"; } /// /// Returns true if the collection contains an item with the ip address, /// or the ip address falls within any of the collection's network ranges. /// /// The . /// The item to look for. /// True if the collection contains the item. public static bool ContainsAddress(this NetCollection source, IPAddress item) { if (source.Count == 0) { return false; } if (item == null) { throw new ArgumentNullException(nameof(item)); } if (item.IsIPv4MappedToIPv6) { item = item.MapToIPv4(); } foreach (var i in source) { if (i.Contains(item)) { return true; } } return false; } /// /// Returns true if the collection contains an item with the ip address, /// or the ip address falls within any of the collection's network ranges. /// /// The . /// The item to look for. /// True if the collection contains the item. public static bool ContainsAddress(this NetCollection source, IPObject item) { if (source.Count == 0) { return false; } if (item == null) { throw new ArgumentNullException(nameof(item)); } foreach (var i in source) { if (i.Contains(item)) { return true; } } return false; } /// /// Returns a collection containing the subnets of this collection given. /// /// The . /// NetCollection object containing the subnets. public static NetCollection AsNetworks(this NetCollection source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } NetCollection res = new NetCollection(); foreach (IPObject i in source) { if (i is IPNetAddress nw) { // Add the subnet calculated from the interface address/mask. var na = nw.NetworkAddress; na.Tag = i.Tag; res.Add(na); } else { // Flatten out IPHost and add all its ip addresses. foreach (var addr in ((IPHost)i).GetAddresses()) { IPNetAddress host = new IPNetAddress(addr) { Tag = i.Tag }; res.Add(host); } } } return res; } /// /// Excludes all the items from this list that are found in excludeList. /// /// The . /// Items to exclude. /// A new collection, with the items excluded. public static NetCollection Exclude(this NetCollection source, NetCollection excludeList) { if (source.Count == 0 || excludeList == null) { return new NetCollection(source); } NetCollection results = new NetCollection(); bool found; foreach (var outer in source) { found = false; foreach (var inner in excludeList) { if (outer.Equals(inner)) { found = true; break; } } if (!found) { results.Add(outer); } } return results; } /// /// Returns all items that co-exist in this object and target. /// /// The . /// Collection to compare with. /// A collection containing all the matches. public static NetCollection Union(this NetCollection source, NetCollection target) { if (source.Count == 0) { return new NetCollection(); } if (target == null) { throw new ArgumentNullException(nameof(target)); } NetCollection nc = new NetCollection(); foreach (IPObject i in source) { if (target.ContainsAddress(i)) { nc.Add(i); } } return nc; } } }