diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..0bddd30 --- /dev/null +++ b/.gdb_history @@ -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 diff --git a/ChangeLog b/ChangeLog index d4117cc..7aeb5c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-05-10 Sami Kerola + * 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 * Release 2.5 * Reverse order for output sorting. diff --git a/NEWS b/NEWS index ea22ce0..b3396de 100644 --- a/NEWS +++ b/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: diff --git a/TODO b/TODO index ba466a4..9340b24 100644 --- a/TODO +++ b/TODO @@ -1,16 +1,25 @@ - + + * 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. - + diff --git a/configure b/configure index 9ecbae9..8f00c30 100755 --- a/configure +++ b/configure @@ -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 . # @@ -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'`\\" diff --git a/configure.in b/configure.in index 0e793e3..342965f 100644 --- a/configure.in +++ b/configure.in @@ -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]) diff --git a/man/dhcpd-pools.1 b/man/dhcpd-pools.1 index 3c70dd1..a4adfd7 100644 --- a/man/dhcpd-pools.1 +++ b/man/dhcpd-pools.1 @@ -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" diff --git a/mkinstalldirs b/mkinstalldirs deleted file mode 120000 index 953d98f..0000000 --- a/mkinstalldirs +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.6/mkinstalldirs \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 529e581..d043305 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -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; } diff --git a/src/defaults.h b/src/defaults.h index e543f04..f279d82 100644 --- a/src/defaults.h +++ b/src/defaults.h @@ -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" diff --git a/src/dhcpd-pools.c b/src/dhcpd-pools.c index 0acd70c..e45d763 100644 --- a/src/dhcpd-pools.c +++ b/src/dhcpd-pools.c @@ -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 (); diff --git a/src/dhcpd-pools.h b/src/dhcpd-pools.h index 53e2aad..13f9580 100644 --- a/src/dhcpd-pools.h +++ b/src/dhcpd-pools.h @@ -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); diff --git a/src/getdata.c b/src/getdata.c index 98b8a47..4ca2199 100644 --- a/src/getdata.c +++ b/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; } diff --git a/src/output.c b/src/output.c index 179335c..d9c6feb 100644 --- a/src/output.c +++ b/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, "Ranges:\n"); fprintf (outfile, - "shared net namefirst iplast ipmaxcurpercent\n"); + "shared net namefirst iplast ipmaxcurpercenttoucht+ct+c perc\n"); } if (config.output_limit[1] & output_limit_bit_1) { @@ -209,11 +220,15 @@ output_html (void) } fprintf (outfile, "%s", inet_ntoa (first)); fprintf (outfile, - "%s%lu%lu%.3f\n", + "%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++; } } @@ -221,7 +236,7 @@ output_html (void) { fprintf (outfile, "\nShared networks:\n"); fprintf (outfile, - "namemaxcurpercent\n"); + "namemaxcurpercenttoucht+ct+c perc\n"); } if (config.output_limit[1] & output_limit_bit_2) { @@ -229,24 +244,34 @@ output_html (void) { shared_p++; fprintf (outfile, - "%s%lu%lu%.3f\n", + "%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); + (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, "\nSum of all ranges:\n"); fprintf (outfile, - "namemaxcurpercent\n"); + "namemaxcurpercenttoucht+ct+c perc\n"); } if (config.output_limit[1] & output_limit_bit_3) { fprintf (outfile, - "%s%lu%lu%.3f\n", + "%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); } fprintf (outfile, "\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; }