2 ** Copyright (C) 2006- Sami Kerola <kerolasa@iki.fi>
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 2 of the License, or
7 ** (at your option) any later version.
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.
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
29 #include "dhcpd-pools.h"
34 struct in_addr first, last;
35 struct range_t *range_p;
36 struct shared_network_t *shared_p;
40 if (config.output_file[0]) {
41 outfile = fopen(config.output_file, "w+");
42 if (outfile == NULL) {
43 err(EXIT_FAILURE, "output_txt: %s",
51 shared_p = shared_networks;
53 if (config.output_limit[0] & output_limit_bit_1) {
54 fprintf(outfile, "Ranges:\n");
57 "shared net name first ip last ip max cur percent touch t+c t+c perc");
58 if (0 < num_backups) {
59 fprintf(outfile, " bu bu perc");
61 fprintf(outfile, "\n");
63 if (config.output_limit[1] & output_limit_bit_1) {
64 for (i = 0; i < num_ranges; i++) {
65 first.s_addr = ntohl(range_p->first_ip + 1);
66 last.s_addr = ntohl(range_p->last_ip - 1);
68 if (range_p->shared_net) {
69 fprintf(outfile, "%-20s",
70 range_p->shared_net->name);
72 fprintf(outfile, "not_defined ");
74 fprintf(outfile, "%-16s", inet_ntoa(first));
76 " - %-16s %5lu %5lu %10.3f %5lu %5lu %9.3f",
78 range_p->last_ip - range_p->first_ip - 1,
80 (float) (100 * range_p->count) /
81 (range_p->last_ip - range_p->first_ip - 1),
83 range_p->touched + range_p->count,
87 (range_p->last_ip - range_p->first_ip -
89 if (0 < num_backups) {
90 fprintf(outfile, "%7lu %8.3f",
92 (float) (100 * range_p->backups) /
94 range_p->first_ip - 1));
96 fprintf(outfile, "\n");
100 if (config.output_limit[1] & output_limit_bit_1
101 && config.output_limit[0] & output_limit_bit_2) {
102 fprintf(outfile, "\n");
104 if (config.output_limit[0] & output_limit_bit_2) {
105 fprintf(outfile, "Shared networks:\n");
107 "name max cur percent touch t+c t+c perc");
108 if (0 < num_backups) {
109 fprintf(outfile, " bu bu perc");
111 fprintf(outfile, "\n");
113 if (config.output_limit[1] & output_limit_bit_2) {
114 for (i = 0; i < num_shared_networks; i++) {
117 "%-20s %5lu %5lu %10.3f %7lu %6lu %9.3f",
118 shared_p->name, shared_p->available,
120 (float) (100 * shared_p->used) /
121 shared_p->available, shared_p->touched,
122 shared_p->touched + shared_p->used,
126 shared_p->available);
127 if (0 < num_backups) {
128 fprintf(outfile, "%7lu %8.3f",
130 (float) (100 * shared_p->backups) /
131 shared_p->available);
134 fprintf(outfile, "\n");
137 if (config.output_limit[1] & output_limit_bit_2
138 && config.output_limit[0] & output_limit_bit_3) {
139 fprintf(outfile, "\n");
141 if (config.output_limit[0] & output_limit_bit_3) {
142 fprintf(outfile, "Sum of all ranges:\n");
144 "name max cur percent touch t+c t+c perc");
146 if (0 < num_backups) {
147 fprintf(outfile, " bu bu perc");
149 fprintf(outfile, "\n");
151 if (config.output_limit[1] & output_limit_bit_3) {
152 fprintf(outfile, "%-20s %5lu %5lu %10.3f %7lu %6lu %9.3f",
153 shared_networks->name,
154 shared_networks->available,
155 shared_networks->used,
156 (float) (100 * shared_networks->used) /
157 shared_networks->available,
158 shared_networks->touched,
159 shared_networks->touched + shared_networks->used,
161 (shared_networks->touched +
162 shared_networks->used)) /
163 shared_networks->available);
165 if (0 < num_backups) {
166 fprintf(outfile, "%7lu %8.3f",
167 shared_networks->backups,
168 (float) (100 * shared_networks->backups) /
169 shared_networks->available);
171 fprintf(outfile, "\n");
173 if (outfile == stdout) {
174 ret = fflush(stdout);
176 warn("output_txt: fflush");
179 ret = fclose(outfile);
181 warn("output_txt: fclose");
191 struct in_addr first, last;
192 struct range_t *range_p;
193 struct shared_network_t *shared_p;
197 if (config.output_file[0]) {
198 outfile = fopen(config.output_file, "w+");
199 if (outfile == NULL) {
200 err(EXIT_FAILURE, "output_xml: %s",
208 shared_p = shared_networks;
210 if (config.output_limit[1] & output_limit_bit_1) {
211 for (i = 0; i < num_ranges; i++) {
212 first.s_addr = ntohl(range_p->first_ip + 1);
213 last.s_addr = ntohl(range_p->last_ip - 1);
215 fprintf(outfile, "<subnet>\n");
217 if (range_p->shared_net) {
219 "\t<location>%s</location>\n",
220 range_p->shared_net->name);
223 "\t<location></location>\n");
226 fprintf(outfile, "\t<network></network>\n");
227 fprintf(outfile, "\t<netmask></netmask>\n");
228 fprintf(outfile, "\t<range>%s ", inet_ntoa(first));
229 fprintf(outfile, "- %s</range>\n",
231 fprintf(outfile, "\t<gateway></gateway>\n");
232 fprintf(outfile, "\t<defined>%lu</defined>\n",
233 range_p->last_ip - range_p->first_ip - 1);
234 fprintf(outfile, "\t<used>%lu</used>\n",
236 fprintf(outfile, "\t<free>%lu</free>\n",
237 range_p->last_ip - range_p->first_ip - 1 -
242 fprintf(outfile, "</subnet>\n");
246 if (config.output_limit[1] & output_limit_bit_2) {
247 for (i = 0; i < num_shared_networks; i++) {
250 fprintf(outfile, "<shared-network>\n");
251 fprintf(outfile, "\t<location>%s</location>\n",
253 fprintf(outfile, "\t<defined>%lu</defined>\n",
254 shared_p->available);
255 fprintf(outfile, "\t<used>%lu</used>\n",
257 fprintf(outfile, "\t<free>%lu</free>\n",
258 shared_p->available - shared_p->used);
259 fprintf(outfile, "</shared-network>\n");
263 if (config.output_limit[0] & output_limit_bit_3) {
264 fprintf(outfile, "<summary>\n");
265 fprintf(outfile, "\t<location>%s</location>\n",
266 shared_networks->name);
267 fprintf(outfile, "\t<defined>%lu</defined>\n",
268 shared_networks->available);
269 fprintf(outfile, "\t<used>%lu</used>\n",
270 shared_networks->used);
271 fprintf(outfile, "\t<free>%lu</free>\n",
272 shared_networks->available -
273 shared_networks->used);
274 fprintf(outfile, "</summary>\n");
277 if (outfile == stdout) {
278 ret = fflush(stdout);
280 warn("output_xml: fflush");
283 ret = fclose(outfile);
285 warn("output_xml: fclose");
292 void html_header(FILE * f)
295 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \n");
296 fprintf(f, " \"http://www.w3.org/TR/html4/strict.dtd\">\n");
297 fprintf(f, "<html>\n");
298 fprintf(f, "<head>\n");
299 fprintf(f, "<meta http-equiv=\"Content-Type\" ");
300 fprintf(f, "content=\"text/html; charset=iso-8859-1\">\n");
301 fprintf(f, " <title>ISC dhcpd stats</title>\n");
302 fprintf(f, " <style TYPE=\"text/css\">\n");
303 fprintf(f, " <!--\n");
304 fprintf(f, " table.dhcpd-pools {\n");
305 fprintf(f, " color: black;\n");
306 fprintf(f, " vertical-align: middle;\n");
307 fprintf(f, " text-align: center;\n");
309 fprintf(f, " table.dhcpd-pools th.section {\n");
310 fprintf(f, " color: black;\n");
311 fprintf(f, " font-size: large;\n");
312 fprintf(f, " vertical-align: middle;\n");
313 fprintf(f, " text-align: left;\n");
315 fprintf(f, " table.dhcpd-pools th.calign {\n");
316 fprintf(f, " color: black;\n");
317 fprintf(f, " vertical-align: middle;\n");
318 fprintf(f, " text-align: center;\n");
319 fprintf(f, " text-decoration: underline;\n");
321 fprintf(f, " table.dhcpd-pools th.ralign {\n");
322 fprintf(f, " color: black;\n");
323 fprintf(f, " vertical-align: middle;\n");
324 fprintf(f, " text-align: right;\n");
325 fprintf(f, " text-decoration: underline;\n");
327 fprintf(f, " table.dhcpd-pools td.calign {\n");
328 fprintf(f, " color: black;\n");
329 fprintf(f, " vertical-align: middle;\n");
330 fprintf(f, " text-align: center;\n");
332 fprintf(f, " table.dhcpd-pools td.ralign {\n");
333 fprintf(f, " color: black;\n");
334 fprintf(f, " vertical-align: middle;\n");
335 fprintf(f, " text-align: right;\n");
337 fprintf(f, " p.created {\n");
338 fprintf(f, " font-size: small;\n");
339 fprintf(f, " color: grey;\n");
341 fprintf(f, " p.updated {\n");
342 fprintf(f, " font-size: small;\n");
343 fprintf(f, " color: grey;\n");
344 fprintf(f, " font-style: italic;\n");
346 fprintf(f, " -->\n");
347 fprintf(f, " </style>\n");
348 fprintf(f, "</head>\n");
349 fprintf(f, "<body>\n");
352 void html_footer(FILE * f)
354 fprintf(f, "<p><br></p>\n");
355 fprintf(f, "<hr>\n");
356 fprintf(f, "<p class=created>\nData generated by ");
357 fprintf(f, "<a href=\"%s\">", PACKAGE_URL);
358 fprintf(f, "dhcpd-pools</a>.\n</p>\n");
360 fprintf(f, "<p class=updated>\n");
361 fprintf(f, "<script type=\"text/javascript\">\n");
362 fprintf(f, " document.write(\"Last Updated On \" + ");
363 fprintf(f, "document.lastModified + \".\")\n");
364 fprintf(f, "</script>\n<br>\n</p>\n");
365 fprintf(f, "</body>\n");
366 fprintf(f, "</html>\n");
369 void newrow(FILE * f)
371 fprintf(f, "<tr>\n");
374 void endrow(FILE * f)
376 fprintf(f, "</tr>\n\n");
379 void output_line(FILE * f, char *type, char *class, char *text)
381 fprintf(f, " <%s class=%s>%s</%s>\n", type, class, text, type);
384 void output_long(FILE * f, char *type, unsigned long unlong)
386 fprintf(f, " <%s class=ralign>%lu</%s>\n", type, unlong, type);
389 void output_float(FILE * f, char *type, float fl)
391 fprintf(f, " <%s class=ralign>%.3f</%s>\n", type, fl, type);
394 void table_start(FILE * f)
396 fprintf(f, "<table width=\"75%%\" ");
397 fprintf(f, "class=\"dhcpd-pools\" ");
398 fprintf(f, "summary=\"ISC dhcpd pool usage report\">\n");
401 void table_end(FILE * f)
403 fprintf(f, "</table>\n");
406 void newsection(FILE * f, char *title)
409 output_line(f, "td", "calign", " ");
413 output_line(f, "th", "section", title);
417 int output_html(void)
420 struct in_addr first, last;
421 struct range_t *range_p;
422 struct shared_network_t *shared_p;
426 if (config.output_file[0]) {
427 outfile = fopen(config.output_file, "w+");
428 if (outfile == NULL) {
429 err(EXIT_FAILURE, "output_html: %s",
437 shared_p = shared_networks;
440 html_header(outfile);
442 table_start(outfile);
443 if (config.output_limit[0] & output_limit_bit_1) {
444 newsection(outfile, "Ranges:");
446 output_line(outfile, "th", "calign", "shared net name");
447 output_line(outfile, "th", "calign", "first ip");
448 output_line(outfile, "th", "calign", "last ip");
449 output_line(outfile, "th", "ralign", "max");
450 output_line(outfile, "th", "ralign", "cur");
451 output_line(outfile, "th", "ralign", "percent");
452 output_line(outfile, "th", "ralign", "touch");
453 output_line(outfile, "th", "ralign", "t+c");
454 output_line(outfile, "th", "ralign", "t+c perc");
455 if (0 < num_backups) {
456 output_line(outfile, "th", "ralign", "bu");
457 output_line(outfile, "th", "ralign", "bu perc");
461 if (config.output_limit[1] & output_limit_bit_1) {
462 for (i = 0; i < num_ranges; i++) {
463 first.s_addr = ntohl(range_p->first_ip + 1);
464 last.s_addr = ntohl(range_p->last_ip - 1);
467 if (range_p->shared_net) {
468 output_line(outfile, "td", "calign",
469 range_p->shared_net->name);
471 output_line(outfile, "td", "calign",
474 output_line(outfile, "td", "calign",
476 output_line(outfile, "td", "calign",
478 output_long(outfile, "td",
479 range_p->last_ip - range_p->first_ip -
481 output_long(outfile, "td", range_p->count);
482 output_float(outfile, "td",
483 (float) (100 * range_p->count) /
485 range_p->first_ip - 1));
486 output_long(outfile, "td", range_p->touched);
487 output_long(outfile, "td",
488 range_p->touched + range_p->count);
489 output_float(outfile, "td",
494 range_p->first_ip - 1));
495 if (0 < num_backups) {
496 output_long(outfile, "td",
498 output_float(outfile, "td",
502 range_p->first_ip - 1));
509 table_start(outfile);
510 if (config.output_limit[0] & output_limit_bit_2) {
511 newsection(outfile, "Shared networks:");
514 output_line(outfile, "th", "calign", "name");
515 output_line(outfile, "th", "ralign", "max");
516 output_line(outfile, "th", "ralign", "cur");
517 output_line(outfile, "th", "ralign", "percent");
518 output_line(outfile, "th", "ralign", "touch");
519 output_line(outfile, "th", "ralign", "t+c");
520 output_line(outfile, "th", "ralign", "t+c perc");
521 if (0 < num_backups) {
522 output_line(outfile, "th", "ralign", "bu");
523 output_line(outfile, "th", "ralign", "bu perc");
527 if (config.output_limit[1] & output_limit_bit_2) {
528 for (i = 0; i < num_shared_networks; i++) {
531 output_line(outfile, "td", "calign",
533 output_long(outfile, "td", shared_p->available);
534 output_long(outfile, "td", shared_p->used);
535 output_float(outfile, "td",
536 (float) (100 * shared_p->used) /
537 shared_p->available);
538 output_long(outfile, "td", shared_p->touched);
539 output_long(outfile, "td",
540 shared_p->touched + shared_p->used);
541 output_float(outfile, "td",
545 shared_p->available);
546 if (0 < num_backups) {
547 output_long(outfile, "td",
549 output_float(outfile, "td",
552 shared_p->available);
558 if (config.output_limit[0] & output_limit_bit_3) {
559 newsection(outfile, "Sum of all ranges:");
562 output_line(outfile, "th", "calign", "name");
563 output_line(outfile, "th", "ralign", "max");
564 output_line(outfile, "th", "ralign", "cur");
565 output_line(outfile, "th", "ralign", "percent");
566 output_line(outfile, "th", "ralign", "touch");
567 output_line(outfile, "th", "ralign", "t+c");
568 output_line(outfile, "th", "ralign", "t+c perc");
569 if (0 < num_backups) {
570 output_line(outfile, "th", "ralign", "bu");
571 output_line(outfile, "th", "ralign", "bu perc");
576 if (config.output_limit[1] & output_limit_bit_3) {
578 output_line(outfile, "td", "calign",
579 shared_networks->name);
580 output_long(outfile, "td", shared_networks->available);
581 output_long(outfile, "td", shared_networks->used);
582 output_float(outfile, "td",
583 (float) (100 * shared_networks->used) /
584 shared_networks->available);
585 output_long(outfile, "td", shared_networks->touched);
586 output_long(outfile, "td",
587 shared_networks->touched +
588 shared_networks->used);
589 output_float(outfile, "td",
591 (shared_networks->touched +
592 shared_networks->used)) /
593 shared_networks->available);
594 if (0 < num_backups) {
595 output_long(outfile, "td",
596 shared_networks->backups);
597 output_float(outfile, "td",
599 shared_networks->backups) /
600 shared_networks->available);
606 html_footer(outfile);
608 if (outfile == stdout) {
609 ret = fflush(stdout);
611 warn("output_html: fflush");
614 ret = fclose(outfile);
616 warn("output_html: fclose");
625 struct in_addr first, last;
626 struct range_t *range_p;
627 struct shared_network_t *shared_p;
631 if (config.output_file[0]) {
632 outfile = fopen(config.output_file, "w+");
633 if (outfile == NULL) {
634 err(EXIT_FAILURE, "output_csv: %s",
642 shared_p = shared_networks;
644 if (config.output_limit[0] & output_limit_bit_1) {
645 fprintf(outfile, "\"Ranges:\"\n");
648 "\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"");
649 if (0 < num_backups) {
650 fprintf(outfile, ",\"bu\",\"bu perc\"");
652 fprintf(outfile, "\n");
655 if (config.output_limit[1] & output_limit_bit_1) {
656 for (i = 0; i < num_ranges; i++) {
657 first.s_addr = ntohl(range_p->first_ip + 1);
658 last.s_addr = ntohl(range_p->last_ip - 1);
660 if (range_p->shared_net) {
661 fprintf(outfile, "\"%s\",",
662 range_p->shared_net->name);
664 fprintf(outfile, "\"not_defined\",");
666 fprintf(outfile, "\"%s\",", inet_ntoa(first));
668 "\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"",
670 range_p->last_ip - range_p->first_ip - 1,
672 (float) (100 * range_p->count) /
673 (range_p->last_ip - range_p->first_ip - 1),
675 range_p->touched + range_p->count,
679 (range_p->last_ip - range_p->first_ip -
681 if (0 < num_backups) {
682 fprintf(outfile, ",\"%lu\",\"%.3f\"",
684 (float) (100 * range_p->backups) /
686 range_p->first_ip - 1));
690 fprintf(outfile, "\n");
693 fprintf(outfile, "\n");
695 if (config.output_limit[0] & output_limit_bit_2) {
696 fprintf(outfile, "\"Shared networks:\"\n");
698 "\"name\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"");
699 if (0 < num_backups) {
700 fprintf(outfile, ",\"bu\",\"bu perc\"");
702 fprintf(outfile, "\n");
704 if (config.output_limit[1] & output_limit_bit_2) {
706 for (i = 0; i < num_shared_networks; i++) {
709 "\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"",
710 shared_p->name, shared_p->available,
712 (float) (100 * shared_p->used) /
713 shared_p->available, shared_p->touched,
714 shared_p->touched + shared_p->used,
718 shared_p->available);
719 if (0 < num_backups) {
720 fprintf(outfile, ",\"%lu\",\"%.3f\"",
722 (float) (100 * shared_p->backups) /
723 shared_p->available);
726 fprintf(outfile, "\n");
730 fprintf(outfile, "\n");
732 if (config.output_limit[0] & output_limit_bit_3) {
733 fprintf(outfile, "\"Sum of all ranges:\"\n");
735 "\"name\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"");
736 if (0 < num_backups) {
737 fprintf(outfile, ",\"bu\",\"bu perc\"");
739 fprintf(outfile, "\n");
741 if (config.output_limit[1] & output_limit_bit_3) {
744 "\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"",
745 shared_networks->name, shared_networks->available,
746 shared_networks->used,
747 (float) (100 * shared_networks->used) /
748 shared_networks->available,
749 shared_networks->touched,
750 shared_networks->touched + shared_networks->used,
752 (shared_networks->touched +
753 shared_networks->used)) /
754 shared_networks->available);
755 if (0 < num_backups) {
756 fprintf(outfile, "%7lu %8.3f",
757 shared_networks->backups,
758 (float) (100 * shared_networks->backups) /
759 shared_networks->available);
761 fprintf(outfile, "\n");
764 if (outfile == stdout) {
765 ret = fflush(stdout);
767 warn("output_cvs: fflush");
771 ret = fclose(outfile);
773 warn("output_cvs: fclose");