mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +00:00
Version 2.6
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
8904b5b82c
commit
4f000e7ab6
14 changed files with 374 additions and 268 deletions
22
.gdb_history
Normal file
22
.gdb_history
Normal 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
|
||||
|
|
@ -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
6
NEWS
|
|
@ -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
13
TODO
|
|
@ -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
20
configure
vendored
|
|
@ -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'`\\"
|
||||
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/usr/share/automake-1.6/mkinstalldirs
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
322
src/getdata.c
322
src/getdata.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
112
src/output.c
112
src/output.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue