docs: add doxygen tags, configuration file, and autotooling

When ./configure --enable-doxygen is used one can browse internal api
documentation from docs/html directory.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2012-12-09 01:25:04 +00:00
parent aa7928b3ab
commit 3471c91796
15 changed files with 2254 additions and 26 deletions

View file

@ -5,3 +5,7 @@ ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = m4/gnulib-cache.m4
SUBDIRS = lib src man tests contrib
if ENABLE_DOXYGEN
SUBDIRS += doc
endif

View file

@ -118,6 +118,26 @@ AC_ARG_WITH([critical],
AC_DEFINE_UNQUOTED([ALARM_CRIT], [$critical_percent], [monitoring critical default])
AC_SUBST([ALARM_CRIT], [$critical_percent])
AC_ARG_ENABLE([doxygen],
AC_HELP_STRING([--enable-doxygen], [build internal api documentation @<:@default=disabled@:>@]),
[], [enable_doxygen=no])
AM_CONDITIONAL([ENABLE_DOXYGEN], [test "x$enable_doxygen" = "xyes"])
AS_IF([test x$enable_doxygen = xyes], [
AC_CHECK_PROGS([DOXYGEN], [doxygen])
AS_IF([test "x$DOXYGEN" = "x"],
AC_MSG_ERROR([doxygen not in path]),
AC_CONFIG_FILES([doc/Makefile doc/doxy.conf])
)
AC_CHECK_PROGS([DOXYGEN_DOT], [dot])
AS_IF([test "x$DOXYGEN" = "x"],
AC_MSG_WARN([dot not in path, internal documentation graphs are not generated])
)
])
AM_CONDITIONAL([HAVE_DOXYGEN], [test "x$DOXYGEN" != "x"])
AM_CONDITIONAL([HAVE_DOXYGEN_DOT], [test "x$DOXYGEN_DOT" != "x"])
AC_CONFIG_FILES([
Makefile
lib/Makefile

5
doc/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
/Makefile
/Makefile.in
/doxy.conf
/doxyfile.stamp
/html

18
doc/Makefile.am Normal file
View file

@ -0,0 +1,18 @@
EXTRA_DIST = doxy.conf.in introduction.dox
if ENABLE_DOXYGEN
doxyfile.stamp:
$(DOXYGEN) doxy.conf
date > doxyfile.stamp
CLEANFILES = doxyfile.stamp
all-local: doxyfile.stamp
clean-local: clean-local-check
.PHONY: clean-local-check
clean-local-check:
-rm -rf html
endif

1808
doc/doxy.conf.in Normal file

File diff suppressed because it is too large Load diff

49
doc/introduction.dox Normal file
View file

@ -0,0 +1,49 @@
/*!
@mainpage
@section introduction Introduction
This is dhcpd-pools ISC dhcp shared network and pool range usage
analysis. Purpose of command is to count usage ratio of each IP range
and shared network pool which ISC dhcpd is in control of. Users of the
command are most likely ISPs and other organizations that have large IP
space.
Program is written C. Design goal is to get analysis done quickly where
there is lots of data. On cheap laptop the speed of analysis is roughly
100k leases per second. Number of ranges, or shared networks, does not
make any significant difference in getting analysis done.
@section main-copyright Copyright Policy
The dhcpd-pools has BSD 2-clause license which also known as "Simplified
BSD License" or "FreeBSD License".
Copyright 2006- Sami Kerola. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are
those of the authors and should not be interpreted as representing
official policies, either expressed or implied, of Sami Kerola.
*/

View file

@ -33,6 +33,10 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file analyze.c
* \brief Data analysis functions.
*/
#include <config.h>
#include <stddef.h>
@ -41,9 +45,10 @@
#include "dhcpd-pools.h"
/* Clean up data */
int prepare_data(void)
{
/*! \brief Prepare data for analysis. The function will sort leases and
* ranges.
* FIXME: This function should return void. */
int prepare_data(void) {
/* Sort leases */
HASH_SORT(leases, leasecomp);
/* Sort ranges */
@ -51,7 +56,8 @@ int prepare_data(void)
return 0;
}
/* Join leases and ranges into counter structs */
/*! \brief Perform counting. Join leases with ranges, and update counters.
* FIXME: This function should return void. */
int do_counting(void)
{
struct range_t *restrict range_p;
@ -110,9 +116,10 @@ int do_counting(void)
range_p++;
}
/* FIXME: During count of other shared networks default network and
* all networks got mixed together semantically. This fixes the
* problem, but is not elegant. */
/* FIXME: During count of other shared networks default network
* and all networks got mixed together semantically. The below
* fixes the problem, but is not elegant. */
shared_networks->available = 0;
shared_networks->used = 0;
shared_networks->touched = 0;

View file

@ -33,16 +33,26 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file defaults.h
* \brief Default settings which cannot be changed without recompiling
* the software.
*/
#ifndef DEFAULTS_H
# define DEFAULTS_H 1
/* Maximum line length in dhcpd.conf and dhcpd.leases */
/*! \var MAXLEN
* \brief Maximum expected line length in dhcpd.conf and dhcpd.leases
* files. */
static const size_t MAXLEN = 1024;
/* Maximum number of shared networks */
/*! \var SHARED_NETWORKS
* \brief Maximum number of different shared networks in dhcpd.conf file. */
static const unsigned int SHARED_NETWORKS = 8192;
/* Maximum number of ranges */
/*! \var RANGES
* \brief Maximum number of ranges
* \xrefitem FIXME RANGES "Move this variable to dhcpd-pools.h"*/
unsigned int RANGES;
#endif /* DEFAULTS_H */

View file

@ -33,6 +33,10 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file dhcpd-pools.c
* \brief The main(), and core initialization.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
@ -49,6 +53,16 @@
#include "dhcpd-pools.h"
#include "xalloc.h"
/*! \brief Start of execution. Parse options, and call other other
* functions one after another. At the moment adding threading support
* would be difficult, but there does not seem to be valid reason to
* consider that. Overall the analysis already quick enough even without
* making it parallel.
*
* \return Return value indicates success or fail or analysis, unless
* either --warning or --critical options are in use, which makes the
* return value in some cases to match with Nagios expectations about
* alarming. */
int main(int argc, char **argv)
{
int i, c, sorts = 0;
@ -79,7 +93,8 @@ int main(int argc, char **argv)
atexit(close_stdout);
/* FIXME: make these allocations dynamic up on need. */
/* FIXME: These allocations should be fully dynamic, e.g., grow
* if needed. */
config.dhcpdconf_file = xmalloc(sizeof(char) * MAXLEN);
config.dhcpdlease_file = xmalloc(sizeof(char) * MAXLEN);
config.output_file = xmalloc(sizeof(char) * MAXLEN);
@ -242,7 +257,9 @@ int main(int argc, char **argv)
return (ret_val);
}
/* Global allocations, counter resets etc */
/*! \brief Run time initialization. Global allocations, counter
* initializations, etc are here.
* FIXME: This function should return void. */
int prepare_memory(void)
{
/* Fill in prefix length cache */

View file

@ -33,6 +33,12 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file dhcpd-pools.h
* \brief Global definitions of structures, enums, and function prototypes.
* FIXME: The file has too many global variables. Most of them should be
* removed, if not all.
*/
#ifndef DHCPD_POOLS_H
# define DHCPD_POOLS_H 1
@ -43,6 +49,12 @@
# include <string.h>
# include <uthash.h>
/*! \def likely(x)
* \brief Symbolic call to __builtin_expect'ed branch.
*/
/*! \def unlikely(x)
* \brief Symbolic call to not-__builtin_expect'ed branch.
*/
# ifdef HAVE_BUILTIN_EXPECT
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
@ -51,16 +63,24 @@
# define unlikely(x) (x)
# endif
/* Structures and unions */
/*! \union ipaddr_t
* \brief Memory space for a binary IP address saving. */
union ipaddr_t {
uint32_t v4;
unsigned char v6[16];
};
/*! \enum dhcp_version
* \brief Indicator which IP version is in use.
*/
enum dhcp_version {
VERSION_4,
VERSION_6,
VERSION_UNKNOWN,
};
/*! \enum prefix_t
* \brief Enumeration of interesting data in dhcpd.leases file, that has
* to be further examined, and saved.
*/
enum prefix_t {
PREFIX_LEASE,
PREFIX_BINDING_STATE_FREE,
@ -69,7 +89,9 @@ enum prefix_t {
PREFIX_HARDWARE_ETHERNET,
NUM_OF_PREFIX
};
/*! \struct configuration_t
* \brief Runtime configuration.
*/
struct configuration_t {
char dhcpv6;
char *dhcpdconf_file;
@ -82,6 +104,9 @@ struct configuration_t {
double warning;
double critical;
};
/*! \struct shared_network_t
* \brief Counters for an individual shared network.
*/
struct shared_network_t {
char *name;
unsigned long int available;
@ -89,6 +114,9 @@ struct shared_network_t {
unsigned long int touched;
unsigned long int backups;
};
/*! \struct range_t
* \brief Counters for an individual range.
*/
struct range_t {
struct shared_network_t *shared_net;
union ipaddr_t first_ip;
@ -97,11 +125,17 @@ struct range_t {
unsigned long int touched;
unsigned long int backups;
};
/*! \enum ltype
* \brief Lease state types.
*/
enum ltype {
ACTIVE,
FREE,
BACKUP
};
/*! \struct leases_t
* \brief An individual lease. The leaases are hashed.
*/
struct leases_t {
union ipaddr_t ip; /* ip as key */
enum ltype type;
@ -110,21 +144,40 @@ struct leases_t {
};
/* Global variables */
/* \var prefixes An array holding dhcpd.leases lines that are wanted to examine.*/
const char *prefixes[2][NUM_OF_PREFIX];
/* \var prefix_length Length of each prefix. */
int prefix_length[2][NUM_OF_PREFIX];
/* \var config Runtime configuration. */
struct configuration_t config;
/* \var dhcp_version Version of IP in use.
* FIXME: move to runtime configuration. */
enum dhcp_version dhcp_version;
/* \var output_limit_bit_1 Bit mask what is printed.
* FIXME: These should probably be enum with hex assignments. */
static int const output_limit_bit_1 = 1;
/* \var output_limit_bit_2 See output_limit_bit_1 */
static int const output_limit_bit_2 = 2;
/* \var output_limit_bit_3 see output_limit_bit_1 */
static int const output_limit_bit_3 = 4;
/* \var fullhtml Setting if full html is been requested by user.
* FIXME: move to config. */
unsigned int fullhtml;
/* \var shared_networks Pointer holding shared network count results. */
struct shared_network_t *shared_networks;
/* \var num_shared_networks Number of shared networks found. */
unsigned int num_shared_networks;
/* \var ranges Pointer holding range count results. */
struct range_t *ranges;
/* \var num_ranges Number of ranges found. */
unsigned int num_ranges;
/* \var leases Pointer holding all leases. */
struct leases_t *leases;
/* \var num_leases FIXME: not in use, remove */
unsigned long int num_leases;
/* \var num_touches FIXME: not in use, remove */
unsigned long int num_touches;
/* \var num_backups FIXME: not in use, remove */
unsigned long int num_backups;
/* Function prototypes */

View file

@ -33,6 +33,10 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file getdata.c
* \brief Functions to read data from dhcpd.conf and dhcdp.leases files.
*/
#include <config.h>
#include <arpa/inet.h>
@ -53,8 +57,13 @@
#include "dhcpd-pools.h"
#include "xalloc.h"
/* The .indent.pro in use will mess formatting of array below. Please do
* not commit less readable indentation. */
/*! \var prefixes[2][NUM_OF_PREFIX]
* \brief ISC lease file formats for IPv4 and IPv6.
*
* The .indent.pro in use will mess formatting of array below.
* Please do not commit less readable indentation.
*
* FIXME: The prefixes should be moved to defaults.h */
const char *prefixes[2][NUM_OF_PREFIX] = {
[VERSION_4] = {
[PREFIX_LEASE] = "lease ",
@ -72,10 +81,15 @@ const char *prefixes[2][NUM_OF_PREFIX] = {
}
};
/*! \var prefix_length[2][NUM_OF_PREFIX]
* \brief Expected configuration string length, that varies for IPv4 and
* IPv6. See also prefixes.
*
* FIXME: The prefix_length should be moved to dhcpd-pools.h */
int prefix_length[2][NUM_OF_PREFIX] = { };
/* Parse dhcpd.leases file. All performance boosts for this function are
* welcome */
/*! \brief Lease file parser. The parser can only read ISC DHCPD
* dhcpd.leases file format. */
int parse_leases(void)
{
FILE *dhcpd_leases;
@ -124,6 +138,12 @@ int parse_leases(void)
const char **p = prefixes[dhcp_version];
int *l = prefix_length[dhcp_version];
/*! \def HAS_PREFIX(line, type)
* \brief A macro to match IPv4 and IPv6 lease lines.
*
* FIXME: This macro should have better name. The HAS_PREFIX sounds like
* some sort of prefix length test. */
#define HAS_PREFIX(line, type) xstrstr((line), p[type], l[type])
while (!feof(dhcpd_leases)) {
@ -177,7 +197,10 @@ int parse_leases(void)
return 0;
}
/* Like strcpy but for field which is separated by white spaces. */
/*! \brief A version of strcpy, but for a white space separated field.
* \param dest String copy destination.
* \param src String copy source.
*/
void nth_field(char *restrict dest, const char *restrict src)
{
size_t i, len;
@ -191,7 +214,11 @@ void nth_field(char *restrict dest, const char *restrict src)
}
}
/* dhcpd.conf interesting words */
/*! \brief Keyword search in dhcpd.conf file.
* \param s A line from the dhcpd.conf file.
* \return Indicator what configuration was found.
* FIXME: This function should return enum type.
*/
static int is_interesting_config_clause(char const *restrict s)
{
if (strstr(s, "range"))
@ -203,7 +230,10 @@ static int is_interesting_config_clause(char const *restrict s)
return 0;
}
/* FIXME: This spaghetti monster function need to be rewrote at least ones. */
/*! \brief The dhcpd.conf file parser.
* FIXME: This spaghetti monster function need to be rewrote at least
* ones.
*/
void parse_config(int is_include, const char *restrict config_file,
struct shared_network_t *restrict shared_p)
{

View file

@ -33,12 +33,20 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file hash.c
* \brief The leases hash functions. The hash sorting is key to make
* analysis happen as quick as possible..
*/
#include "dhcpd-pools.h"
#include "xalloc.h"
#define HASH_FIND_V6(head, findv6, out) HASH_FIND(hh, head, findv6, 16, out)
#define HASH_ADD_V6(head, v6field, add) HASH_ADD(hh, head, v6field, 16, add)
/*! \brief Add a lease to hash array.
* \param addr Binary IP to be added in leases hash.
* \param type Lease state of the IP. */
void add_lease(union ipaddr_t *addr, enum ltype type)
{
struct leases_t *l;
@ -53,6 +61,10 @@ void add_lease(union ipaddr_t *addr, enum ltype type)
l->ethernet = NULL;
}
/*! \brief Find pointer to lease from hash array.
* \param addr Binary IP searched from leases hash.
* \return A lease structure about requested IP, or NULL.
*/
struct leases_t *find_lease(union ipaddr_t *addr)
{
struct leases_t *l;
@ -65,6 +77,8 @@ struct leases_t *find_lease(union ipaddr_t *addr)
return l;
}
/*! \brief Delete a lease from hash array.
* \param lease Pointer to lease hash. */
void delete_lease(struct leases_t *lease)
{
if (lease->ethernet != NULL)
@ -84,6 +98,11 @@ void delete_all_leases()
}
*/
/*! \brief Delete all leases from hash array.
* FIXME: The prototype should have (void) as an argument.
* FIXME: Take the HASH_ITER + HASH_DEL in use by if uthash version
* allows it.
*/
void delete_all_leases()
{
struct leases_t *l;

View file

@ -33,6 +33,10 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file other.c
* \brief Collection of various functions.
*/
#include <config.h>
#include "dhcpd-pools.h"
@ -47,6 +51,11 @@
#include <unistd.h>
#include <limits.h>
/*! \brief Convert text string IP address from either IPv4 or IPv6 to an integer.
* \param src An IP string in either format.
* \param dst An union which will hold conversion result.
* \return Was parsing successful.
*/
int parse_ipaddr(const char *restrict src, union ipaddr_t *restrict dst)
{
int rv;
@ -73,6 +82,10 @@ int parse_ipaddr(const char *restrict src, union ipaddr_t *restrict dst)
return rv == 1;
}
/*! \brief Copy IP address to union.
*
* \param dst Destination for a binary IP address.
* \param src Sourse of an IP address. */
void copy_ipaddr(union ipaddr_t *restrict dst,
const union ipaddr_t *restrict src)
{
@ -83,6 +96,14 @@ void copy_ipaddr(union ipaddr_t *restrict dst,
}
}
/*! \brief Convert an address to string. This function will convert the
* IPv4 addresses to 123.45.65.78 format, and the IPv6 addresses to it's
* native format depending on which version of the addressing is found to
* be in use.
*
* \param ip Binary IP address.
* \return Printable address.
*/
const char *ntop_ipaddr(const union ipaddr_t *ip)
{
static char
@ -98,6 +119,12 @@ const char *ntop_ipaddr(const union ipaddr_t *ip)
}
}
/*! \brief Calculate how many addresses there are in a range.
*
* \param r Pointer to range structure, which has information about first
* and last IP in the range.
* \return Size of a range.
*/
unsigned long get_range_size(const struct range_t *r)
{
if (dhcp_version == VERSION_6) {
@ -117,6 +144,15 @@ unsigned long get_range_size(const struct range_t *r)
}
}
/*! \fn xstrstr(const char *restrict a, const char *restrict b, const int len)
* \brief Compare two strings. Similar to strcmp, but tuned to be
* quicker which is possible because input data is known to have certain
* structure.
*
* \param a String which is been compared, e.g., a haystack.
* \param b Constant string which is hoped to found, e.g., a needle.
* \param len Stop point in characters when comparison must be ended.
* \return Zero if strings differ, one if they are the same. */
int
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
__attribute__ ((hot))
@ -143,7 +179,12 @@ int
return true;
}
/* Return percentage value */
/*! \brief Return a double floating point value.
*
* \param str String to be converted to a double.
* \param errmesg Exit error message if conversion fails.
* \return Binary result of string to double conversion.
*/
double strtod_or_err(const char *restrict str, const char *restrict errmesg)
{
double num;
@ -165,6 +206,13 @@ double strtod_or_err(const char *restrict str, const char *restrict errmesg)
errx(EXIT_FAILURE, "%s: '%s'", errmesg, str);
}
/*! \brief Reverse range.
* Used before output, if a caller has requested reverse sorting.
* FIXME: The temporary memory area handling should be internal to this
* function, not a parameter.
*
* \param flip_me The range that needs to be inverted.
* \param tmp_ranges Temporary memory area for the flip. */
void flip_ranges(struct range_t *restrict flip_me,
struct range_t *restrict tmp_ranges)
{
@ -178,7 +226,7 @@ void flip_ranges(struct range_t *restrict flip_me,
memcpy(flip_me, tmp_ranges, num_ranges * sizeof(struct range_t));
}
/* Free memory, flush buffers etc */
/*! \brief Free memory, flush buffers etc. */
void clean_up(void)
{
unsigned int i;
@ -199,6 +247,7 @@ void clean_up(void)
free(shared_networks);
}
/*! \brief A version printing. */
void __attribute__ ((__noreturn__)) print_version(void)
{
fprintf(stdout, "%s\n"
@ -208,6 +257,7 @@ void __attribute__ ((__noreturn__)) print_version(void)
exit(EXIT_SUCCESS);
}
/*! \brief Command line help screen. */
void __attribute__ ((__noreturn__)) usage(int status)
{
FILE *out;

View file

@ -33,6 +33,10 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file output.c
* \brief All about output formats.
*/
#include <config.h>
#include <arpa/inet.h>
@ -50,6 +54,8 @@
#include "dhcpd-pools.h"
#include "strftime.h"
/*! \brief Text output format, which is the default.
* FIXME: This function should return void. */
int output_txt(void)
{
unsigned int i;
@ -214,6 +220,9 @@ int output_txt(void)
return 0;
}
/*! \brief The xml output formats.
* FIXME: This function should return void.
*/
int output_xml(void)
{
unsigned int i;
@ -328,6 +337,9 @@ int output_xml(void)
return 0;
}
/*! \brief The json output formats.
* FIXME: This function should return void.
*/
int output_json(void)
{
unsigned int i = 0;
@ -471,6 +483,10 @@ int output_json(void)
return 0;
}
/*! \brief Header for full html output format.
*
* \param f Output file descriptor.
*/
static void html_header(FILE *restrict f)
{
char outstr[200];
@ -545,6 +561,10 @@ static void html_header(FILE *restrict f)
fprintf(f, "<a name=\"ranges\">The lease file mtime: %s</a>", outstr);
}
/*! \brief Footer for full html output format.
*
* \param f Output file descriptor.
*/
static void html_footer(FILE *restrict f)
{
fprintf(f, "<p><br></p>\n");
@ -561,33 +581,64 @@ static void html_footer(FILE *restrict f)
fprintf(f, "</html>\n");
}
/*! \brief A new row for html output format.
*
* \param f Output file descriptor.
*/
static void newrow(FILE *restrict f)
{
fprintf(f, "<tr>\n");
}
/*! \brief End a row for html output format.
*
* \param f Output file descriptor.
*/
static void endrow(FILE *restrict f)
{
fprintf(f, "</tr>\n\n");
}
/*! \brief Line with text in html output format.
*
* \param f Output file descriptor.
* \param type HTML tag name.
* \param class How the data is aligned.
* \param text Actual payload of the printout.
*/
static void output_line(FILE *restrict f, char const *restrict type,
char const *restrict class, char const *restrict text)
{
fprintf(f, " <%s class=%s>%s</%s>\n", type, class, text, type);
}
/*! \brief Line with digit in html output format.
*
* \param f Output file descriptor.
* \param type HMTL tag name.
* \param unlong Actual payload of the printout.
*/
static void output_long(FILE *restrict f, char const *restrict type,
unsigned long unlong)
{
fprintf(f, " <%s class=ralign>%lu</%s>\n", type, unlong, type);
}
/*! \brief Line with float in html output format.
*
* \param f Output file descriptor.
* \param type HTML tag name.
* \param fl Actual payload of the printout.
*/
static void output_float(FILE *f, char const *restrict type, float fl)
{
fprintf(f, " <%s class=ralign>%.3f</%s>\n", type, fl, type);
}
/*! \brief Begin table in html output format.
*
* \param f Output file descriptor.
*/
static void table_start(FILE *restrict f)
{
fprintf(f, "<table width=\"75%%\" ");
@ -595,11 +646,20 @@ static void table_start(FILE *restrict f)
fprintf(f, "summary=\"ISC dhcpd pool usage report\">\n");
}
/*! \brief End table in html output format.
*
* \param f Output file descriptor.
*/
static void table_end(FILE *restrict f)
{
fprintf(f, "</table>\n");
}
/*! \brief New section in html output format.
*
* \param f Output file descriptor.
* \param title Table title.
*/
static void newsection(FILE *restrict f, char const *restrict title)
{
newrow(f);
@ -610,6 +670,9 @@ static void newsection(FILE *restrict f, char const *restrict title)
endrow(f);
}
/*! \brief Output html format.
* FIXME: This function should return void.
*/
int output_html(void)
{
unsigned int i;
@ -798,6 +861,9 @@ int output_html(void)
return 0;
}
/*! \brief Output cvs format.
* FIXME: This function should return void.
*/
int output_csv(void)
{
unsigned int i;
@ -941,6 +1007,9 @@ int output_csv(void)
return 0;
}
/*! \brief Output alarm text, and return program exit value.
* FIXME: This function should return void.
*/
int output_alarming(void)
{
FILE *outfile;

View file

@ -33,6 +33,10 @@
* official policies, either expressed or implied, of Sami Kerola.
*/
/*! \file sort.c
* \brief Functions to sort output.
*/
#include <config.h>
#include <err.h>
@ -43,7 +47,11 @@
#include "dhcpd-pools.h"
/* Sort functions for range sorting */
/*! \brief Compare unsigned 32 bit integers. Suitable for IPv4 sorting.
* \param x Binary IPv4 address.
* \param y Binary IPv4 address.
* \return If x < y return -1, if y < x return 1, when they are equal return 0.
*/
int intcomp(const void *restrict x, const void *restrict y)
{
if (*(uint32_t *) x < *(uint32_t *) y)
@ -53,6 +61,11 @@ int intcomp(const void *restrict x, const void *restrict y)
return 0;
}
/*! \brief Compare IP address, with IPv4/v6 determination.
* \param a Binary IP address.
* \param b Binary IP address.
* \return If a < b return -1, if a < b return 1, when they are equal return 0.
*/
int ipcomp(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b)
{
if (dhcp_version == VERSION_6) {
@ -66,34 +79,60 @@ int ipcomp(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b)
}
}
/*! \brief Compare IP address in leases. Suitable for sorting leases.
* \param a A lease structure.
* \param b A lease structure.
* \return Return pas through from ipcomp.
*/
int leasecomp(const void *restrict a, const void *restrict b)
{
return ipcomp(&((const struct leases_t *)a)->ip,
&((const struct leases_t *)b)->ip);
}
/*! \brief Compare IP address in leases. Suitable for sorting range table.
* \param r1 A range structure.
* \param r2 A range structure.
* \return Return pas through from ipcomp.
*/
int rangecomp(const void *restrict r1, const void *restrict r2)
{
return ipcomp(&((const struct range_t *)r1)->first_ip,
&((const struct range_t *)r2)->first_ip);
}
/*! \brief Return IP.
* \param r A range structure.
* \return First IP in the range, perhaps?? maybe?
* FIXME: This function is not implemented, yet.
*/
unsigned long int ret_ip(struct range_t r)
{
/* FIXME: IPv6 */
return (r.first_ip.v4);
}
/*! \brief In use in range.
* \param r A range structure.
* \return Number of addresses that are in use in the given range.
*/
unsigned long int ret_cur(struct range_t r)
{
return (r.count);
}
/*! \brief Range maximum.
* \param r A range structure.
* \return Maximum number of addresses that can be in the given range.
*/
unsigned long int ret_max(struct range_t r)
{
return get_range_size(&r);
}
/*! \brief Percentage in use in range.
* \param r A range structure.
* \return Usage percentage of the given range.
*/
unsigned long int ret_percent(struct range_t r)
{
float f;
@ -101,16 +140,28 @@ unsigned long int ret_percent(struct range_t r)
return ((unsigned long int)(f * 100000));
}
/*! \brief Touched in range.
* \param r A range structure.
* \return Number of touched addresses in the given range.
*/
unsigned long int ret_touched(struct range_t r)
{
return (r.touched);
}
/*! \brief Touched and in use in range
* \param r A range structure.
* \return Number of touched or in use addresses in the given range.
*/
unsigned long int ret_tc(struct range_t r)
{
return (r.count + r.touched);
}
/*! \brief Return percentage of addresses touched and in use in range.
* \param r A range structure.
* \return Percentage of touched or in use addresses in the given range.
*/
unsigned long int ret_tcperc(struct range_t r)
{
float f;
@ -118,6 +169,12 @@ unsigned long int ret_tcperc(struct range_t r)
return ((unsigned long int)(f * 10000));
}
/*! \brief Sort field selector.
* \param c Symbolic name of a sort by character.
* The sort algorithms are stabile, which means multiple sorts can be
* specified and they do not mess the result of previous sort. The sort
* algorithms are used via function pointer, that gets to be reassigned.
*/
void field_selector(char c)
{
switch (c) {
@ -151,7 +208,13 @@ void field_selector(char c)
}
}
/* Needed to support multiple key sorting. */
/*! \brief Perform requested sorting.
* \param left The left side of the merge sort.
* \param right The right side of the merge sort.
* FIXME: This function should be marked as static.
* FIXME: Really horribly named indirection about which function is in use.
* \return Relevant for merge sort decision.
*/
int get_order(struct range_t *restrict left, struct range_t *restrict right)
{
int i, len, ret;
@ -189,6 +252,12 @@ int get_order(struct range_t *restrict left, struct range_t *restrict right)
return (0);
}
/*! \brief Mergesort for range table.
* \param orig Pointer to range that is requested to be sorted.
* \param size Number of ranges to be sorted.
* \param temp Temporary memory space, needed when a values has to be
* flipped.
*/
void mergesort_ranges(struct range_t *restrict orig, int size,
struct range_t *restrict temp)
{