diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2016-05-09 21:40:54 +0200 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-05-11 13:25:13 +0300 |
commit | 7ae7712429737afe72068eec6b76f0632f1d8d55 (patch) | |
tree | 6ad2e98fa8e05d1785246bbdb8e4d4290fba2339 /accel-pppd/utils.c | |
parent | f5a97ed5f9f5788655dbb4720b669a7235b5d663 (diff) | |
download | accel-ppp-7ae7712429737afe72068eec6b76f0632f1d8d55.tar.gz accel-ppp-7ae7712429737afe72068eec6b76f0632f1d8d55.zip |
iprange: rework ip range parsing functions
The previous parsing functions had a few problems:
* They did accept negative numbers in addresses (e.g. 192.0.2.-5).
* They relied on C undefined behaviour for detecting /0 prefix
length: "mask = htonl(~((1 << (32 - m)) - 1)" was wrong for m = 0,
because that resulted in a left shift of 32 bits, on a 32 bit wide
value (the right operand of a bitwise shift operator must be
strictly smaller than the width of the promoted left operand).
* They misinterpreted /32 prefixes as disable requests. In fact, due
to the undefined behaviour described above, /0 and /32 prefix
lengths were represented in the same way by parse1(), that is, with
an iprange_t structure where ->begin == ->end. Therefore
load_ranges() had no way to distinguish between them and did
disable the module in both cases.
This patch fixes these issues and brings the following improvements:
* It uses getaddrinfo() to parse IP addresses, so it accept (almost)
all IPv4 representations and is more easily extensible to IPv6 in
the future.
* It warns when the IP address used in CIDR notation is not the first
address in the range (e.g. the first address of 192.0.2.1/24 is
192.0.2.0, not 192.0.2.1).
* It doesn't _exit() on parsing failures, thus making the functions
usable in an EV_CONFIG_RELOAD handler.
While there, the unfinished tunnel_ranges code, which was already
commented, has been removed.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd/utils.c')
-rw-r--r-- | accel-pppd/utils.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/accel-pppd/utils.c b/accel-pppd/utils.c index 81b4c993..3b87ee16 100644 --- a/accel-pppd/utils.c +++ b/accel-pppd/utils.c @@ -1,7 +1,9 @@ #include <errno.h> +#include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <netinet/in.h> #include "triton.h" #include "utils.h" @@ -35,6 +37,31 @@ int __export u_readlong(long int *dst, const char *src, } } +int __export u_parse_ip4addr(const char *src, struct in_addr *addr, + const char **err_msg) +{ + struct addrinfo hint = { + .ai_flags = AI_NUMERICHOST, + .ai_family = AF_INET, + .ai_socktype = 0, + .ai_protocol = 0, + }; + struct addrinfo *ainfo; + int err; + + err = getaddrinfo(src, NULL, &hint, &ainfo); + if (err) { + *err_msg = gai_strerror(err); + return err; + } + + *addr = ((struct sockaddr_in *)ainfo->ai_addr)->sin_addr; + + freeaddrinfo(ainfo); + + return 0; +} + int __export u_randbuf(void *buf, size_t buf_len, int *err) { uint8_t *u8buf = buf; |