diff --git a/THANKS b/THANKS index 7a9ce82..ae23230 100644 --- a/THANKS +++ b/THANKS @@ -40,3 +40,4 @@ Derrick Lin Ivanov Ivan Manuel Hachtkemper Klaus Slott +Boris Lytochkin diff --git a/man/dhcpd-pools.1.in b/man/dhcpd-pools.1.in index 6b7a74b..8a55165 100644 --- a/man/dhcpd-pools.1.in +++ b/man/dhcpd-pools.1.in @@ -202,6 +202,10 @@ backup leases. This option is meaningful only in context of alarming and will print lots of data, if there are many networks. By default this option is not in use. .TP +\fB\-A\fR, \fB\-\-all\-as\-shared\fR +Treat all stand-alone subnets as shared-network with named formed from it's +CIDR. By default this option is not in use for backwards compatibility. +.TP \fB\-v\fR, \fB\-\-version\fR Print version information to standard output and exit successfully. .TP diff --git a/src/dhcpd-pools.c b/src/dhcpd-pools.c index 0d9718d..16d685e 100644 --- a/src/dhcpd-pools.c +++ b/src/dhcpd-pools.c @@ -129,6 +129,7 @@ int main(int argc, char **argv) {"crit-count", required_argument, NULL, OPT_CRIT_COUNT}, {"minsize", required_argument, NULL, OPT_MINSIZE}, {"perfdata", no_argument, NULL, 'p'}, + {"all-as-shared", no_argument, NULL, 'A'}, {NULL, 0, NULL, 0} }; @@ -161,12 +162,14 @@ int main(int argc, char **argv) /* Default sort order is by IPs small to big */ config.reverse_order = 0; config.backups_found = 0; + /* Treat single networks as shared with network CIDR as name */ + config.all_as_shared = 0; prepare_memory(); /* Parse command line options */ while (1) { int c; - c = getopt_long(argc, argv, "c:l:f:o:s:rL:pvh", long_options, &option_index); + c = getopt_long(argc, argv, "c:l:f:o:s:rL:pAvh", long_options, &option_index); if (c == EOF) break; switch (c) { @@ -241,6 +244,10 @@ int main(int argc, char **argv) /* Print additional performance data in alarming mode */ config.perfdata = 1; break; + case 'A': + /* Treat single networks as shared with network CIDR as name */ + config.all_as_shared = 1; + break; case 'v': /* Print version */ print_version(); diff --git a/src/dhcpd-pools.h b/src/dhcpd-pools.h index 5b2dbc7..53df74a 100644 --- a/src/dhcpd-pools.h +++ b/src/dhcpd-pools.h @@ -108,6 +108,7 @@ struct shared_network_t { double used; double touched; double backups; + int netmask; }; /*! \struct range_t * \brief Counters for an individual range. @@ -128,7 +129,9 @@ enum isc_conf_parser { ITS_A_RANGE_FIRST_IP, ITS_A_RANGE_SECOND_IP, ITS_A_SHAREDNET, - ITS_AN_INCLUCE + ITS_AN_INCLUCE, + ITS_A_SUBNET, + ITS_A_NETMASK }; /*! \enum ltype * \brief Lease state types. @@ -196,6 +199,7 @@ struct configuration_t { snet_alarms:1, print_mac_addreses:1, perfdata:1, + all_as_shared:1, header_limit:3, number_limit:3; }; diff --git a/src/getdata.c b/src/getdata.c index 2083440..995e1a9 100644 --- a/src/getdata.c +++ b/src/getdata.c @@ -153,6 +153,12 @@ static int is_interesting_config_clause(char const *restrict s) return ITS_A_RANGE_FIRST_IP; if (strstr(s, "shared-network")) return ITS_A_SHAREDNET; + if (config.all_as_shared) { + if (strstr(s, "subnet")) + return ITS_A_SUBNET; + if (strstr(s, "netmask")) + return ITS_A_NETMASK; + } if (strstr(s, "include")) return ITS_AN_INCLUCE; return ITS_NOTHING_INTERESTING; @@ -364,6 +370,12 @@ void parse_config(int is_include, const char *restrict config_file, argument = ITS_A_RANGE_SECOND_IP; break; case ITS_A_SHAREDNET: + case ITS_A_SUBNET: + /* ignore subnets inside a shared-network */ + if (argument == ITS_A_SUBNET && shared_p != shared_networks) { + argument = ITS_NOTHING_INTERESTING; + break; + } /* printf ("shared-network named: %s\n", word); */ num_shared_networks++; shared_p = shared_networks + num_shared_networks; @@ -372,10 +384,32 @@ void parse_config(int is_include, const char *restrict config_file, shared_p->used = 0; shared_p->touched = 0; shared_p->backups = 0; + shared_p->netmask = (argument == ITS_A_SUBNET ? -1 : 0); /* do not fill in netmask */ if (SHARED_NETWORKS < num_shared_networks + 2) /* FIXME: make this to go away by reallocating more space. */ error(EXIT_FAILURE, 0, "parse_config: increase default.h SHARED_NETWORKS and recompile"); + /* record network's mask too */ + if (argument == ITS_A_SUBNET) + newclause = 1; + argument = ITS_NOTHING_INTERESTING; + braces_shared = braces; + break; + case ITS_A_NETMASK: + /* fill in only when requested to do so */ + if (shared_p->netmask) { + if (!(parse_ipaddr(word, &addr))) + break; + shared_p->netmask = 32; + while ((addr.v4 & 0x01) == 0) { + addr.v4 >>= 1; + shared_p->netmask--; + } + snprintf(word, MAXLEN-1, "%s/%d", shared_p->name, shared_p->netmask); + if (shared_p->name) + free(shared_p->name); + shared_p->name = xstrdup(word); + } argument = ITS_NOTHING_INTERESTING; braces_shared = braces; break; diff --git a/src/other.c b/src/other.c index 5e54367..5794ccc 100644 --- a/src/other.c +++ b/src/other.c @@ -474,7 +474,8 @@ void __attribute__ ((__noreturn__)) usage(int status) fputs( " --crit-count=NR a number of free leases before critical raised\n", out); fputs( " --minsize=size disable alarms for small ranges and shared-nets\n", out); fputs( " --snet-alarms suppress range alarms that are part of a shared-net\n", out); - fputs( " -p --perfdata print additional perfdata in alarming mode\n", out); + fputs( " -p, --perfdata print additional perfdata in alarming mode\n", out); + fputs( " -A, --all-as-shared treat single subnets as shared-network with CIDR as their name\n", out); fputs( " -v, --version output version information and exit\n", out); fputs( " -h, --help display this help and exit\n", out); fputs( "\n", out);