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> 2008-05-05 Sami Kerola <kerolasa@iki.fi>
* Release 2.5 * Release 2.5
* Reverse order for output sorting. * 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. 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 Version 2.5
* Feature: * 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 * Bad english to good english translation in all files that
author has touched. Help needed! author has touched. Help needed!
* Count of touched IPs IE the ones which are leased some time and * Count of touched IPs IE the ones which are leased some time and
currently marked as free. Knowing number of these should currently marked as free. Knowing number of these should
give idea about possible peak value of reservations. Highly give idea about possible peak value of reservations. Highly
unscientific thou. 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) @ version 3.x (not coming soon)
* Configuration file for this command. * Configuration file for this command.
* Convert program to snmp subagent daemon. * Convert program to snmp subagent daemon.
* Analysis caching.
* Threshold values -> alarming possibility by snmp traps. * Threshold values -> alarming possibility by snmp traps.
</Todo state="Done"> </Todo>

20
configure vendored
View file

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

View file

@ -2,7 +2,7 @@
.\" http://www.iki.fi/kerolasa/ .\" http://www.iki.fi/kerolasa/
.\" kerolasa@iki.fi .\" 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 .SH NAME
dhcpd-pools \- ISC dhcp pools usage analysis dhcpd-pools \- ISC dhcp pools usage analysis
.SH SYNOPSIS .SH SYNOPSIS
@ -11,6 +11,35 @@ dhcpd-pools \- ISC dhcp pools usage analysis
.SH DESCRIPTION .SH DESCRIPTION
The program counts ISC dhcp shared network and pool usage The program counts ISC dhcp shared network and pool usage
analysis and outputs it in selected format. 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 .SH ARGUMENTS
.TP .TP
.I "\-c, \-\-config" .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; 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 */ /* Sort ranges */
qsort (ranges, (size_t) num_ranges, sizeof (struct range_t), &rangecomp); qsort (ranges, (size_t) num_ranges, sizeof (struct range_t), &rangecomp);
@ -57,41 +72,73 @@ int
do_counting (void) do_counting (void)
{ {
struct range_t *range_p; struct range_t *range_p;
unsigned int i, block_size; unsigned int i, j, k, block_size;
i = j = 0;
range_p = ranges; range_p = ranges;
for (i = 0; i < num_leases; i++) for (k = 0; k < num_ranges; k++)
{ {
/* IP with in range */ /* Count IPs in use */
if (range_p->first_ip < leases[i] && range_p->last_ip > leases[i]) 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++; range_p->count++;
if (range_p->shared_net) if (range_p->shared_net)
{ {
range_p->shared_net->used++; 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; return 0;
} }

View file

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

View file

@ -253,7 +253,7 @@ main (int argc, char **argv)
/* Do actual job */ /* Do actual job */
prepare_memory (); 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 (); parse_leases ();
prepare_data (); prepare_data ();
do_counting (); do_counting ();

View file

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

View file

@ -58,7 +58,7 @@ parse_leases (void)
char *line, *ipstring; char *line, *ipstring;
struct in_addr inp; struct in_addr inp;
struct stat lease_file_stats; struct stat lease_file_stats;
num_leases = 0; num_touches = num_leases = 0;
dhcpd_leases = fopen (config.dhcpdlease_file, "r"); dhcpd_leases = fopen (config.dhcpdlease_file, "r");
if (dhcpd_leases == NULL) if (dhcpd_leases == NULL)
@ -80,6 +80,9 @@ parse_leases (void)
leases = leases =
safe_malloc (sizeof (long int) * safe_malloc (sizeof (long int) *
((lease_file_stats.st_size / 250) + MAXLEN)); ((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); line = safe_malloc (sizeof (long int) * MAXLEN);
ipstring = 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); leases[num_leases] = htonl (inp.s_addr);
num_leases++; 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; return 0;
@ -141,23 +151,21 @@ nth_field (int n, char *dest, const char *src)
return 0; return 0;
} }
/* UUTTA */
/* dhcpd.conf interesting words */ /* dhcpd.conf interesting words */
int int
is_interesting_config_clause (char *s) is_interesting_config_clause (char *s)
{ {
if (strstr (s, "range")) if (strstr (s, "shared-network"))
{ {
return 1; return 1;
} }
else if (strstr (s, "shared-network")) else if (strstr (s, "range"))
{ {
return 2; return 3;
} }
else if (strstr (s, "include")) else if (strstr (s, "include"))
{ {
return 3; return 4;
} }
else else
{ {
@ -165,25 +173,27 @@ is_interesting_config_clause (char *s)
} }
} }
/* This function is far too long. */
int 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; 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 word[MAXLEN], c;
char *current_shared_name, *next_free_shared_name, *last_shared_name;
int braces_shared = 1000; int braces_shared = 1000;
struct shared_network_t *shared_p; struct in_addr inp;
struct range_t *range_p;
shared_p = shared_networks; char *last_shared_name;
current_shared_name = shared_net_names;
next_free_shared_name = shared_net_names + strlen (shared_net_names) + 1;
last_shared_name = SHARED_NETWORKS_NAMES + shared_net_names; 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->name = current_shared_name;
shared_p->available = 0; shared_p->available = 0;
shared_p->used = 0; shared_p->used = 0;
shared_p->touched = 0;
/* Open configuration file */ /* Open configuration file */
dhcpd_config = fopen (config_file, "r"); dhcpd_config = fopen (config_file, "r");
@ -193,61 +203,93 @@ parse_config (char *config_file)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
/* Parse file with a bit hairy style */ /* Hairy stuff begins. */
while (!feof (dhcpd_config)) while (!feof (dhcpd_config))
{ {
c = fgetc (dhcpd_config); c = fgetc (dhcpd_config);
/* Certain characters are magical */ /* Certain characters are magical */
switch (c) switch (c)
{ {
/* Handle comments if they are not quoted */
case '#': case '#':
comment = 1; if (quote == false)
{
comment = true;
}
continue;
case '"':
if (comment == false)
{
quote++;
/* Either one or zero */
quote = quote % 2;
}
continue; continue;
case '\n': case '\n':
comment = 0; /* New line resets comment section, but not if quoted */
continue; if (quote == false)
case ';':
if (comment == 0)
{ {
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; i = 0;
} }
continue; continue;
case '{': case '{':
if (comment == 0) if (quote == true)
{
break;
}
if (comment == false)
{ {
braces++; braces++;
newclause = 1; newclause = true;
} }
continue; continue;
case '}': case '}':
if (comment == 0) if (quote == true)
{
break;
}
if (comment == false)
{ {
braces--; braces--;
/* End of shared-network */
if (braces_shared == braces) if (braces_shared == braces)
{ {
current_shared_name = shared_net_names; current_shared_name = shared_net_names;
braces_shared = 1000; braces_shared = 1000;
shared_p = shared_networks; shared_p = shared_networks;
} }
newclause = 1; /* Not literally true, but works for this program */
newclause = true;
} }
continue; continue;
default: default:
break; break;
} }
/* Either inside comment or Nth word of clause. */ /* Either inside comment or Nth word of clause. */
if (comment == 1 || newclause == 0) if (comment == true || (newclause == false && argument == 0))
{ {
continue; continue;
} }
/* Strip white spaces before new clause word. */ /* Strip white spaces before new clause word. */
if (newclause == 1 && isspace (c) && i == 0) if ((newclause == true || argument != 0) && isspace (c) && i == false)
{ {
continue; continue;
} }
/* Save to word which clause this is. */ /* Save to word which clause this is. */
if (newclause == 1 && !isspace (c)) if ((newclause == true || argument != 0) && (!isspace (c) || quote == true))
{ {
word[i] = c; word[i] = c;
i++; i++;
@ -255,189 +297,95 @@ parse_config (char *config_file)
* this program is looking for are this long. */ * this program is looking for are this long. */
if (i > MAXLEN) if (i > MAXLEN)
{ {
newclause = 0; newclause = false;
i = 0; i = 0;
continue; continue;
} }
} }
/* See if clause is something that parser is looking for. */ /* See if clause is something that parser is looking for. */
else else if (newclause == true)
{ {
/* Insert string end & set state */ /* Insert string end & set state */
word[i] = '\0'; word[i] = '\0';
newclause = 0; newclause = false;
i = 0; i = 0;
ret = is_interesting_config_clause (word); argument = is_interesting_config_clause (word);
switch (ret) }
/* words after range, shared-network or include */
else if (argument != 0)
{
word[i] = '\0';
newclause = false;
i = 0;
switch (argument)
{ {
case 0: case 0:
/* printf ("nothing interesting: %s\n", word); */ /* printf ("nothing interesting: %s\n", word); */
argument = 0;
break; break;
case 1: case 1:
/* printf ("range %s\n", shared_p->name); */ /* printf ("shared-network named: %s\n", word); */
save_range (dhcpd_config, shared_p); strcpy (next_free_shared_name, word);
break; shared_p = shared_networks + num_shared_networks;
case 2:
/* printf("shared-network\n"); */
braces_shared = braces;
num_shared_networks++; num_shared_networks++;
shared_p++; shared_p++;
save_shared_network (dhcpd_config, next_free_shared_name, shared_p->name = next_free_shared_name;
last_shared_name, shared_p->available = 0;
shared_networks + num_shared_networks); shared_p->used = 0;
current_shared_name = next_free_shared_name; shared_p->touched = 0;
/* printf ("current name: %s \n", current_shared_name); */ /* Temporary abuse of argument variable */
next_free_shared_name += strlen (next_free_shared_name) + 1; argument = strlen (next_free_shared_name) + 1;
shared_p = shared_networks + num_shared_networks; 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; break;
case 3: case 2:
/* printf ("include\n"); */ /* printf ("range 2nd ip: %s\n", word); */
follow_include (dhcpd_config); range_p = ranges + num_ranges;
break; inet_aton (word, &inp);
default: argument = 0;
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
{
range_p->last_ip = htonl (inp.s_addr) + 1; range_p->last_ip = htonl (inp.s_addr) + 1;
range_p->count = 0; range_p->count = 0;
range_p->touched = 0;
range_p->shared_net = shared_p; range_p->shared_net = shared_p;
num_ranges++; num_ranges++;
} if (num_ranges > RANGES)
{
/* This needs to be convert to a dynamic memory engrowing. */ eprintf
if (num_ranges > RANGES) ("parse_config: Range space full! Increase RANGES and recompile.");
{ exit (EXIT_FAILURE);
eprintf }
("parse_config: Range space full! Increase RANGES and recompile."); 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); 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; return 0;
} }

View file

@ -28,11 +28,6 @@
#include "dhcpd-pools.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 int
output_txt (void) output_txt (void)
{ {
@ -64,7 +59,7 @@ output_txt (void)
fprintf (outfile, "Ranges:\n"); fprintf (outfile, "Ranges:\n");
fprintf fprintf
(outfile, (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) if (config.output_limit[1] & output_limit_bit_1)
{ {
@ -82,12 +77,16 @@ output_txt (void)
fprintf (outfile, "not_defined "); fprintf (outfile, "not_defined ");
} }
fprintf (outfile, "%-16s", inet_ntoa (first)); 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), inet_ntoa (last),
range_p->last_ip - range_p->first_ip - 1, range_p->last_ip - range_p->first_ip - 1,
range_p->count, range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip - (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++; range_p++;
} }
} }
@ -99,18 +98,23 @@ output_txt (void)
if (config.output_limit[0] & output_limit_bit_2) if (config.output_limit[0] & output_limit_bit_2)
{ {
fprintf (outfile, "Shared networks:\n"); 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) if (config.output_limit[1] & output_limit_bit_2)
{ {
for (i = 0; i < num_shared_networks; i++) for (i = 0; i < num_shared_networks; i++)
{ {
shared_p++; 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->name,
shared_p->available, shared_p->available,
shared_p->used, 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 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) if (config.output_limit[0] & output_limit_bit_3)
{ {
fprintf (outfile, "Sum of all ranges:\n"); 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) 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->name,
shared_networks->available, shared_networks->available,
shared_networks->used, shared_networks->used,
(float) (100 * 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); shared_networks->available);
} }
if (outfile == stdout) if (outfile == stdout)
@ -190,7 +201,7 @@ output_html (void)
fprintf (outfile, "<tr><th>Ranges:</th></tr>\n"); fprintf (outfile, "<tr><th>Ranges:</th></tr>\n");
fprintf fprintf
(outfile, (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) 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>", inet_ntoa (first));
fprintf (outfile, 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, inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1,
range_p->count, range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip - (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++; range_p++;
} }
} }
@ -221,7 +236,7 @@ output_html (void)
{ {
fprintf (outfile, "\n<tr><th>Shared networks:</th></tr>\n"); fprintf (outfile, "\n<tr><th>Shared networks:</th></tr>\n");
fprintf (outfile, 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) if (config.output_limit[1] & output_limit_bit_2)
{ {
@ -229,24 +244,34 @@ output_html (void)
{ {
shared_p++; shared_p++;
fprintf (outfile, 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, 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) if (config.output_limit[0] & output_limit_bit_3)
{ {
fprintf (outfile, "\n<tr><th>Sum of all ranges:</th></tr>\n"); fprintf (outfile, "\n<tr><th>Sum of all ranges:</th></tr>\n");
fprintf (outfile, 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) if (config.output_limit[1] & output_limit_bit_3)
{ {
fprintf (outfile, 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->name, shared_networks->available,
shared_networks->used, shared_networks->used,
(float) (100 * 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); shared_networks->available);
} }
fprintf (outfile, "</table>\n"); fprintf (outfile, "</table>\n");
@ -305,7 +330,7 @@ output_csv (void)
fprintf (outfile, "\"Ranges:\"\n"); fprintf (outfile, "\"Ranges:\"\n");
fprintf fprintf
(outfile, (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) if (config.output_limit[1] & output_limit_bit_1)
{ {
@ -323,12 +348,15 @@ output_csv (void)
fprintf (outfile, "\"not_defined\","); fprintf (outfile, "\"not_defined\",");
} }
fprintf (outfile, "\"%s\",", inet_ntoa (first)); fprintf (outfile, "\"%s\",", inet_ntoa (first));
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", fprintf (outfile,
inet_ntoa (last), "\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"\n",
range_p->last_ip - range_p->first_ip - 1, inet_ntoa (last), range_p->last_ip - range_p->first_ip - 1,
range_p->count, range_p->count,
(float) (100 * range_p->count) / (range_p->last_ip - (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++; range_p++;
} }
fprintf (outfile, "\n"); fprintf (outfile, "\n");
@ -336,7 +364,8 @@ output_csv (void)
if (config.output_limit[0] & output_limit_bit_2) if (config.output_limit[0] & output_limit_bit_2)
{ {
fprintf (outfile, "\"Shared networks:\"\n"); 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) if (config.output_limit[1] & output_limit_bit_2)
{ {
@ -344,27 +373,35 @@ output_csv (void)
for (i = 0; i < num_shared_networks; i++) for (i = 0; i < num_shared_networks; i++)
{ {
shared_p++; shared_p++;
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", fprintf (outfile,
shared_p->name, "\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_p->available, shared_p->name, shared_p->available, shared_p->used,
shared_p->used, (float) (100 * shared_p->used) / shared_p->available,
(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"); fprintf (outfile, "\n");
} }
if (config.output_limit[0] & output_limit_bit_3) if (config.output_limit[0] & output_limit_bit_3)
{ {
fprintf (outfile, "\"Sum of all ranges:\"\n"); 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) if (config.output_limit[1] & output_limit_bit_3)
{ {
fprintf (outfile, "\"%s\",\"%lu\",\"%lu\",\"%.3f\"\n", fprintf (outfile,
shared_networks->name, "\"%s\",\"%lu\",\"%lu\",\"%.3f\",\"%lu\",\"%lu\",\"%.3f\"\n",
shared_networks->available, shared_networks->name, shared_networks->available,
shared_networks->used, shared_networks->used,
(float) (100 * 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); shared_networks->available);
} }
if (outfile == stdout) if (outfile == stdout)
@ -384,9 +421,8 @@ output_csv (void)
else else
{ {
eprintf ("output_csv: stdout:"); eprintf ("output_csv: stdout:");
exit (EXIT_FAILURE);
} }
exit (EXIT_FAILURE);
} }
return 0; return 0;
} }