Version 2.2

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2006-03-27 00:00:00 +02:00
parent 61b6acf2f5
commit 658fe50312
14 changed files with 697 additions and 163 deletions

View file

@ -1,3 +1,11 @@
2006-xx-yy Sami Kerola <kerolasa@iki.fi>
* Release 2.2
* No ranges defined -> crash bug fixed.
* Better error messages for command line options.
* File flushes more clean and error messages added.
* Possibility to limit what is printed out.
* Output limit update to man page.
2006-03-13 Sami Kerola <sami.kerola@iki.fi>
* Release 2.1

7
NEWS
View file

@ -5,6 +5,13 @@ See the end for copying conditions.
Please send dhcpd-pools bug reports to kerolasa@iki.fi.
Version 2.2
* Bugfixes:
*. No ranges in dhcpd.conf -> crash.
* Better error messages.
* Possibility to limit output.
Version 2.1
* Bugfixs:

2
THANKS
View file

@ -8,3 +8,5 @@ and exempt of errors.
Otto J. Mäkelä
Mika Paananen
Brian W. Kernighan
Rob Pike

2
TODO
View file

@ -8,8 +8,6 @@ Todo:
using auto tools. Help needed.
* Bad english to good english translation for all files that
author has touched. Help needed.
* Output limit for pools / shared net / all. Bit mask will do
this quite nicely, copy idea from chmod.
* Threshold values -> alarm possibility.
* Bug perhaps not? ./dhcpd-pools -o /dev/null
/dev/null: Inappropriate ioctl for device

View file

@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT([dhcpd-pools], [2.1], [kerolasa@iki.fi])
AC_INIT([dhcpd-pools], [2.2], [kerolasa@iki.fi])
AM_INIT_AUTOMAKE([1.9 foreign])
@ -40,6 +40,14 @@ AC_ARG_WITH(output-format,
)
AC_SUBST(output_format)
AC_ARG_WITH(output-limit,
[ --with-output-limit=NRO Default output limit 00 - 77],
[ output_limit=$withval
CPPFLAGS="$CPPFLAGS -DOUTPUT_LIMIT='\"$withval\"'" ],
[ output_limit=$output_limit_default ]
)
AC_SUBST(output_limit)
AC_CHECK_FUNCS(getopt_long inet_aton inet_addr, break)
AC_CHECK_LIB(resolv, inet_ntoa)

View file

@ -2,7 +2,7 @@
.\" http://www.iki.fi/kerolasa/
.\" kerolasa@iki.fi
.\"
.TH DHCPD-POOLS 1 "Mar 9 2006 - version 2.1"
.TH DHCPD-POOLS 1 "Mar 14 2006 - version 2.2"
.SH NAME
dhcpd-pools \- ISC dhcp pools usage analysis
.SH SYNOPSIS
@ -26,6 +26,12 @@ Output format. Currently there is text, html and csv
.I "\-o, \-\-output"
File where output is directed. Default is stdout.
.TP
.I "\-L, \-\-limit"
Limit what is printed. Syntax is similar to chmod permission
string. This limit string has two meaningful digits which can be
between 0 and 7. First digit limits output of headers and second
numeric analysis tables.
.TP
.I "\-v, \-\-version"
Print version information to standard output and exit successfully.
.TP
@ -51,4 +57,5 @@ Sami Kerola <kerolasa@iki.fi>
http://dhcpd-pools.sourceforge.net/
.SH "SEE ALSO"
.BR dhcpd.leases (5),
.BR dhcpd.conf (5)
.BR dhcpd.conf (5),
.BR chmod (1)

View file

