getdata: increase max number of shared networks
[debian/dhcpd-pools.git] / src / analyze.c
1 /* http://dhcpd-pools.sourceforge.net/
2 ** Copyright 2006- Sami Kerola <kerolasa@iki.fi>
3 **
4 ** This program is free software: you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation, either version 3 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 ** GNU General Public License for more details.
13 **
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <stdlib.h>
23 #include <stdio.h>
24
25 #include "dhcpd-pools.h"
26
27 /* Clean up data */
28 int prepare_data(void)
29 {
30         unsigned long int i, j, k;
31
32         /* Sort leases */
33         qsort(leases, (size_t) num_leases, sizeof(long int), &intcomp);
34
35         /* Get rid of lease dublicates */
36         for (k = j = i = 0; i < num_leases; i++) {
37                 if (j != leases[i]) {
38                         leases[k] = leases[i];
39                         j = leases[i];
40                         k++;
41                 }
42         }
43         num_leases = k;
44
45         /* Delete touched IPs that are in use. */
46         j = 0;
47         for (i = 0; i < num_touches; i++) {
48                 if (bsearch
49                     (&touches[i], leases, (size_t) num_leases,
50                      sizeof(long int), &intcomp) == NULL) {
51                         touches[j] = touches[i];
52                         j++;
53                 }
54         }
55         num_touches = j;
56         qsort(touches, (size_t) num_touches, sizeof(long int), &intcomp);
57
58         /* Sort ranges */
59         qsort(ranges, (size_t) num_ranges, sizeof(struct range_t),
60               &rangecomp);
61
62         /* Sort backups */
63         if (0 < num_backups) {
64                 qsort(backups, (size_t) num_backups, sizeof(long int),
65                       &intcomp);
66         }
67
68         return 0;
69 }
70
71 /* Join leases and ranges into couter structs */
72 int do_counting(void)
73 {
74         struct range_t *range_p;
75         unsigned int i, j, k, m, block_size;
76
77         i = j = m = 0;
78         range_p = ranges;
79
80         /* Walk through ranges */
81         for (k = 0; k < num_ranges; k++) {
82                 /* Count IPs in use */
83                 for (; leases[i] < range_p->last_ip
84                      && (unsigned long) i < num_leases; i++) {
85                         if (leases[i] < range_p->first_ip) {
86                                 continue;
87                         }
88                         /* IP with in range */
89                         range_p->count++;
90                         if (range_p->shared_net) {
91                                 range_p->shared_net->used++;
92                         }
93                 }
94
95                 /* Count touched IPs */
96                 for (; touches[j] < range_p->last_ip
97                      && (unsigned long) j < num_touches; j++) {
98                         if (touches[j] < range_p->first_ip) {
99                                 continue;
100                         }
101                         /* IP with in range */
102                         range_p->touched++;
103                         if (range_p->shared_net) {
104                                 range_p->shared_net->touched++;
105                         }
106                 }
107
108                 /* Count backup IPs */
109                 if (0 < num_backups) {
110                         for (; backups[m] < range_p->last_ip
111                              && (unsigned long) m < num_touches; m++) {
112                                 if (touches[m] < range_p->first_ip) {
113                                         continue;
114                                 }
115                                 /* IP with in range */
116                                 range_p->backups++;
117                                 if (range_p->shared_net) {
118                                         range_p->shared_net->backups++;
119                                 }
120                         }
121                 }
122
123                 /* Size of range, shared net & all networks */
124                 block_size =
125                     (unsigned int) (range_p->last_ip - range_p->first_ip -
126                                     1);
127                 if (range_p->shared_net) {
128                         range_p->shared_net->available += block_size;
129                 }
130
131                 /* Go backwards one step so that not even a one IP will be
132                  * missed. This is possibly always unnecessary. */
133                 if (i) {
134                         i--;
135                 }
136                 if (j) {
137                         j--;
138                 }
139
140                 range_p++;
141         }
142
143         /* FIXME: During count of other shared networks default network and
144          * all networks got mixed to gether semantically. This fixes the
145          * problem, but is not elegant. */
146         shared_networks->available = 0;
147         shared_networks->used = 0;
148         shared_networks->touched = 0;
149         range_p = ranges;
150         for (k = 0; k < num_ranges; k++) {
151                 shared_networks->available +=
152                     range_p->last_ip - range_p->first_ip - 1;
153                 shared_networks->used += range_p->count;
154                 shared_networks->touched += range_p->touched;
155                 shared_networks->backups += range_p->backups;
156                 range_p++;
157         }
158
159         return 0;
160 }