summaryrefslogtreecommitdiff
path: root/accel-pppd/extra/ipv6pool.c
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2021-04-07 04:35:00 +0500
committerVladislav Grishenko <themiron@mail.ru>2021-04-07 04:55:12 +0500
commit63ea2beb79e30417dcea4a0926a3a18303872658 (patch)
tree8f2a91ffbd6248f1cc18ffb79cee984cca7502f0 /accel-pppd/extra/ipv6pool.c
parenta77f9e071f084918bbb805c2509aec0f47fcf95b (diff)
downloadaccel-ppp-63ea2beb79e30417dcea4a0926a3a18303872658.tar.gz
accel-ppp-63ea2beb79e30417dcea4a0926a3a18303872658.zip
ipv6pool: fix next pool handling
* fix no next pool when subsequent pool prefix was defined w/o next pool: fc00:0:3::/48,64,name=pool1,next=pool2 fc00:0:4::/48,64,name=pool1 * fix no next pool when it was defined after referencing: fc00:0:3::/48,64,name=pool1,next=pool2 fc00:0:4::/48,64,name=pool2 * fix UB when next pool was set to same pool: fc00:0:3::/48,64,name=pool1,next=pool1 * add warning about empty/not defined next pools
Diffstat (limited to 'accel-pppd/extra/ipv6pool.c')
-rw-r--r--accel-pppd/extra/ipv6pool.c87
1 files changed, 52 insertions, 35 deletions
diff --git a/accel-pppd/extra/ipv6pool.c b/accel-pppd/extra/ipv6pool.c
index 24ea3736..5ca85f1c 100644
--- a/accel-pppd/extra/ipv6pool.c
+++ b/accel-pppd/extra/ipv6pool.c
@@ -404,30 +404,39 @@ static int parse_vendor_opt(const char *opt)
}
#endif
-static void parse_options(enum ippool_type type, const char *opt, char **pool_name, struct ippool_t **next)
+static int parse_options(enum ippool_type type, const char *opt, struct ippool_t **pool, struct ippool_t **next)
{
- char *ptr1, *ptr2, *tmp;
-
- ptr1 = strstr(opt, ",name=");
- if (ptr1) {
- ptr1 += sizeof(",name=") - 1;
- ptr2 = strchrnul(ptr1, ',');
- *pool_name = _strndup(ptr1, ptr2 - ptr1);
- }
-
- ptr1 = strstr(opt, ",next=");
- if (ptr1) {
- ptr1 += sizeof(",next=") - 1;
- ptr2 = strchrnul(ptr1, ',');
- if (*ptr2 == ',') {
- tmp = alloca(ptr2 - ptr1 + 1);
- strncpy(tmp, ptr1, ptr2 - ptr1);
- ptr1 = tmp;
+ char *name, *ptr;
+
+ name = strstr(opt, ",name=");
+ if (name) {
+ name += sizeof(",name=") - 1;
+ ptr = strchrnul(name, ',');
+ name = _strndup(name, ptr - name);
+ if (!name)
+ return -1;
+ *pool = find_pool(type, name, 1);
+ } else if (type == IPPOOL_PREFIX)
+ *pool = def_dppool;
+ else
+ *pool = def_ippool;
+
+ name = strstr(opt, ",next=");
+ if (name) {
+ name += sizeof(",next=") - 1;
+ ptr = strchrnul(name, ',');
+ name = strncpy(alloca(ptr - name + 1), name, ptr - name + 1);
+ *next = find_pool(type, name, 0);
+ if (!*next) {
+ name = _strdup(name);
+ if (!name)
+ return -1;
+ *next = find_pool(type, name, 1);
}
- *next = find_pool(type, ptr1, 0);
- if (!(*next))
- log_error("ipv6_pool: %s: next pool not found\n", opt);
- }
+ } else
+ *next = NULL;
+
+ return 0;
}
static void ippool_init1(void)
@@ -440,7 +449,7 @@ static void ippool_init2(void)
struct conf_sect_t *s = conf_get_section("ipv6-pool");
struct conf_option_t *opt;
struct ippool_t *pool, *next;
- char *pool_name, *val;
+ char *val;
enum ippool_type type;
#ifdef RADIUS
int dppool_attr = 0, ippool_attr = 0;
@@ -458,12 +467,10 @@ static void ippool_init2(void)
if (!strcmp(opt->name, "vendor")) {
conf_vendor = parse_vendor_opt(opt->val);
continue;
- }
- if (!strcmp(opt->name, "attr-prefix")) {
+ } else if (!strcmp(opt->name, "attr-prefix")) {
dppool_attr = parse_attr_opt(opt->val);
continue;
- }
- if (!strcmp(opt->name, "attr-address")) {
+ } else if (!strcmp(opt->name, "attr-address")) {
ippool_attr = parse_attr_opt(opt->val);
continue;
}
@@ -471,26 +478,36 @@ static void ippool_init2(void)
#endif
if (!strcmp(opt->name, "gw-ip6-address")) {
if (inet_pton(AF_INET6, opt->val, &conf_gw_addr) == 0)
- log_error("ipv6_pool: failed to parse gw-ip6-address\n");
+ log_error("ipv6_pool: failed to parse '%s'\n", opt->raw);
continue;
} else if (!strcmp(opt->name, "delegate")) {
type = IPPOOL_PREFIX;
val = opt->val;
- pool = def_dppool;
} else {
type = IPPOOL_ADDRESS;
val = opt->name;
- pool = def_ippool;
}
- pool_name = NULL;
- parse_options(type, opt->raw, &pool_name, &next);
+ if (parse_options(type, opt->raw, &pool, &next)) {
+ log_error("ipv6_pool: failed to parse '%s'\n", opt->raw);
+ continue;
+ }
- if (pool_name)
- pool = find_pool(type, pool_name, 1);
add_prefix(type, pool, val);
- pool->next = next;
+ if (pool == next)
+ log_warn("ipv6_pool: %s: same next pool\n", opt->raw);
+ else if (next)
+ pool->next = next;
+ }
+
+ list_for_each_entry(pool, &ippool_list, entry) {
+ if (list_empty(&pool->items))
+ log_warn("ipv6_pool: pool '%s' is empty or not defined\n", pool->name);
+ }
+ list_for_each_entry(pool, &dppool_list, entry) {
+ if (list_empty(&pool->items))
+ log_warn("ipv6_pool: delegate pool '%s' is empty or not defined\n", pool->name);
}
#ifdef RADIUS