mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +00:00
getdata: add cidr range support
This makes 'range6 123::/45' style cidr notation to be understood as address range. Earlier ranges that used cidr failed to parse completely. Reported-by: Jeff Bailey <jeffrey.bailey@bt.com> Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
48d0629881
commit
bb0fa9adae
13 changed files with 175 additions and 5 deletions
1
THANKS
1
THANKS
|
|
@ -41,3 +41,4 @@ Ivanov Ivan
|
|||
Manuel Hachtkemper
|
||||
Klaus Slott
|
||||
Boris Lytochkin
|
||||
Jeff Bailey
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ extern int parse_ipaddr_init(const char *restrict src,
|
|||
extern int parse_ipaddr_v4(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
extern int parse_ipaddr_v6(const char *restrict src, union ipaddr_t *restrict dst);
|
||||
|
||||
extern void parse_cidr(struct range_t *range_p, const char *word);
|
||||
|
||||
extern void (*copy_ipaddr) (union ipaddr_t *restrict dst, const union ipaddr_t *restrict src);
|
||||
extern void copy_ipaddr_init(union ipaddr_t *restrict dst,
|
||||
const union ipaddr_t *restrict src);
|
||||
|
|
|
|||
|
|
@ -339,6 +339,11 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
/* printf ("range 2nd ip: %s\n", word); */
|
||||
range_p = ranges + num_ranges;
|
||||
argument = ITS_NOTHING_INTERESTING;
|
||||
if (strchr(word, '/')) {
|
||||
parse_cidr(range_p, word);
|
||||
one_ip_range = 0;
|
||||
} else {
|
||||
/* not cidr */
|
||||
parse_ipaddr(word, &addr);
|
||||
if (one_ip_range == 1) {
|
||||
one_ip_range = 0;
|
||||
|
|
@ -346,6 +351,7 @@ void parse_config(int is_include, const char *restrict config_file,
|
|||
}
|
||||
copy_ipaddr(&range_p->last_ip, &addr);
|
||||
reorder_last_first(range_p);
|
||||
}
|
||||
newrange:
|
||||
range_p->count = 0;
|
||||
range_p->touched = 0;
|
||||
|
|
|
|||
94
src/other.c
94
src/other.c
|
|
@ -52,10 +52,15 @@
|
|||
#include "error.h"
|
||||
#include "progname.h"
|
||||
#include "quote.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#include "dhcpd-pools.h"
|
||||
#include "defaults.h"
|
||||
|
||||
char *(*cidr_last)(union ipaddr_t *restrict addr, const int mask);
|
||||
static char *cidr_last_v4(union ipaddr_t *restrict addr, const int mask);
|
||||
static char *cidr_last_v6(union ipaddr_t *restrict addr, const int mask);
|
||||
|
||||
/*! \brief Set function pointers depending on IP version.
|
||||
* \param ip IP version.
|
||||
*/
|
||||
|
|
@ -73,6 +78,7 @@ void set_ipv_functions(int version)
|
|||
leasecomp = leasecomp_v4;
|
||||
ntop_ipaddr = ntop_ipaddr_v4;
|
||||
parse_ipaddr = parse_ipaddr_v4;
|
||||
cidr_last = cidr_last_v4;
|
||||
xstrstr = xstrstr_v4;
|
||||
break;
|
||||
|
||||
|
|
@ -86,6 +92,7 @@ void set_ipv_functions(int version)
|
|||
leasecomp = leasecomp_v6;
|
||||
ntop_ipaddr = ntop_ipaddr_v6;
|
||||
parse_ipaddr = parse_ipaddr_v6;
|
||||
cidr_last = cidr_last_v6;
|
||||
xstrstr = xstrstr_v6;
|
||||
break;
|
||||
|
||||
|
|
@ -99,6 +106,7 @@ void set_ipv_functions(int version)
|
|||
leasecomp = leasecomp_init;
|
||||
ntop_ipaddr = ntop_ipaddr_init;
|
||||
parse_ipaddr = parse_ipaddr_init;
|
||||
cidr_last = NULL;
|
||||
xstrstr = xstrstr_init;
|
||||
break;
|
||||
|
||||
|
|
@ -148,6 +156,92 @@ int parse_ipaddr_v6(const char *restrict src, union ipaddr_t *restrict dst)
|
|||
return rv == 1;
|
||||
}
|
||||
|
||||
static int strtol_mask(const char *str)
|
||||
{
|
||||
long num;
|
||||
char *end = NULL;
|
||||
|
||||
errno = 0;
|
||||
if (str == NULL || *str == '\0')
|
||||
goto err;
|
||||
num = strtol(str, &end, 10);
|
||||
|
||||
if (errno || str == end || (end && *end))
|
||||
goto err;
|
||||
if (num < 0 || 128 < num)
|
||||
goto err;
|
||||
return (int)num;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *cidr_last_v4(union ipaddr_t *restrict addr, const int mask)
|
||||
{
|
||||
union ipaddr_t last_ip;
|
||||
uint32_t netmask;
|
||||
const char *ip;
|
||||
|
||||
if (mask)
|
||||
netmask = (1U << (32 - mask)) - 1;
|
||||
else
|
||||
netmask = 0;
|
||||
last_ip.v4 = addr->v4 | netmask;
|
||||
|
||||
ip = ntop_ipaddr(&last_ip);
|
||||
return xstrdup(ip);
|
||||
}
|
||||
|
||||
static char *cidr_last_v6(union ipaddr_t *restrict addr, const int mask)
|
||||
{
|
||||
union ipaddr_t bitmask;
|
||||
int i, j;
|
||||
char ip[128];
|
||||
|
||||
memset(&bitmask, 0x0, sizeof(bitmask));
|
||||
for (i = mask, j = 0; i > 0; i -= 8, j++) {
|
||||
if (i >= 8)
|
||||
bitmask.v6[j] = 0xff;
|
||||
else
|
||||
bitmask.v6[j] = (unsigned char)(0xffU << (8 - i));
|
||||
}
|
||||
for (i = 0; i < (int)sizeof(bitmask); i++)
|
||||
addr->v6[i] |= ~bitmask.v6[i];
|
||||
inet_ntop(AF_INET6, addr, ip, sizeof(ip));
|
||||
return xstrdup(ip);
|
||||
}
|
||||
|
||||
void parse_cidr(struct range_t *range_p, const char *word)
|
||||
{
|
||||
char *divider;
|
||||
int mask;
|
||||
union ipaddr_t addr;
|
||||
char *last;
|
||||
|
||||
/* determine cidr */
|
||||
divider = strchr(word, '/');
|
||||
*divider++ = '\0';
|
||||
mask = strtol_mask(divider);
|
||||
if (mask < 0)
|
||||
error(EXIT_FAILURE, 0, "cidr %s invalid mask %s", word,
|
||||
divider);
|
||||
if (config.ip_version == IPvUNKNOWN) {
|
||||
if (!strchr(word, ':'))
|
||||
set_ipv_functions(IPv4);
|
||||
else
|
||||
set_ipv_functions(IPv6);
|
||||
}
|
||||
|
||||
/* start of the range is easy */
|
||||
parse_ipaddr(word, &addr);
|
||||
copy_ipaddr(&range_p->first_ip, &addr);
|
||||
|
||||
/* end of the range depends cidr size */
|
||||
last = cidr_last(&addr, mask);
|
||||
parse_ipaddr(last, &addr);
|
||||
copy_ipaddr(&range_p->last_ip, &addr);
|
||||
free(last);
|
||||
}
|
||||
|
||||
/*! \brief Copy IP address to union.
|
||||
*
|
||||
* \param dst Destination for a binary IP address.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ TESTS = \
|
|||
tests/leading0 \
|
||||
tests/one-ip \
|
||||
tests/one-line \
|
||||
tests/range4 \
|
||||
tests/range6 \
|
||||
tests/same-twice \
|
||||
tests/simple \
|
||||
tests/sorts \
|
||||
|
|
|
|||
31
tests/confs/range4
Normal file
31
tests/confs/range4
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
shared-network example1 {
|
||||
subnet 10.0.0.0 netmask 255.255.255.0 {
|
||||
pool {
|
||||
range 10.0.0.0/27;
|
||||
}
|
||||
}
|
||||
subnet 10.1.0.0 netmask 255.255.255.0 {
|
||||
pool {
|
||||
range 10.1.0.1/27;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared-network example2 {
|
||||
subnet 10.2.0.0 netmask 255.255.255.0 {
|
||||
pool {
|
||||
range 10.2.0.1/28;
|
||||
}
|
||||
}
|
||||
subnet 10.3.0.0 netmask 255.255.255.0 {
|
||||
pool {
|
||||
range 10.3.0.1/29;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subnet 10.4.0.0 netmask 255.255.255.0 {
|
||||
pool {
|
||||
range 10.4.0.1/32;
|
||||
}
|
||||
}
|
||||
4
tests/confs/range6
Normal file
4
tests/confs/range6
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
subnet6 dead:abba:1000::/56 {
|
||||
range6 dead:abba:1000::/56;
|
||||
prefix6 dead:abba:1000:0100:: dead:abba:1000:ff00::/56;
|
||||
}
|
||||
16
tests/expected/range4
Normal file
16
tests/expected/range4
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Ranges:
|
||||
shared net name first ip last ip max cur percent touch t+c t+c perc
|
||||
example1 10.0.0.0 - 10.0.0.31 32 12 37.500 0 12 37.500
|
||||
example1 10.1.0.1 - 10.1.0.31 31 10 32.258 0 10 32.258
|
||||
example2 10.2.0.1 - 10.2.0.15 15 8 53.333 0 8 53.333
|
||||
example2 10.3.0.1 - 10.3.0.7 7 7 100.000 0 7 100.000
|
||||
All networks 10.4.0.1 - 10.4.0.1 1 1 100.000 0 1 100.000
|
||||
|
||||
Shared networks:
|
||||
name max cur percent touch t+c t+c perc
|
||||
example1 63 22 34.921 0 22 34.921
|
||||
example2 22 15 68.182 0 15 68.182
|
||||
|
||||
Sum of all ranges:
|
||||
name max cur percent touch t+c t+c perc
|
||||
All networks 86 38 44.186 0 38 44.186
|
||||
10
tests/expected/range6
Normal file
10
tests/expected/range6
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Ranges:
|
||||
shared net name first ip last ip max cur percent touch t+c t+c perc
|
||||
All networks dead:abba:1000:: - dead:abba:1000:ff:ffff:ffff:ffff:ffff 4.72237e+21 2 0.000 1 3 0.000
|
||||
|
||||
Shared networks:
|
||||
name max cur percent touch t+c t+c perc
|
||||
|
||||
Sum of all ranges:
|
||||
name max cur percent touch t+c t+c perc
|
||||
All networks 4.72237e+21 2 0.000 1 3 0.000
|
||||
1
tests/leases/range4
Symbolic link
1
tests/leases/range4
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
complete
|
||||
1
tests/leases/range6
Symbolic link
1
tests/leases/range6
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
v6
|
||||
1
tests/range4
Symbolic link
1
tests/range4
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
test.sh
|
||||
1
tests/range6
Symbolic link
1
tests/range6
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
test.sh
|
||||
Loading…
Add table
Add a link
Reference in a new issue