@ -104,6 +104,12 @@ do_counting (void)
if (range_p->last_ip < leases[i])
{
range_p++;
/* Break loop before trying to access memorory that is
* not allocated. */
if (range_p - ranges > num_ranges)
{
break;
}
block_size = range_p->last_ip - range_p->first_ip - 1;
if (range_p->shared_net)
{

View file

@ -32,6 +32,9 @@
#ifndef OUTPUT_FORMAT
# define OUTPUT_FORMAT "text"
#endif
#ifndef OUTPUT_LIMIT
# define OUTPUT_LIMIT "77"
#endif
/* Maximum line length in dhcpd.conf and dhcpd.leases */
static const int MAXLEN = 1024;

View file

@ -45,6 +45,7 @@ int
main (int argc, char **argv)
{
int c;
char *tmp;
FILE *fopen_test;
/* Options for getopt_long */
@ -53,6 +54,7 @@ main (int argc, char **argv)
{"leases", required_argument, 0, (int) 'l'},
{"format", required_argument, 0, (int) 'f'},
{"output", required_argument, 0, (int) 'o'},
{"limit", required_argument, 0, (int) 'L'},
{"version", no_argument, 0, (int) 'v'},
{"help", no_argument, 0, (int) 'h'},
{0, 0, 0, 0}
@ -70,6 +72,10 @@ main (int argc, char **argv)
strncpy (config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1);
strncpy (config.dhcpdlease_file, DHCPDLEASE_FILE, MAXLEN - 1);
tmp = OUTPUT_LIMIT;
config.output_limit[0] = (int) (*tmp - '0');
tmp++;
config.output_limit[1] = (int) (*tmp - '0');
/* Make sure some output format is selected by default */
strncpy (config.output_format, OUTPUT_FORMAT, 1);
@ -77,7 +83,7 @@ main (int argc, char **argv)
/* Parse command line options */
while (1)
{
c = getopt_long (argc, argv, "clfovh", long_options, (int *) 0);
c = getopt_long (argc, argv, "clfoLvh", long_options, (int *) 0);
if (c == EOF)
break;
@ -93,6 +99,7 @@ main (int argc, char **argv)
}
else
{
eprintf ("main: for argument -c parameter not set");
print_help ();
exit (EXIT_FAILURE);
}
@ -104,6 +111,7 @@ main (int argc, char **argv)
}
else
{
eprintf ("main: for argument -l parameter not set");
print_help ();
exit (EXIT_FAILURE);
}
@ -115,6 +123,7 @@ main (int argc, char **argv)
}
else
{
eprintf ("main: for argument -f parameter not set");
print_help ();
exit (EXIT_FAILURE);
}
@ -127,19 +136,50 @@ main (int argc, char **argv)
fopen_test = fopen (config.output_file, "w+");
if (fopen_test == NULL)
{
eprintf ("%s:", config.output_file);
print_help ();
eprintf ("main: %s:", config.output_file);
exit (EXIT_FAILURE);
}
fclose (fopen_test);
if (errno)
{
eprintf ("%s:", config.output_file);
eprintf ("main: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
else
{
eprintf ("main: for argument -o parameter not set");
print_help ();
exit (EXIT_FAILURE);
}
break;
case 'L':
if (argv[optind] != NULL)
{
if (argv[optind][0] >= '0' && argv[optind][0] < '8')
{
config.output_limit[0] = (int) argv[optind][0] - '0';
}
else
{
eprintf ("main: output limit mask %s illegal", argv[optind]);
print_help ();
exit (EXIT_FAILURE);
}
if (argv[optind][1] >= '0' && argv[optind][1] < '8')
{
config.output_limit[1] = (int) argv[optind][1] - '0';
}
else
{
eprintf ("main: output limit mask %s illegal", argv[optind]);
print_help ();
exit (EXIT_FAILURE);
}
}
else
{
eprintf ("main: for argument -L parameter not set");
print_help ();
exit (EXIT_FAILURE);
}
@ -173,6 +213,7 @@ main (int argc, char **argv)
output_analysis = output_txt;
break;
default:
eprintf ("main: unknown ouput format");
print_help ();
exit (EXIT_FAILURE);
}

View file

@ -37,6 +37,7 @@ struct configuration_t
char *dhcpdlease_file;
char output_format[2];
char *output_file;
int output_limit[2];
};
struct shared_network_t
{
@ -54,9 +55,13 @@ struct range_t
/* External variables */
char *program_name;
static const float version_number = 2.1;
static const float version_number = 2.2;
struct configuration_t config;
static int output_limit_bit_1 = 1;
static int output_limit_bit_2 = 2;
static int output_limit_bit_3 = 4;
struct shared_network_t *shared_networks;
char *shared_net_names;
unsigned int num_shared_networks;

View file

@ -84,7 +84,7 @@ parse_config (void)
dhcpd_config = fopen (config.dhcpdconf_file, "r");
if (dhcpd_config == NULL)
{
eprintf ("%s:", config.dhcpdconf_file);
eprintf ("parse_config: %s:", config.dhcpdconf_file);
exit (EXIT_FAILURE);
}
@ -162,8 +162,7 @@ parse_config (void)
if (num_ranges > RANGES)
{
fprintf (stderr, "Range space full!\n");
fprintf (stderr, "Increase RANGES and recompile.\n");
eprintf ("parse_config: Range space full! Increase RANGES and recompile.");
exit (EXIT_FAILURE);
}
}
@ -173,9 +172,7 @@ parse_config (void)
linelen = strlen (line);
if (shared_name_p + linelen > last_shared)
{
fprintf (stderr, "Shared network name space full!\n");
fprintf (stderr,
"Increase SHARED_NETWORKS_NAMES and recompile\n");
eprintf ("parse_config: Shared network name space full! Increase SHARED_NETWORKS_NAMES and recompile.\n");
exit (EXIT_FAILURE);
}
@ -191,8 +188,7 @@ parse_config (void)
if (num_shared_networks > SHARED_NETWORKS)
{
fprintf (stderr, "Shared network space full!\n");
fprintf (stderr, "Increase SHARED_NETWORKS and recompile\n");
eprintf ("parse_config: Shared network space full! Increase SHARED_NETWORKS and recompile.\n");
exit (EXIT_FAILURE);
}
}
@ -215,7 +211,7 @@ parse_leases (void)
dhcpd_leases = fopen (config.dhcpdlease_file, "r");
if (dhcpd_leases == NULL)
{
eprintf ("%s:", config.dhcpdlease_file);
eprintf ("parse_leases: %s:", config.dhcpdlease_file);
exit (EXIT_FAILURE);
}
@ -226,7 +222,7 @@ parse_leases (void)
* to hear about that. */
if (stat (config.dhcpdlease_file, &lease_file_stats))
{
eprintf ("%s:", config.dhcpdlease_file);
eprintf ("parse_leases: %s:", config.dhcpdlease_file);
exit (EXIT_FAILURE);
}
leases =

