mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 07:47:00 +00:00
various: split functions to IPv4 and IPv6 versions
The code selection will be set with function pointer, which avoids numerous IP version checks. As a result with some inputs the analysis runs quicker. Most users will not notice much of difference. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
97c6f0292f
commit
8da98bbc89
5 changed files with 215 additions and 89 deletions
|
|
@ -248,7 +248,7 @@ int main(int argc, char **argv)
|
|||
|
||||
/* Do the job */
|
||||
prepare_memory();
|
||||
xstrstr = xstrstr_init;
|
||||
set_ipv_functions(VERSION_UNKNOWN);
|
||||
parse_config(true, config.dhcpdconf_file, shared_networks);
|
||||
|
||||
parse_leases();
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ unsigned int RANGES;
|
|||
|
||||
/* Function prototypes */
|
||||
int prepare_memory(void);
|
||||
void set_ipv_functions(int version);
|
||||
int parse_leases(void);
|
||||
void parse_config(int, const char *__restrict,
|
||||
struct shared_network_t *__restrict)
|
||||
|
|
@ -199,11 +200,26 @@ void flip_ranges(struct range_t *__restrict ranges,
|
|||
struct range_t *__restrict tmp_ranges)
|
||||
__attribute__ ((nonnull(1, 2)));
|
||||
/* support functions */
|
||||
int parse_ipaddr(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
void copy_ipaddr(union ipaddr_t *restrict dst,
|
||||
const union ipaddr_t *restrict src);
|
||||
const char *ntop_ipaddr(const union ipaddr_t *ip);
|
||||
double get_range_size(const struct range_t *r);
|
||||
int (*parse_ipaddr)(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
int parse_ipaddr_init(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
int parse_ipaddr_v4(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
int parse_ipaddr_v6(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
|
||||
void (*copy_ipaddr)(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
void copy_ipaddr_init(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
void copy_ipaddr_v4(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
void copy_ipaddr_v6(union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
|
||||
const char *(*ntop_ipaddr)(const union ipaddr_t *ip);
|
||||
const char *ntop_ipaddr_init(const union ipaddr_t *ip);
|
||||
const char *ntop_ipaddr_v4(const union ipaddr_t *ip);
|
||||
const char *ntop_ipaddr_v6(const union ipaddr_t *ip);
|
||||
|
||||
double (*get_range_size)(const struct range_t *r);
|
||||
double get_range_size_init(const struct range_t *r);
|
||||
double get_range_size_v4(const struct range_t *r);
|
||||
double get_range_size_v6(const struct range_t *r);
|
||||
|
||||
int (*xstrstr)(const char *__restrict str);
|
||||
int xstrstr_init(const char *__restrict str)
|
||||
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||
|
|
@ -227,7 +243,11 @@ void print_version(void) __attribute__ ((noreturn));
|
|||
void usage(int status) __attribute__ ((noreturn));
|
||||
/* qsort required functions... */
|
||||
/* ...for ranges and... */
|
||||
int ipcomp(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
int (*ipcomp)(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
int ipcomp_init(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
int ipcomp_v4(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
int ipcomp_v6(const union ipaddr_t *restrict a, const union ipaddr_t *restrict b);
|
||||
|
||||
int comp_cur(struct range_t *r1, struct range_t *r2);
|
||||
int comp_double(double f1, double f2);
|
||||
int comp_ip(struct range_t *r1, struct range_t *r2);
|
||||
|
|
@ -258,8 +278,16 @@ int output_alarming(void);
|
|||
/* Memory release, file closing etc */
|
||||
void clean_up(void);
|
||||
/* Hash functions */
|
||||
void add_lease(union ipaddr_t *ip, enum ltype type);
|
||||
struct leases_t *find_lease(union ipaddr_t *ip);
|
||||
void (*add_lease)(union ipaddr_t *ip, enum ltype type);
|
||||
void add_lease_init(union ipaddr_t *ip, enum ltype type);
|
||||
void add_lease_v4(union ipaddr_t *ip, enum ltype type);
|
||||
void add_lease_v6(union ipaddr_t *ip, enum ltype type);
|
||||
|
||||
struct leases_t *(*find_lease)(union ipaddr_t *ip);
|
||||
struct leases_t *find_lease_init(union ipaddr_t *ip);
|
||||
struct leases_t *find_lease_v4(union ipaddr_t *ip);
|
||||
struct leases_t *find_lease_v6(union ipaddr_t *ip);
|
||||
|
||||
void delete_lease(struct leases_t *lease);
|
||||
void delete_all_leases(void);
|
||||
|
||||
|
|
|
|||
39
src/hash.c
39
src/hash.c
|
|
@ -47,17 +47,27 @@
|
|||
/*! \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)
|
||||
void add_lease_init(union ipaddr_t *addr __attribute__((unused)), enum ltype type __attribute__((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void add_lease_v4(union ipaddr_t *addr, enum ltype type)
|
||||
{
|
||||
struct leases_t *l;
|
||||
l = xmalloc(sizeof(struct leases_t));
|
||||
copy_ipaddr(&l->ip, addr);
|
||||
l->type = type;
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
HASH_ADD_V6(leases, ip.v6, l);
|
||||
} else {
|
||||
HASH_ADD_INT(leases, ip.v4, l);
|
||||
}
|
||||
l->ethernet = NULL;
|
||||
}
|
||||
|
||||
void add_lease_v6(union ipaddr_t *addr, enum ltype type)
|
||||
{
|
||||
struct leases_t *l;
|
||||
l = xmalloc(sizeof(struct leases_t));
|
||||
copy_ipaddr(&l->ip, addr);
|
||||
l->type = type;
|
||||
HASH_ADD_V6(leases, ip.v6, l);
|
||||
l->ethernet = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -65,15 +75,22 @@ void add_lease(union ipaddr_t *addr, enum ltype type)
|
|||
* \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 *find_lease_init(union ipaddr_t *addr __attribute__((unused)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct leases_t *find_lease_v4(union ipaddr_t *addr)
|
||||
{
|
||||
struct leases_t *l;
|
||||
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
HASH_FIND_V6(leases, &addr->v6, l);
|
||||
} else {
|
||||
HASH_FIND_INT(leases, &addr->v4, l);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
struct leases_t *find_lease_v6(union ipaddr_t *addr)
|
||||
{
|
||||
struct leases_t *l;
|
||||
HASH_FIND_V6(leases, &addr->v4, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
|
|
|||
154
src/other.c
154
src/other.c
|
|
@ -55,36 +55,90 @@
|
|||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*! \brief Set function pointers depending on IP version.
|
||||
* \param ip IP version.
|
||||
*/
|
||||
void set_ipv_functions(int version)
|
||||
{
|
||||
switch (version) {
|
||||
|
||||
case VERSION_4:
|
||||
config.dhcp_version = version;
|
||||
add_lease = add_lease_v4;
|
||||
copy_ipaddr = copy_ipaddr_v4;
|
||||
find_lease = find_lease_v4;
|
||||
get_range_size = get_range_size_v4;
|
||||
ipcomp = ipcomp_v4;
|
||||
ntop_ipaddr = ntop_ipaddr_v4;
|
||||
parse_ipaddr = parse_ipaddr_v4;
|
||||
xstrstr = xstrstr_v4;
|
||||
break;
|
||||
|
||||
case VERSION_6:
|
||||
config.dhcp_version = version;
|
||||
add_lease = add_lease_v6;
|
||||
copy_ipaddr = copy_ipaddr_v6;
|
||||
find_lease = find_lease_v6;
|
||||
get_range_size = get_range_size_v6;
|
||||
ipcomp = ipcomp_v6;
|
||||
ntop_ipaddr = ntop_ipaddr_v6;
|
||||
parse_ipaddr = parse_ipaddr_v6;
|
||||
xstrstr = xstrstr_v6;
|
||||
break;
|
||||
|
||||
case VERSION_UNKNOWN:
|
||||
config.dhcp_version = version;
|
||||
add_lease = add_lease_init;
|
||||
copy_ipaddr = copy_ipaddr_init;
|
||||
find_lease = find_lease_init;
|
||||
get_range_size = get_range_size_init;
|
||||
ipcomp = ipcomp_init;
|
||||
ntop_ipaddr = ntop_ipaddr_init;
|
||||
parse_ipaddr = parse_ipaddr_init;
|
||||
xstrstr = xstrstr_init;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*! \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 parse_ipaddr_init(const char *restrict src, union ipaddr_t *restrict dst)
|
||||
{
|
||||
int rv;
|
||||
if (config.dhcp_version == VERSION_UNKNOWN) {
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
if (inet_aton(src, &addr) == 1) {
|
||||
config.dhcp_version = VERSION_4;
|
||||
xstrstr = xstrstr_v4;
|
||||
set_ipv_functions(VERSION_4);
|
||||
} else if (inet_pton(AF_INET6, src, &addr6) == 1) {
|
||||
config.dhcp_version = VERSION_6;
|
||||
xstrstr = xstrstr_v6;
|
||||
set_ipv_functions(VERSION_6);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
struct in6_addr addr;
|
||||
rv = inet_pton(AF_INET6, src, &addr);
|
||||
memcpy(&dst->v6, addr.s6_addr, sizeof(addr.s6_addr));
|
||||
} else {
|
||||
return parse_ipaddr(src, dst);
|
||||
}
|
||||
|
||||
int parse_ipaddr_v4(const char *restrict src, union ipaddr_t *restrict dst)
|
||||
{
|
||||
int rv;
|
||||
struct in_addr addr;
|
||||
rv = inet_aton(src, &addr);
|
||||
dst->v4 = ntohl(addr.s_addr);
|
||||
}
|
||||
return rv == 1;
|
||||
}
|
||||
|
||||
int parse_ipaddr_v6(const char *restrict src, union ipaddr_t *restrict dst)
|
||||
{
|
||||
int rv;
|
||||
struct in6_addr addr;
|
||||
rv = inet_pton(AF_INET6, src, &addr);
|
||||
memcpy(&dst->v6, addr.s6_addr, sizeof(addr.s6_addr));
|
||||
return rv == 1;
|
||||
}
|
||||
|
||||
|
|
@ -92,14 +146,21 @@ int parse_ipaddr(const char *restrict src, union ipaddr_t *restrict dst)
|
|||
*
|
||||
* \param dst Destination for a binary IP address.
|
||||
* \param src Sourse of an IP address. */
|
||||
void copy_ipaddr(union ipaddr_t *restrict dst,
|
||||
void copy_ipaddr_init(union ipaddr_t *restrict dst __attribute__((unused)),
|
||||
const union ipaddr_t *restrict src __attribute__((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void copy_ipaddr_v4(union ipaddr_t *restrict dst,
|
||||
const union ipaddr_t *restrict src)
|
||||
{
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
memcpy(&dst->v6, &src->v6, sizeof(src->v6));
|
||||
} else {
|
||||
dst->v4 = src->v4;
|
||||
}
|
||||
}
|
||||
|
||||
void copy_ipaddr_v6(union ipaddr_t *restrict dst,
|
||||
const union ipaddr_t *restrict src)
|
||||
{
|
||||
memcpy(&dst->v6, &src->v6, sizeof(src->v6));
|
||||
}
|
||||
|
||||
/*! \brief Convert an address to string. This function will convert the
|
||||
|
|
@ -110,19 +171,27 @@ void copy_ipaddr(union ipaddr_t *restrict dst,
|
|||
* \param ip Binary IP address.
|
||||
* \return Printable address.
|
||||
*/
|
||||
const char *ntop_ipaddr(const union ipaddr_t *ip)
|
||||
const char *ntop_ipaddr_init(const union ipaddr_t *ip __attribute__((unused)))
|
||||
{
|
||||
static char
|
||||
buffer[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
struct in6_addr addr;
|
||||
memcpy(addr.s6_addr, ip->v6, sizeof(addr.s6_addr));
|
||||
return inet_ntop(AF_INET6, &addr, buffer, sizeof(buffer));
|
||||
} else {
|
||||
static char buffer = '\0';
|
||||
return &buffer;
|
||||
}
|
||||
|
||||
const char *ntop_ipaddr_v4(const union ipaddr_t *ip)
|
||||
{
|
||||
static char buffer[sizeof("255.255.255.255")];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(ip->v4);
|
||||
return inet_ntop(AF_INET, &addr, buffer, sizeof(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
const char *ntop_ipaddr_v6(const union ipaddr_t *ip)
|
||||
{
|
||||
static char
|
||||
buffer[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
|
||||
struct in6_addr addr;
|
||||
memcpy(addr.s6_addr, ip->v6, sizeof(addr.s6_addr));
|
||||
return inet_ntop(AF_INET6, &addr, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
/*! \brief Calculate how many addresses there are in a range.
|
||||
|
|
@ -131,23 +200,28 @@ const char *ntop_ipaddr(const union ipaddr_t *ip)
|
|||
* and last IP in the range.
|
||||
* \return Size of a range.
|
||||
*/
|
||||
double get_range_size(const struct range_t *r)
|
||||
double get_range_size_init(const struct range_t *r __attribute__((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double get_range_size_v4(const struct range_t *r)
|
||||
{
|
||||
return r->last_ip.v4 - r->first_ip.v4 + 1;
|
||||
}
|
||||
|
||||
double get_range_size_v6(const struct range_t *r)
|
||||
{
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
double size = 0;
|
||||
int i;
|
||||
/* When calculating the size of an IPv6 range overflow may
|
||||
* occur. In that case only the last LONG_BIT bits are
|
||||
* preserved, thus we just skip the first (16 - LONG_BIT)
|
||||
* bits... */
|
||||
/* When calculating the size of an IPv6 range overflow may occur.
|
||||
* In that case only the last LONG_BIT bits are preserved, thus
|
||||
* we just skip the first (16 - LONG_BIT) bits... */
|
||||
for (i = 0; i < 16; i++) {
|
||||
size *= 256;
|
||||
size += (int)r->last_ip.v6[i] - (int)r->first_ip.v6[i];
|
||||
}
|
||||
return size + 1;
|
||||
} else {
|
||||
return r->last_ip.v4 - r->first_ip.v4 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \fn xstrstr_init(const char *restrict str)
|
||||
|
|
@ -164,12 +238,10 @@ int
|
|||
xstrstr_init(const char *restrict str)
|
||||
{
|
||||
if (memcmp("lease ", str, 6)) {
|
||||
config.dhcp_version = VERSION_4;
|
||||
xstrstr = xstrstr_v4;
|
||||
set_ipv_functions(VERSION_4);
|
||||
return PREFIX_LEASE;
|
||||
} else if (memcmp(" iaaddr ", str, 9)) {
|
||||
config.dhcp_version = VERSION_6;
|
||||
xstrstr = xstrstr_v6;
|
||||
set_ipv_functions(VERSION_6);
|
||||
return PREFIX_LEASE;
|
||||
}
|
||||
return NUM_OF_PREFIX;
|
||||
|
|
|
|||
19
src/sort.c
19
src/sort.c
|
|
@ -54,17 +54,26 @@
|
|||
* \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)
|
||||
int ipcomp_init(const union ipaddr_t *restrict a __attribute__((unused)),
|
||||
const union ipaddr_t *restrict b __attribute__((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipcomp_v4(const union ipaddr_t *restrict a,
|
||||
const union ipaddr_t *restrict b)
|
||||
{
|
||||
if (config.dhcp_version == VERSION_6) {
|
||||
return memcmp(&a->v6, &b->v6, sizeof(a->v6));
|
||||
} else {
|
||||
if (a->v4 < b->v4)
|
||||
return -1;
|
||||
if (a->v4 > b->v4)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ipcomp_v6(const union ipaddr_t *restrict a,
|
||||
const union ipaddr_t *restrict b)
|
||||
{
|
||||
return memcmp(&a->v6, &b->v6, sizeof(a->v6));
|
||||
}
|
||||
|
||||
/*! \brief Compare IP address in leases. Suitable for sorting range table.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue