Version 2.6

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2008-05-10 00:00:00 +02:00
parent 8904b5b82c
commit 4f000e7ab6
14 changed files with 374 additions and 268 deletions

22
.gdb_history Normal file
View file

@ -0,0 +1,22 @@
run ./src/dhcpd-pools
run ./src/dhcpd-pools
file ./src/dhcpd-pools
run
help
help options
quit
run gdb.run
quit
run
quit
run
quit
run
quit
run
quit
run
quit
run
quit
quit

View file

@ -1,3 +1,9 @@
2008-05-10 Sami Kerola <kerolasa@iki.fi>
* Last version did not follow include directives.
* The dhcpd.conf parser was still quite stupid.
* Touched IP counting.
* All networks count was completely broken.
2008-05-05 Sami Kerola <kerolasa@iki.fi>
* Release 2.5
* Reverse order for output sorting.

6
NEWS
View file

@ -5,6 +5,12 @@ See the end for copying conditions.
Please send dhcpd-pools bug reports to kerolasa@iki.fi.
Version 2.6
* I forgot to follow include when I rewrote dhcpd.conf parser.
* And the dhcpd.conf parser was still quite stupid.
* All networks count was broken. Results before this version where bogus.
* Feature: Touched IP counting.
Version 2.5
* Feature:

13
TODO
View file

@ -1,16 +1,25 @@
<Todo state="Begin">
<Todo>
* Memory allocations to such that recopilation is _never_ needed.
* Bad english to good english translation in all files that
author has touched. Help needed!
* Count of touched IPs IE the ones which are leased some time and
currently marked as free. Knowing number of these should
give idea about possible peak value of reservations. Highly
unscientific thou.
* Output sorting should sort also shared networks to in use, perscent
etc order.
* Check comments, variable names etc so that the code makes more sense.
* More ./configure options.
* Touched IP output sort.
* All networks analyse.c semantics problem.
* Template based html page.
@ version 3.x (not coming soon)
* Configuration file for this command.
* Convert program to snmp subagent daemon.
* Analysis caching.
* Threshold values -> alarming possibility by snmp traps.
</Todo state="Done">
</Todo>

20
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for dhcpd-pools 2.5.
# Generated by GNU Autoconf 2.59 for dhcpd-pools 2.6.
#
# Report bugs to <kerolasa@iki.fi>.
#
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='dhcpd-pools'
PACKAGE_TARNAME='dhcpd-pools'
PACKAGE_VERSION='2.5'
PACKAGE_STRING='dhcpd-pools 2.5'
PACKAGE_VERSION='2.6'
PACKAGE_STRING='dhcpd-pools 2.6'
PACKAGE_BUGREPORT='kerolasa@iki.fi'
# Factoring default headers for most tests.
@ -779,7 +779,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures dhcpd-pools 2.5 to adapt to many kinds of systems.
\`configure' configures dhcpd-pools 2.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -841,7 +841,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of dhcpd-pools 2.5:";;
short | recursive ) echo "Configuration of dhcpd-pools 2.6:";;
esac
cat <<\_ACEOF
@ -967,7 +967,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
dhcpd-pools configure 2.5
dhcpd-pools configure 2.6
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@ -981,7 +981,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by dhcpd-pools $as_me 2.5, which was
It was created by dhcpd-pools $as_me 2.6, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@ -1625,7 +1625,7 @@ fi
# Define the identity of the package.
PACKAGE='dhcpd-pools'
VERSION='2.5'
VERSION='2.6'
cat >>confdefs.h <<_ACEOF
@ -4802,7 +4802,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by dhcpd-pools $as_me 2.5, which was
This file was extended by dhcpd-pools $as_me 2.6, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -4865,7 +4865,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
dhcpd-pools config.status 2.5
dhcpd-pools config.status 2.6
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"

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.5], [kerolasa@iki.fi])
AC_INIT([dhcpd-pools], [2.6], [kerolasa@iki.fi])
AM_INIT_AUTOMAKE([1.9 foreign])

View file

@ -2,7 +2,7 @@
.\" http://www.iki.fi/kerolasa/
.\" kerolasa@iki.fi
.\"
.TH DHCPD-POOLS 1 "May 1 2008 - version 2.5"
.TH DHCPD-POOLS 1 "May 10 2008 - version 2.6"
.SH NAME
dhcpd-pools \- ISC dhcp pools usage analysis
.SH SYNOPSIS
@ -11,6 +11,35 @@ dhcpd-pools \- ISC dhcp pools usage analysis
.SH DESCRIPTION
The program counts ISC dhcp shared network and pool usage
analysis and outputs it in selected format.
.SH FIELDS
.TP
.I "shared net name"
Name of the shared-network for the range.
.TP
.I "first ip"
First IP in lease pool range.
.TP
.I "last ip"
Last IP in lease pool range.
.TP
.I "max"
Number of IPs which exist on pool, shared network or all together.
.TP
.I "cur"
Number of leases currently in use.
.TP
.I "percent"
Percent of IPs currently in use compared to max.
.TP
.I "touch"
Number of leases which are not actively. This number should indicate how
much there are clients which are turned off.
.TP
.I "t+c"
Touched leases and currently in use together.
.TP
.I "t+c perc"
Percent of touched and currently in use together compared to max.
.SH ARGUMENTS
.TP
.I "\-c, \-\-config"

View file

@ -1 +0,0 @@
/usr/share/automake-1.6/mkinstalldirs

View file

@ -46,6 +46,21 @@ prepare_data (void)
}
num_leases = k;
/* Delete touched IPs that are in use */
j = 0;
for (i = 0; i < num_touches; i++)
{
if (bsearch
(&touches[i], leases, num_leases, sizeof (long int),
&intcomp) == NULL)
{
touches[j] = touches[i];
j++;
}
}
num_touches = j;
qsort (touches, (size_t) num_touches, sizeof (long int), &intcomp);
/* Sort ranges */
qsort (ranges, (size_t) num_ranges, sizeof (struct range_t), &rangecomp);
@ -57,41 +72,73 @@ int
do_counting (void)
{
struct range_t *range_p;
unsigned int i, block_size;
unsigned int i, j, k, block_size;
i = j = 0;
range_p = ranges;
for (i = 0; i < num_leases; i++)
for (k = 0; k < num_ranges; k++)
{
/* IP with in range */
if (range_p->first_ip < leases[i] && range_p->last_ip > leases[i])
/* Count IPs in use */
for (; range_p->last_ip > leases[i] && i < num_leases; i++)
{
if (range_p->first_ip > leases[i])
{
continue;
}
/* IP with in range */
range_p->count++;
if (range_p->shared_net)
{
range_p->shared_net->used++;
}
shared_networks->used++;
}
/* IP out of range */
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)
{
range_p->shared_net->available += block_size;
}
shared_networks->available += block_size;
i--;
}
/* Count touched IPs */
for (; range_p->last_ip > touches[j] && j < num_touches; j++)
{
if (range_p->first_ip > touches[j])
{
continue;
}
/* IP with in range */
range_p->touched++;
if (range_p->shared_net)
{
range_p->shared_net->touched++;
}
}
/* Size of range, shared net & all networks */
block_size = range_p->last_ip - range_p->first_ip - 1;
if (range_p->shared_net)
{
range_p->shared_net->available += block_size;
}
/* Reverse so that not even a one IP will be missed. */
i--;
j--;
range_p++;
}
/* During count of other shared networks default network and
* all networks got mixed to gether semantically. This fixes
* the problem, but is not elegant. TODO: fix semantics of all
* and default share_network. */
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 += range_p->last_ip - range_p->first_ip - 1;
shared_networks->used += range_p->count;
shared_networks->touched += range_p->touched;
range_p++;
}
return 0;
}

View file

@ -33,7 +33,7 @@
# define OUTPUT_FORMAT "text"
#endif
#ifndef OUTPUT_ORDER
# define OUTPUT_ORDER "i"
# define OUTPUT_ORDER 'i'
#endif
#ifndef OUTPUT_LIMIT
# define OUTPUT_LIMIT "77"

View file

@ -253,7 +253,7 @@ main (int argc, char **argv)
/* Do actual job */
prepare_memory ();
parse_config (config.dhcpdconf_file);
parse_config (config.dhcpdconf_file, shared_net_names, shared_net_names + strlen (shared_net_names) + 1, shared_networks);
parse_leases ();
prepare_data ();
do_counting ();

View file

@ -46,6 +46,7 @@ struct shared_network_t
char *name;
unsigned long int available;
unsigned long int used;
unsigned long int touched;
};
struct range_t
{
@ -53,14 +54,14 @@ struct range_t
unsigned long int first_ip;
unsigned long int last_ip;
unsigned long int count;
unsigned long int touched;
};
/* Global variables */
static int true = 1;
static int false = 0;
char *program_name;
static const float version_number = 2.5;
static const float version_number = 2.6;
struct configuration_t config;
static int output_limit_bit_1 = 1;
@ -77,10 +78,13 @@ unsigned int num_ranges;
unsigned long int *leases;
unsigned long int num_leases;
unsigned long int *touches;
unsigned long int num_touches;
/* Function prototypes */
int prepare_memory (void);
int parse_leases (void);
int parse_config (char *);
int parse_config (char *, char *, char *, struct shared_network_t *);
int nth_field (int n, char *dest, const char *src);
int prepare_data (void);
int do_counting (void);

View file

@ -58,7 +58,7 @@ parse_leases (void)
char *line, *ipstring;
struct in_addr inp;
struct stat lease_file_stats;
num_leases = 0;
num_touches = num_leases = 0;
dhcpd_leases = fopen (config.dhcpdlease_file, "r");
if (dhcpd_leases == NULL)
@ -80,6 +80,9 @@ parse_leases (void)
leases =
safe_malloc (sizeof (long int) *
((lease_file_stats.st_size / 250) + MAXLEN));
touches =
safe_malloc (sizeof (long int) *
((lease_file_stats.st_size / 250) + MAXLEN));
line = safe_malloc (sizeof (long int) * MAXLEN);
ipstring = safe_malloc (sizeof (long int) * MAXLEN);
@ -100,6 +103,13 @@ parse_leases (void)
leases[num_leases] = htonl (inp.s_addr);
num_leases++;
}
if (strstr (line, " binding state free"))
{
nth_field (2, ipstring, ipstring);
inet_aton (ipstring, &inp);
touches[num_touches] = htonl (inp.s_addr);
num_touches++;
}
}
return 0;
@ -141,23 +151,21 @@ nth_field (int n, char *dest, const char *src)
return 0;
}
/* UUTTA */
/* dhcpd.conf interesting words */
int
is_interesting_config_clause (char *s)
{
if (strstr (s, "range"))
if (strstr (s, "shared-network"))
{
return 1;
}
else if (strstr (s, "shared-network"))
else if (strstr (s, "range"))
{
return 2;
return 3;
}
else if (strstr (s, "include"))
{
return 3;
return 4;
}
else
{
@ -165,25 +173,27 @@ is_interesting_config_clause (char *s)
}
}
/* This function is far too long. */
int
parse_config (char *config_file)
parse_config (char *config_file, char *current_shared_name,
char *next_free_shared_name, struct shared_network_t *shared_p)
{
FILE *dhcpd_config;
int ret = 0, i = 0, newclause = 1, comment = 0, braces = 0;
int i = 0, newclause = 1, argument = 0, comment = 0, braces = 0, quote = 0;
char word[MAXLEN], c;
char *current_shared_name, *next_free_shared_name, *last_shared_name;
int braces_shared = 1000;
struct shared_network_t *shared_p;
struct in_addr inp;
struct range_t *range_p;
shared_p = shared_networks;
current_shared_name = shared_net_names;
next_free_shared_name = shared_net_names + strlen (shared_net_names) + 1;
char *last_shared_name;
last_shared_name = SHARED_NETWORKS_NAMES + shared_net_names;
/* Default place holder for ranges "All networks" */
/* Default place holder for ranges "All networks".
* If this is include file basicly nothing happens. */
shared_p->name = current_shared_name;
shared_p->available = 0;
shared_p->used = 0;
shared_p->touched = 0;
/* Open configuration file */
dhcpd_config = fopen (config_file, "r");
@ -193,61 +203,93 @@ parse_config (char *config_file)
exit (EXIT_FAILURE);
}
/* Parse file with a bit hairy style */
/* Hairy stuff begins. */
while (!feof (dhcpd_config))
{
c = fgetc (dhcpd_config);
/* Certain characters are magical */
switch (c)
{
/* Handle comments if they are not quoted */
case '#':
comment = 1;
if (quote == false)
{
comment = true;
}
continue;
case '"':
if (comment == false)
{
quote++;
/* Either one or zero */
quote = quote % 2;
}
continue;
case '\n':
comment = 0;
continue;
case ';':
if (comment == 0)
/* New line resets comment section, but not if quoted */
if (quote == false)
{
newclause = 1;
comment = false;
}
break;
case ';':
/* Quoted colon does not mean new clause */
if (quote == true)
{
break;
}
if (comment == false && argument != 2 && argument != 4)
{
newclause = true;
i = 0;
}
continue;
case '{':
if (comment == 0)
if (quote == true)
{
break;
}
if (comment == false)
{
braces++;
newclause = 1;
newclause = true;
}
continue;
case '}':
if (comment == 0)
if (quote == true)
{
break;
}
if (comment == false)
{
braces--;
/* End of shared-network */
if (braces_shared == braces)
{
current_shared_name = shared_net_names;
braces_shared = 1000;
shared_p = shared_networks;
}
newclause = 1;
/* Not literally true, but works for this program */
newclause = true;
}
continue;
default:
break;
}
/* Either inside comment or Nth word of clause. */
if (comment == 1 || newclause == 0)
if (comment == true || (newclause == false && argument == 0))
{
continue;
}
/* Strip white spaces before new clause word. */
if (newclause == 1 && isspace (c) && i == 0)
if ((newclause == true || argument != 0) && isspace (c) && i == false)
{
continue;
}
/* Save to word which clause this is. */
if (newclause == 1 && !isspace (c))
if ((newclause == true || argument != 0) && (!isspace (c) || quote == true))
{
word[i] = c;
i++;
@ -255,189 +297,95 @@ parse_config (char *config_file)
* this program is looking for are this long. */
if (i > MAXLEN)
{
newclause = 0;
newclause = false;
i = 0;
continue;
}
}
/* See if clause is something that parser is looking for. */
else
else if (newclause == true)
{
/* Insert string end & set state */
word[i] = '\0';
newclause = 0;
newclause = false;
i = 0;
ret = is_interesting_config_clause (word);
switch (ret)
argument = is_interesting_config_clause (word);
}
/* words after range, shared-network or include */
else if (argument != 0)
{
word[i] = '\0';
newclause = false;
i = 0;
switch (argument)
{
case 0:
/* printf ("nothing interesting: %s\n", word); */
argument = 0;
break;
case 1:
/* printf ("range %s\n", shared_p->name); */
save_range (dhcpd_config, shared_p);
break;
case 2:
/* printf("shared-network\n"); */
braces_shared = braces;
/* printf ("shared-network named: %s\n", word); */
strcpy (next_free_shared_name, word);
shared_p = shared_networks + num_shared_networks;
num_shared_networks++;
shared_p++;
save_shared_network (dhcpd_config, next_free_shared_name,
last_shared_name,
shared_networks + num_shared_networks);
current_shared_name = next_free_shared_name;
/* printf ("current name: %s \n", current_shared_name); */
next_free_shared_name += strlen (next_free_shared_name) + 1;
shared_p = shared_networks + num_shared_networks;
shared_p->name = next_free_shared_name;
shared_p->available = 0;
shared_p->used = 0;
shared_p->touched = 0;
/* Temporary abuse of argument variable */
argument = strlen (next_free_shared_name) + 1;
if (last_shared_name > next_free_shared_name + argument)
{
next_free_shared_name += argument;
}
else
{
/* TODO: make this go away by reallocationg more space. */
eprintf
("End of shared-network space, increase SHARED_NETWORKS_NAMES and recompile");
}
argument = 0;
break;
case 3:
/* printf ("include\n"); */
follow_include (dhcpd_config);
break;
default:
eprintf ("This cannot happen, report a bug!");
exit (EXIT_FAILURE);
}
}
}
// mitvit num_ranges--;
return 0;
}
int
save_range (FILE * dhcpd_config, char *shared_p)
{
char c, ipstr[17];
/* ip string index */
int i = 0;
/* white spaces before first IP detector */
int j = 0;
/* index is it first or second IP */
int k = 0;
/* wishful thingking that this could make performance better */
int space = 0;
struct in_addr inp;
struct range_t *range_p;
range_p = ranges + num_ranges;
while (!feof (dhcpd_config))
{
c = fgetc (dhcpd_config);
/* Avoid constantly running same syscall by saving result. */
space = isspace (c);
/* white spaces before first IP */
if (space != 0 && j == 0)
{
continue;
/* save IP string */
}
else if (space == 0)
{
ipstr[i] = c;
i++;
j = 1;
continue;
}
/* Put IP to structure where it will be analyzed. */
if ((space != 0) && i > 0)
{
ipstr[i] = '\0';
/* Remove possible trailing colon */
if (ipstr[i - 1] == ';')
{
ipstr[i - 1] = '\0';
}
/* Convert string to decimal */
inet_aton (ipstr, &inp);
if (k == 0)
{
range_p->first_ip = htonl (inp.s_addr) - 1;
}
else
{
case 2:
/* printf ("range 2nd ip: %s\n", word); */
range_p = ranges + num_ranges;
inet_aton (word, &inp);
argument = 0;
range_p->last_ip = htonl (inp.s_addr) + 1;
range_p->count = 0;
range_p->touched = 0;
range_p->shared_net = shared_p;
num_ranges++;
}
/* This needs to be convert to a dynamic memory engrowing. */
if (num_ranges > RANGES)
{
eprintf
("parse_config: Range space full! Increase RANGES and recompile.");
if (num_ranges > RANGES)
{
eprintf
("parse_config: Range space full! Increase RANGES and recompile.");
exit (EXIT_FAILURE);
}
newclause = true;
break;
case 3:
/* printf ("range 1nd ip: %s\n", word); */
range_p = ranges + num_ranges;
inet_aton (word, &inp);
range_p->first_ip = htonl (inp.s_addr) - 1;
argument = 2;
break;
case 4:
/* printf ("include file: %s\n", word); */
argument = 0;
parse_config (word, current_shared_name,
next_free_shared_name, shared_p);
newclause = true;
break;
default:
eprintf ("This cannot happpen, report a bug!");
exit (EXIT_FAILURE);
}
/* Reset IP string index and start looking for next one */
i = 0;
k++;
}
if (k > 1)
{
return 0;
}
}
eprintf ("This cannot happen, report a bug!");
exit (EXIT_FAILURE);
}
int
save_shared_network (FILE * dhcpd_config, char *name, char *last,
struct shared_network_t *shared_p)
{
char c;
/* Name in quotes must be saved with spaces */
int quoted = 0;
/* name string index */
int i = 0;
/* white spaces before name detector */
int j = 0;
/* wishful thingking that this could make performance better */
int space = 0;
while (!feof (dhcpd_config))
{
c = fgetc (dhcpd_config);
/* Avoid constantly running same syscall by saving result. */
space = isspace (c);
/* Skip initial white spaces */
if (space != 0 && j == 0)
{
continue;
}
if (c == '"')
{
quoted++;
j = 1;
continue;
}
if (space != 0 && quoted != 1)
{
if (&name[i] == last)
{
eprintf ("Shared network name space out of memory");
exit (1);
}
name[i] = '\0';
j = strlen (name);
break;
}
name[i] = c;
i++;
j = 1;
}
shared_p->name = name;
shared_p->available = 0;
shared_p->used = 0;
return 0;
}
int
follow_include (FILE * dhcpd_config)
{
return 0;
}

View file

@ -28,11 +28,6 @@
#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)
{
@ -64,7 +59,7 @@ output_txt (void)
fprintf (outfile, "Ranges:\n");
fprintf
(outfile,
"shared net name first ip last ip max cur percent\n");
"shared net name first ip last ip max cur percent touch t+c t+c perc\n");
}
if (config.output_limit[1] & output_limit_bit_1)
{
@ -82,12 +77,16 @@ output_txt (void)
fprintf (outfile, "not_defined ");
}
fprintf (outfile, "%-16s", inet_ntoa (first));
fprintf (outfile, " - %-16s %5lu %5lu %10.3f\n",
fprintf (outfile, " - %-16s %5lu %5lu %10.3f %5lu %5lu %9.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->first_ip - 1),
range_p->touched,
range_p->touched + range_p->count,
(float) (100 * (range_p->touched + range_p->count)) /
(range_p->last_ip - range_p->first_ip - 1));
range_p++;
}
}
@ -99,18 +98,23 @@ output_txt (void)
if (config.output_limit[0] & output_limit_bit_2)
{
fprintf (outfile, "Shared networks:\n");
fprintf (outfile, "name max cur percent\n");
fprintf (outfile,
"name max cur percent touch t+c t+c perc\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",
fprintf (outfile, "%-20s %5lu %5lu %10.3f %7lu %6lu %9.3f\n",
shared_p->name,
shared_p->available,
shared_p->used,
(float) (100 * shared_p->used) / shared_p->available);
(float) (100 * shared_p->used) / shared_p->available,
shared_p->touched,
shared_p->touched + shared_p->used,
(float) (100 * (shared_p->touched + shared_p->used)) /
shared_p->available);
}
}
if (config.output_limit[1] & output_limit_bit_2
@ -121,15 +125,22 @@ output_txt (void)
if (config.output_limit[0] & output_limit_bit_3)
{
fprintf (outfile, "Sum of all ranges:\n");
fprintf (outfile, "name max cur percent\n");
fprintf (outfile,
"name max cur percent touch t+c t+c perc\n");
}
if (config.output_limit[1] & output_limit_bit_3)
{
fprintf (outfile, "%-20s %5lu %5lu %10.3f\n",
fprintf (outfile, "%-20s %5lu %5lu %10.3f %7lu %6lu %9.3f\n",
shared_networks->name,
shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available,
shared_networks->touched,
shared_networks->touched + shared_networks->used,
(float) (100 *
(shared_networks->touched +
shared_networks->used)) /
shared_networks->available);
}
if (outfile == stdout)
@ -190,7 +201,7 @@ output_html (void)
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");
"<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><th align=\"right\">touch</th><th align=\"right\">t+c</th><th align=\"right\">t+c perc</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_1)
{
@ -209,11 +220,15 @@ output_html (void)
}
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",
"<td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</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->first_ip - 1),
range_p->touched,
range_p->touched + range_p->count,
(float) (100 * (range_p->touched + range_p->count)) /
(range_p->last_ip - range_p->first_ip - 1));
range_p++;
}
}
@ -221,7 +236,7 @@ output_html (void)
{
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");
"<tr><th>name</td><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th><th align=\"right\">touch</th><th align=\"right\">t+c</th><th align=\"right\">t+c perc</th></tr>\n");
}
if (config.output_limit[1] & output_limit_bit_2)
{
@ -229,24 +244,34 @@ output_html (void)
{
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",
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</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);
(float) (100 * shared_p->used) / shared_p->available,
shared_p->touched,
shared_p->touched + shared_p->used,
(float) (100 * (shared_p->touched + 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");
"<tr><th>name</th><th align=\"right\">max</th><th align=\"right\">cur</th><th align=\"right\">percent</th><th align=\"right\">touch</th><th align=\"right\">t+c</th><th align=\"right\">t+c perc</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",
"<tr><td>%s</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td><td align=\"right\">%lu</td><td align=\"right\">%lu</td><td align=\"right\">%.3f</td>\n",
shared_networks->name, shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available,
shared_networks->touched,
shared_networks->touched + shared_networks->used,
(float) (100 *
(shared_networks->touched +
shared_networks->used)) /
shared_networks->available);
}
fprintf (outfile, "</table>\n");
@ -305,7 +330,7 @@ output_csv (void)
fprintf (outfile, "\"Ranges:\"\n");
fprintf
(outfile,
"\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\"\n");
"\"shared net name\",\"first ip\",\"last ip\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"\n");
}
if (config.output_limit[1] & output_limit_bit_1)
{
@ -323,12 +348,15 @@ output_csv (void)
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,
fprintf (outfile,
"\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%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->first_ip - 1),
range_p->touched, range_p->touched + range_p->count,
(float) (100 * (range_p->touched + range_p->count)) /
(range_p->last_ip - range_p->first_ip - 1));
range_p++;
}
fprintf (outfile, "\n");
@ -336,7 +364,8 @@ output_csv (void)
if (config.output_limit[0] & output_limit_bit_2)
{
fprintf (outfile, "\"Shared networks:\"\n");
fprintf (outfile, "\"name\",\"max\",\"cur\",\"percent\"\n");
fprintf (outfile,
"\"name\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"\n");
}
if (config.output_limit[1] & output_limit_bit_2)
{
@ -344,27 +373,35 @@ output_csv (void)
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,
"\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_p->name, shared_p->available, shared_p->used,
(float) (100 * shared_p->used) / shared_p->available,
shared_p->touched + shared_p->used,
(float) (100 * (shared_p->touched + 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");
fprintf (outfile,
"\"name\",\"max\",\"cur\",\"percent\",\"touch\",\"t+c\",\"t+c perc\"\n");
}
if (config.output_limit[1] & output_limit_bit_3)
{
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_networks->name,
shared_networks->available,
fprintf (outfile,
"\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_networks->name, shared_networks->available,
shared_networks->used,
(float) (100 * shared_networks->used) /
shared_networks->available, shared_networks->touched,
shared_networks->touched + shared_networks->used,
(float) (100 *
(shared_networks->touched +
shared_networks->used)) /
shared_networks->available);
}
if (outfile == stdout)
@ -384,9 +421,8 @@ output_csv (void)
else
{
eprintf ("output_csv: stdout:");
exit (EXIT_FAILURE);
}
exit (EXIT_FAILURE);
}
return 0;
}