View file

@ -44,7 +44,7 @@ safe_malloc (size_t size)
void *ret = malloc (size);
if (ret == NULL)
{
eprintf ("malloc: ");
eprintf ("safe_malloc: malloc: ");
exit (EXIT_FAILURE);
}
return ret;
@ -84,7 +84,17 @@ clean_up (void)
free (shared_networks);
/* Just in case there something in buffers */
fclose (stdout);
if (errno)
{
eprintf ("clean_up: stdout:");
exit (EXIT_FAILURE);
}
fclose (stderr);
if (errno)
{
eprintf ("clean_up: stderr:");
exit (EXIT_FAILURE);
}
}
void
@ -114,6 +124,7 @@ This is ISC dhcpd pools usage analyzer.\n\
*/
fprintf (stdout, "\
-o --output file output into a file\n\
-L --limit nr output limit mask 77 - 00\n\
-v --version version information\n\
-h --help this screen\n\
\n\

View file

@ -47,7 +47,7 @@ output_txt (void)
outfile = fopen (config.output_file, "w+");
if (outfile == NULL)
{
eprintf ("%s:", config.output_file);
eprintf ("output_txt: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
@ -59,58 +59,89 @@ output_txt (void)
range_p = ranges;
shared_p = shared_networks;
fprintf (outfile, "Ranges:\n");
fprintf
(outfile,
"shared net name first ip last ip max cur percent\n");
for (i = 0; i < num_ranges; i++)
if (config.output_limit[0] & output_limit_bit_1)
{
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
fprintf (outfile, "Ranges:\n");
fprintf
(outfile,
"shared net name first ip last ip max cur percent\n");
}
if (config.output_limit[1] & output_limit_bit_1)
{
for (i = 0; i < num_ranges; i++)
{
fprintf (outfile, "%-20s", range_p->shared_net->name);
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
{
fprintf (outfile, "%-20s", range_p->shared_net->name);
}
else
{
fprintf (outfile, "not_defined ");
}
fprintf (outfile, "%-16s", inet_ntoa (first));
fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n",
inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_2)
{
fprintf (outfile, "Shared networks:\n");
fprintf (outfile, "name max cur percent\n");
}
if (config.output_limit[1] & output_limit_bit_2)
{
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf (outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_3)
{
fprintf (outfile, "Sum of all ranges:\n");
fprintf (outfile, "name max cur percent\n");
}
if (config.output_limit[1] & output_limit_bit_3)
{
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
}
if (outfile == stdout)
{
fflush (stdout);
}
else
{
fclose (outfile);
}
if (errno)
{
if (config.output_file[0])
{
eprintf ("output_txt: %s:", config.output_file);
}
else
{
fprintf (outfile, "not_defined ");
eprintf ("output_txt: stdout:");
}
fprintf (outfile, "%-16s", inet_ntoa (first));
fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n",
inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\nShared networks:\n");
fprintf (outfile, "name max cur percent\n");
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf (outfile, "\nSum of all ranges:\n");
fprintf (outfile, "name max cur percent\n");
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
fclose (outfile);
if (errno)
{
eprintf ("%s:", config.output_file);
exit (EXIT_FAILURE);
}
@ -132,7 +163,7 @@ output_html (void)
outfile = fopen (config.output_file, "w+");
if (outfile == NULL)
{
eprintf ("%s:", config.output_file);
eprintf ("output_html: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
@ -146,60 +177,89 @@ output_html (void)
fprintf (outfile,
"<table width=\"75%\" class=\"dhcpd-pools\" summary=\"ISC dhcpd pool usage raport\">\n");
fprintf (outfile, "<tr><th>Ranges:</th></tr>\n");
fprintf
(outfile,
"<tr><th>shared net name</th><th>first ip</th><th>last ip</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
for (i = 0; i < num_ranges; i++)
if (config.output_limit[0] & output_limit_bit_1)
{
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
fprintf (outfile, "<tr><th>Ranges:</th></tr>\n");
fprintf
(outfile,
"<tr><th>shared net name</th><th>first ip</th><th>last ip</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_1)
{
for (i = 0; i < num_ranges; i++)
{
fprintf (outfile, "<tr><td>%s</td>", range_p->shared_net->name);
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
{
fprintf (outfile, "<tr><td>%s</td>", range_p->shared_net->name);
}
else
{
fprintf (outfile, "<tr><td>not_defined</td>");
}
fprintf (outfile, "<td>%s</td>", inet_ntoa (first));
fprintf (outfile,
"<td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
}
if (config.output_limit[0] & output_limit_bit_2)
{
fprintf (outfile, "\n<tr><th>Shared networks:</th></tr>\n");
fprintf (outfile,
"<tr><th>name</td><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_2)
{
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile,
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
shared_p->name, shared_p->available, shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
}
if (config.output_limit[0] & output_limit_bit_3)
{
fprintf (outfile, "\n<tr><th>Sum of all ranges:</th></tr>\n");
fprintf (outfile,
"<tr><th>name</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_3)
{
fprintf (outfile,
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
shared_networks->name, shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
}
fprintf (outfile, "</table>\n");
if (outfile == stdout)
{
fflush (stdout);
}
else
{
fclose (outfile);
}
if (errno)
{
if (config.output_file[0])
{
eprintf ("output_html: %s:", config.output_file);
}
else
{
fprintf (outfile, "<tr><td>not_defined</td>");
eprintf ("output_html: stdout:");
}
fprintf (outfile, "<td>%s</td>", inet_ntoa (first));
fprintf (outfile,
"<td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\n<tr><th>Shared networks:</th></tr>\n");
fprintf (outfile,
"<tr><th>name</td><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile,
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
shared_p->name, shared_p->available, shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf (outfile, "\n<tr><th>Sum of all ranges:</th></tr>\n");
fprintf (outfile,
"<tr><th>name</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
fprintf (outfile,
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
shared_networks->name, shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
fprintf (outfile, "</table>\n");
fclose (outfile);
if (errno)
{
eprintf ("%s:", config.output_file);
exit (EXIT_FAILURE);
}
@ -220,7 +280,7 @@ output_csv (void)
outfile = fopen (config.output_file, "w+");
if (outfile == NULL)
{
eprintf ("%s:", config.output_file);
eprintf ("output_csv: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
@ -232,57 +292,91 @@ output_csv (void)
range_p = ranges;
shared_p = shared_networks;
fprintf (outfile, "\"Ranges:\"\n");
fprintf
(outfile,
"\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n");
for (i = 0; i < num_ranges; i++)
if (config.output_limit[0] & output_limit_bit_1)
{
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
fprintf (outfile, "\"Ranges:\"\n");
fprintf
(outfile,
"\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n");
}
if (config.output_limit[1] & output_limit_bit_1)
{
for (i = 0; i < num_ranges; i++)
{
fprintf (outfile, "\"%s\",", range_p->shared_net->name);
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
{
fprintf (outfile, "\"%s\",", range_p->shared_net->name);
}
else
{
fprintf (outfile, "\"not_defined\",");
}
fprintf (outfile, "\"%s\",", inet_ntoa (first));
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_2)
{
fprintf (outfile, "\"Shared networks:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
}
if (config.output_limit[1] & output_limit_bit_2)
{
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf (outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_3)
{
fprintf (outfile, "\"Sum of all ranges:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
}
if (config.output_limit[1] & output_limit_bit_3)
{
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
}
if (outfile == stdout)
{
fflush (stdout);
}
else
{
fclose (outfile);
}
if (errno)
{
if (config.output_file[0])
{
eprintf ("output_csv: %s:", config.output_file);
}
else
{
fprintf (outfile, "\"not_defined\",");
eprintf ("output_csv: stdout:");
}
fprintf (outfile, "\"%s\",", inet_ntoa (first));
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\n\"Shared networks:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf (outfile, "\n\"Sum of all ranges:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
fclose (outfile);
if (errno)
{
eprintf ("%s:", config.output_file);
exit (EXIT_FAILURE);
}

348
src/output.c~ Normal file
View file

@ -0,0 +1,348 @@
/*
** Copyright (C) 2006 Sami Kerola <kerolasa@iki.fi>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include "dhcpd-pools.h"
/* There should be command line switches that can be used to
* limit output. Not always one wishes to see headers, ranges,
* shared networks or total. Perhaps this is fixed on next
* version. */
int
output_txt (void)
{
unsigned int i;
struct in_addr first, last;
struct range_t *range_p;
struct shared_network_t *shared_p;
FILE *outfile;
if (config.output_file[0])
{
outfile = fopen (config.output_file, "w+");
if (outfile == NULL)
{
eprintf ("output_txt: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
else
{
outfile = stdout;
}
range_p = ranges;
shared_p = shared_networks;
if (config.output_limit[0] & output_limit_bit_1) {
fprintf (outfile, "Ranges:\n");
fprintf
(outfile,
"shared net name first ip last ip max cur percent\n");
}
if (config.output_limit[1] & output_limit_bit_1) {
for (i = 0; i < num_ranges; i++)
{
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
{
fprintf (outfile, "%-20s", range_p->shared_net->name);
}
else
{
fprintf (outfile, "not_defined ");
}
fprintf (outfile, "%-16s", inet_ntoa (first));
fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n",
inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf(outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_2) {
fprintf (outfile, "Shared networks:\n");
fprintf (outfile, "name max cur percent\n");
}
if (config.output_limit[1] & output_limit_bit_2) {
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf(outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_3) {
fprintf (outfile, "Sum of all ranges:\n");
fprintf (outfile, "name max cur percent\n");
}
if (config.output_limit[1] & output_limit_bit_3) {
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
}
if (outfile == stdout) {
fflush(stdout);
} else {
fclose (outfile);
}
if (errno)
{
if (config.output_file[0]) {
eprintf ("output_txt: %s:", config.output_file);
} else {
eprintf ("output_txt: stdout:");
}
exit (EXIT_FAILURE);
}
return 0;
}
int
output_html (void)
{
unsigned int i;
struct in_addr first, last;
struct range_t *range_p;
struct shared_network_t *shared_p;
FILE *outfile;
if (config.output_file[0])
{
outfile = fopen (config.output_file, "w+");
if (outfile == NULL)
{
eprintf ("output_html: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
else
{
outfile = stdout;
}
range_p = ranges;
shared_p = shared_networks;
fprintf (outfile,
"<table width=\"75%\" class=\"dhcpd-pools\" summary=\"ISC dhcpd pool usage raport\">\n");
if (config.output_limit[0] & output_limit_bit_1) {
fprintf (outfile, "<tr><th>Ranges:</th></tr>\n");
fprintf
(outfile,
"<tr><th>shared net name</th><th>first ip</th><th>last ip</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_1) {
for (i = 0; i < num_ranges; i++)
{
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
{
fprintf (outfile, "<tr><td>%s</td>", range_p->shared_net->name);
}
else
{
fprintf (outfile, "<tr><td>not_defined</td>");
}
fprintf (outfile, "<td>%s</td>", inet_ntoa (first));
fprintf (outfile,
"<td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
}
if (config.output_limit[0] & output_limit_bit_2) {
fprintf (outfile, "\n<tr><th>Shared networks:</th></tr>\n");
fprintf (outfile,
"<tr><th>name</td><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_2) {
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile,
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
shared_p->name, shared_p->available, shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
}
if (config.output_limit[0] & output_limit_bit_3) {
fprintf (outfile, "\n<tr><th>Sum of all ranges:</th></tr>\n");
fprintf (outfile,
"<tr><th>name</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_3) {
fprintf (outfile,
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td></tr>\n",
shared_networks->name, shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
}
fprintf (outfile, "</table>\n");
if (outfile == stdout) {
fflush(stdout);
} else {
fclose (outfile);
}
if (errno)
{
if (config.output_file[0]) {
eprintf ("output_html: %s:", config.output_file);
} else {
eprintf ("output_html: stdout:");
}
exit (EXIT_FAILURE);
}
return 0;
}
int
output_csv (void)
{
unsigned int i;
struct in_addr first, last;
struct range_t *range_p;
struct shared_network_t *shared_p;
FILE *outfile;
if (config.output_file[0])
{
outfile = fopen (config.output_file, "w+");
if (outfile == NULL)
{
eprintf ("output_csv: %s:", config.output_file);
exit (EXIT_FAILURE);
}
}
else
{
outfile = stdout;
}
range_p = ranges;
shared_p = shared_networks;
if (config.output_limit[0] & output_limit_bit_1) {
fprintf (outfile, "\"Ranges:\"\n");
fprintf
(outfile,
"\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n");
}
if (config.output_limit[1] & output_limit_bit_1) {
for (i = 0; i < num_ranges; i++)
{
first.s_addr = ntohl (range_p->first_ip + 1);
last.s_addr = ntohl (range_p->last_ip - 1);
if (range_p->shared_net)
{
fprintf (outfile, "\"%s\",", range_p->shared_net->name);
}
else
{
fprintf (outfile, "\"not_defined\",");
}
fprintf (outfile, "\"%s\",", inet_ntoa (first));
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1,
range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip -
range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_2) {
fprintf (outfile, "\"Shared networks:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
}
if (config.output_limit[1] & output_limit_bit_2) {
for (i = 0; i < num_shared_networks; i++)
{
shared_p++;
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
}
fprintf (outfile, "\n");
}
if (config.output_limit[0] & output_limit_bit_3) {
fprintf (outfile, "\"Sum of all ranges:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
}
if (config.output_limit[1] & output_limit_bit_3) {
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available);
}
if (outfile == stdout) {
fflush(stdout);
} else {
fclose (outfile);
}
if (errno)
{
if (config.output_file[0]) {
eprintf ("output_csv: %s:", config.output_file);
} else {
eprintf ("output_csv: stdout:");
}
exit (EXIT_FAILURE);
}
return 0;
}