Exemplo n.º 1
0
        /// <summary>
        ///     Function to be called recursively for FewestConsecutiveSubnetsFor
        ///     Works by verifying that passed subnet isn't bounded by head, tail
        ///     if not breaks subnet in half and recursively tests, building in essence a binary tree of testable subnet paths
        /// </summary>
        /// <param name="headIP">the head IP</param>
        /// <param name="tailIP">the tail IP</param>
        /// <param name="subnet">The subnet found on success</param>
        /// <returns>true on success</returns>
        private static IEnumerable <Subnet> FilledSubnets([NotNull] IPAddress headIP,
                                                          [NotNull] IPAddress tailIP,
                                                          [NotNull] Subnet subnet)
        {
            var networkPrefixAddress = subnet.NetworkPrefixAddress;
            var broadcastAddress     = subnet.BroadcastAddress;

            // the given subnet is the perfect size for the head/tail (not papa bear, not mama bear, but just right with baby bear)
            if (networkPrefixAddress.ToUnsignedBigInteger() >= headIP.ToUnsignedBigInteger() &&
                broadcastAddress.ToUnsignedBigInteger() <= tailIP.ToUnsignedBigInteger())
            {
                return(new[] { subnet });
            }

            // increasing the route prefix by 1 creates a subnet of half the initial size (due 2^(max-n) route prefix sizing)
            var nextSmallestRoutePrefix = subnet.RoutingPrefix + 1;

            // over-iterated route prefix, no valid subnet beyond this point; end search on this branch
            if ((subnet.IsIPv6 && nextSmallestRoutePrefix > 128) ||
                (subnet.IsIPv4 && nextSmallestRoutePrefix > 32))
            {
                return(Enumerable.Empty <Subnet>()); // no subnets to be found here, stop investigating branch of tree
            }

            // build head subnet
            var headSubnet = new Subnet(networkPrefixAddress, nextSmallestRoutePrefix);

            // use the next address after the end of the head subnet as the first address for the tail subnet
            var       tailStartingAddressBigInteger = headSubnet.BroadcastAddress.ToUnsignedBigInteger() + 1;
            IPAddress tailStartingAddress;

            if (!IPAddressUtilities.TryParse(tailStartingAddressBigInteger, headIP.AddressFamily, out tailStartingAddress))
            {
                throw new ArgumentException();
            }

            var tailSubnet = new Subnet(tailStartingAddress, nextSmallestRoutePrefix);

            // break into binary search tree, searching both head subnet and tail subnet for ownership of head and tail ip
            return(FilledSubnets(headIP, tailIP, headSubnet)
                   .Concat(FilledSubnets(headIP, tailIP, tailSubnet)));
        }