/* * The dhcpd-pools has BSD 2-clause license which also known as "Simplified * BSD License" or "FreeBSD License". * * Copyright 2006- Sami Kerola. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing * official policies, either expressed or implied, of Sami Kerola. */ /*! \file analyze.c * \brief Data analysis functions. */ #include #include #include #include #include "dhcpd-pools.h" /*! \brief Prepare data for analysis. The function will sort leases and * ranges. */ void prepare_data(void) { /* Sort leases */ HASH_SORT(leases, leasecomp); /* Sort ranges */ qsort(ranges, (size_t)num_ranges, sizeof(struct range_t), &rangecomp); } /*! \brief Perform counting. Join leases with ranges, and update counters. */ void do_counting(void) { struct range_t *restrict range_p; const struct leases_t *restrict l = leases; unsigned long i, k, block_size; /* Walk through ranges */ range_p = ranges; for (i = 0; i < num_ranges; i++) { while (l != NULL && ipcomp(&range_p->first_ip, &l->ip) < 0) l = l->hh.prev; /* rewind */ if (l == NULL) l = leases; for (; l != NULL && ipcomp(&l->ip, &range_p->last_ip) <= 0; l = l->hh.next) { if (ipcomp(&l->ip, &range_p->first_ip) < 0) continue; /* cannot happen? */ /* IP in range */ switch (l->type) { case FREE: range_p->touched++; break; case ACTIVE: range_p->count++; break; case BACKUP: range_p->backups++; break; } if (range_p->shared_net) { switch (l->type) { case FREE: range_p->shared_net->touched++; break; case ACTIVE: range_p->shared_net->used++; break; case BACKUP: range_p->shared_net->backups++; break; } } } /* Size of range, shared net & all networks */ block_size = get_range_size(range_p); if (range_p->shared_net) range_p->shared_net->available += block_size; range_p++; } /* FIXME: During count of other shared networks default network * and all networks got mixed together semantically. The below * fixes the problem, but is not elegant. */ shared_networks->available = 0; shared_networks->used = 0; shared_networks->touched = 0; range_p = ranges; for (k = 0; k < num_ranges; k++) { shared_networks->available += get_range_size(range_p); shared_networks->used += range_p->count; shared_networks->touched += range_p->touched; shared_networks->backups += range_p->backups; range_p++; } }