mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Extend 79aba0f10a for multiple IPv6 addresses.
This commit is contained in:
@@ -271,26 +271,35 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
|
||||
{
|
||||
if (!context) /* called via find_config() from lease_update_from_configs() */
|
||||
return 1;
|
||||
|
||||
if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
|
||||
return 1;
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
if ((context->flags & CONTEXT_V6) && (config->flags & CONFIG_WILDCARD))
|
||||
return 1;
|
||||
#endif
|
||||
if (context->flags & CONTEXT_V6)
|
||||
{
|
||||
struct addrlist *addr_list;
|
||||
|
||||
for (; context; context = context->current)
|
||||
#ifdef HAVE_DHCP6
|
||||
if (context->flags & CONTEXT_V6)
|
||||
{
|
||||
if ((config->flags & CONFIG_ADDR6) && is_same_net6(&config->addr6, &context->start6, context->prefix))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (!(config->flags & CONFIG_ADDR6))
|
||||
return 1;
|
||||
|
||||
for (; context; context = context->current)
|
||||
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
|
||||
{
|
||||
if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
|
||||
return 1;
|
||||
|
||||
if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
|
||||
{
|
||||
if (!(config->flags & CONFIG_ADDR))
|
||||
return 1;
|
||||
|
||||
for (; context; context = context->current)
|
||||
if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -426,9 +435,19 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
||||
if (prot == AF_INET6 &&
|
||||
(!(conf_tmp = config_find_by_address6(configs, NULL, 0, &crec->addr.addr6)) || conf_tmp == config))
|
||||
{
|
||||
memcpy(&config->addr6, &crec->addr.addr6, IN6ADDRSZ);
|
||||
config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
|
||||
config->flags &= ~CONFIG_PREFIX;
|
||||
/* host must have exactly one address if comming from /etc/hosts. */
|
||||
if (!config->addr6 && (config->addr6 = whine_malloc(sizeof(struct addrlist))))
|
||||
{
|
||||
config->addr6->next = NULL;
|
||||
config->addr6->flags = 0;
|
||||
}
|
||||
|
||||
if (config->addr6 && !config->addr6->next && !(config->addr6->flags & (ADDRLIST_WILDCARD|ADDRLIST_PREFIX)))
|
||||
{
|
||||
memcpy(&config->addr6->addr.addr6, &crec->addr.addr6, IN6ADDRSZ);
|
||||
config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
13
src/dhcp6.c
13
src/dhcp6.c
@@ -423,10 +423,15 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
|
||||
struct dhcp_config *config;
|
||||
|
||||
for (config = configs; config; config = config->next)
|
||||
if ((config->flags & CONFIG_ADDR6) &&
|
||||
(!net || is_same_net6(&config->addr6, net, prefix)) &&
|
||||
is_same_net6(&config->addr6, addr, (config->flags & CONFIG_PREFIX) ? config->prefix : 128))
|
||||
return config;
|
||||
if (config->flags & CONFIG_ADDR6)
|
||||
{
|
||||
struct addrlist *addr_list;
|
||||
|
||||
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
|
||||
if ((!net || is_same_net6(&addr_list->addr.addr6, net, prefix) || ((addr_list->flags & ADDRLIST_WILDCARD) && prefix == 64)) &&
|
||||
is_same_net6(&addr_list->addr.addr6, addr, (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128))
|
||||
return config;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -374,9 +374,11 @@ struct ds_config {
|
||||
struct ds_config *next;
|
||||
};
|
||||
|
||||
#define ADDRLIST_LITERAL 1
|
||||
#define ADDRLIST_IPV6 2
|
||||
#define ADDRLIST_REVONLY 4
|
||||
#define ADDRLIST_LITERAL 1
|
||||
#define ADDRLIST_IPV6 2
|
||||
#define ADDRLIST_REVONLY 4
|
||||
#define ADDRLIST_PREFIX 8
|
||||
#define ADDRLIST_WILDCARD 16
|
||||
|
||||
struct addrlist {
|
||||
union all_addr addr;
|
||||
@@ -766,8 +768,7 @@ struct dhcp_config {
|
||||
char *hostname, *domain;
|
||||
struct dhcp_netid_list *netid;
|
||||
#ifdef HAVE_DHCP6
|
||||
struct in6_addr addr6;
|
||||
int prefix;
|
||||
struct addrlist *addr6;
|
||||
#endif
|
||||
struct in_addr addr;
|
||||
time_t decline_time;
|
||||
@@ -789,9 +790,7 @@ struct dhcp_config {
|
||||
#define CONFIG_DECLINED 1024 /* address declined by client */
|
||||
#define CONFIG_BANK 2048 /* from dhcp hosts file */
|
||||
#define CONFIG_ADDR6 4096
|
||||
#define CONFIG_WILDCARD 8192
|
||||
#define CONFIG_ADDR6_HOSTS 16384 /* address added by from /etc/hosts */
|
||||
#define CONFIG_PREFIX 32768 /* addr6 is a set, size given by prefix */
|
||||
|
||||
struct dhcp_opt {
|
||||
int opt, len, flags;
|
||||
|
||||
428
src/option.c
428
src/option.c
@@ -1020,15 +1020,30 @@ static void dhcp_config_free(struct dhcp_config *config)
|
||||
if (config)
|
||||
{
|
||||
struct hwaddr_config *hwaddr = config->hwaddr;
|
||||
|
||||
while (hwaddr)
|
||||
{
|
||||
struct hwaddr_config *tmp = hwaddr;
|
||||
hwaddr = hwaddr->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
dhcp_netid_list_free(config->netid);
|
||||
|
||||
if (config->flags & CONFIG_CLID)
|
||||
free(config->clid);
|
||||
|
||||
if (config->flags & CONFIG_ADDR6)
|
||||
{
|
||||
struct addrlist *addr, *tmp;
|
||||
|
||||
for (addr = config->addr6; addr; addr = tmp)
|
||||
{
|
||||
tmp = addr->next;
|
||||
free(addr);
|
||||
}
|
||||
}
|
||||
|
||||
free(config);
|
||||
}
|
||||
}
|
||||
@@ -3193,8 +3208,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case LOPT_BANK:
|
||||
case 'G': /* --dhcp-host */
|
||||
{
|
||||
int j, k = 0;
|
||||
char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
struct dhcp_config *new;
|
||||
struct in_addr in;
|
||||
|
||||
@@ -3205,215 +3218,222 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
new->hwaddr = NULL;
|
||||
new->netid = NULL;
|
||||
new->clid = NULL;
|
||||
new->addr6 = NULL;
|
||||
|
||||
if ((a[0] = arg))
|
||||
for (k = 1; k < 7; k++)
|
||||
if (!(a[k] = split(a[k-1])))
|
||||
break;
|
||||
|
||||
for (j = 0; j < k; j++)
|
||||
if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */
|
||||
{
|
||||
char *arg = a[j];
|
||||
|
||||
if ((arg[0] == 'i' || arg[0] == 'I') &&
|
||||
(arg[1] == 'd' || arg[1] == 'D') &&
|
||||
arg[2] == ':')
|
||||
{
|
||||
if (arg[3] == '*')
|
||||
new->flags |= CONFIG_NOCLID;
|
||||
else
|
||||
{
|
||||
int len;
|
||||
arg += 3; /* dump id: */
|
||||
if (strchr(arg, ':'))
|
||||
len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
|
||||
else
|
||||
{
|
||||
unhide_metas(arg);
|
||||
len = (int) strlen(arg);
|
||||
}
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad hex constant"));
|
||||
}
|
||||
else if ((new->clid = opt_malloc(len)))
|
||||
{
|
||||
new->flags |= CONFIG_CLID;
|
||||
new->clid_len = len;
|
||||
memcpy(new->clid, arg, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* dhcp-host has strange backwards-compat needs. */
|
||||
else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
|
||||
{
|
||||
struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
|
||||
newlist->next = new->netid;
|
||||
new->netid = newlist;
|
||||
newlist->list = dhcp_netid_create(arg+4, NULL);
|
||||
}
|
||||
else if (strstr(arg, "tag:") == arg)
|
||||
{
|
||||
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("cannot match tags in --dhcp-host"));
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
|
||||
{
|
||||
char *pref;
|
||||
|
||||
arg[strlen(arg)-1] = 0;
|
||||
arg++;
|
||||
pref = split_chr(arg, '/');
|
||||
|
||||
if (!inet_pton(AF_INET6, arg, &new->addr6))
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad IPv6 address"));
|
||||
}
|
||||
|
||||
if (pref)
|
||||
{
|
||||
u64 addrpart = addr6part(&new->addr6);
|
||||
|
||||
if (!atoi_check(pref, &new->prefix) ||
|
||||
new->prefix > 128 ||
|
||||
(((1<<(128-new->prefix))-1) & addrpart) != 0)
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad IPv6 prefix"));
|
||||
}
|
||||
|
||||
new->flags |= CONFIG_PREFIX;
|
||||
}
|
||||
|
||||
for (i= 0; i < 8; i++)
|
||||
if (new->addr6.s6_addr[i] != 0)
|
||||
break;
|
||||
|
||||
/* set WILDCARD if network part all zeros */
|
||||
if (i == 8)
|
||||
new->flags |= CONFIG_WILDCARD;
|
||||
|
||||
new->flags |= CONFIG_ADDR6;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
|
||||
if ((newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX,
|
||||
&newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
|
||||
{
|
||||
free(newhw);
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad hex constant"));
|
||||
}
|
||||
else
|
||||
{
|
||||
newhw->next = new->hwaddr;
|
||||
new->hwaddr = newhw;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strchr(a[j], '.') && (inet_pton(AF_INET, a[j], &in) > 0))
|
||||
{
|
||||
struct dhcp_config *configs;
|
||||
|
||||
new->addr = in;
|
||||
new->flags |= CONFIG_ADDR;
|
||||
|
||||
/* If the same IP appears in more than one host config, then DISCOVER
|
||||
for one of the hosts will get the address, but REQUEST will be NAKed,
|
||||
since the address is reserved by the other one -> protocol loop. */
|
||||
for (configs = daemon->dhcp_conf; configs; configs = configs->next)
|
||||
if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
|
||||
while (arg)
|
||||
{
|
||||
comma = split(arg);
|
||||
if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */
|
||||
{
|
||||
if ((arg[0] == 'i' || arg[0] == 'I') &&
|
||||
(arg[1] == 'd' || arg[1] == 'D') &&
|
||||
arg[2] == ':')
|
||||
{
|
||||
sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *cp, *lastp = NULL, last = 0;
|
||||
int fac = 1, isdig = 0;
|
||||
|
||||
if (strlen(a[j]) > 1)
|
||||
{
|
||||
lastp = a[j] + strlen(a[j]) - 1;
|
||||
last = *lastp;
|
||||
switch (last)
|
||||
{
|
||||
case 'w':
|
||||
case 'W':
|
||||
fac *= 7;
|
||||
/* fall through */
|
||||
case 'd':
|
||||
case 'D':
|
||||
fac *= 24;
|
||||
/* fall through */
|
||||
case 'h':
|
||||
case 'H':
|
||||
fac *= 60;
|
||||
/* fall through */
|
||||
case 'm':
|
||||
case 'M':
|
||||
fac *= 60;
|
||||
/* fall through */
|
||||
case 's':
|
||||
case 'S':
|
||||
*lastp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (cp = a[j]; *cp; cp++)
|
||||
if (isdigit((unsigned char)*cp))
|
||||
isdig = 1;
|
||||
else if (*cp != ' ')
|
||||
break;
|
||||
if (arg[3] == '*')
|
||||
new->flags |= CONFIG_NOCLID;
|
||||
else
|
||||
{
|
||||
int len;
|
||||
arg += 3; /* dump id: */
|
||||
if (strchr(arg, ':'))
|
||||
len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
|
||||
else
|
||||
{
|
||||
unhide_metas(arg);
|
||||
len = (int) strlen(arg);
|
||||
}
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad hex constant"));
|
||||
}
|
||||
else if ((new->clid = opt_malloc(len)))
|
||||
{
|
||||
new->flags |= CONFIG_CLID;
|
||||
new->clid_len = len;
|
||||
memcpy(new->clid, arg, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* dhcp-host has strange backwards-compat needs. */
|
||||
else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
|
||||
{
|
||||
struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
|
||||
newlist->next = new->netid;
|
||||
new->netid = newlist;
|
||||
newlist->list = dhcp_netid_create(arg+4, NULL);
|
||||
}
|
||||
else if (strstr(arg, "tag:") == arg)
|
||||
{
|
||||
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("cannot match tags in --dhcp-host"));
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
|
||||
{
|
||||
char *pref;
|
||||
struct in6_addr in6;
|
||||
struct addrlist *new_addr;
|
||||
|
||||
arg[strlen(arg)-1] = 0;
|
||||
arg++;
|
||||
pref = split_chr(arg, '/');
|
||||
|
||||
if (!inet_pton(AF_INET6, arg, &in6))
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad IPv6 address"));
|
||||
}
|
||||
|
||||
if (*cp)
|
||||
{
|
||||
if (lastp)
|
||||
*lastp = last;
|
||||
if (strcmp(a[j], "infinite") == 0)
|
||||
new_addr = opt_malloc(sizeof(struct addrlist));
|
||||
new_addr->next = new->addr6;
|
||||
new_addr->flags = 0;
|
||||
new_addr->addr.addr6 = in6;
|
||||
new->addr6 = new_addr;
|
||||
|
||||
if (pref)
|
||||
{
|
||||
u64 addrpart = addr6part(&in6);
|
||||
|
||||
if (!atoi_check(pref, &new_addr->prefixlen) ||
|
||||
new_addr->prefixlen > 128 ||
|
||||
(((1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad IPv6 prefix"));
|
||||
}
|
||||
|
||||
new_addr->flags |= ADDRLIST_PREFIX;
|
||||
}
|
||||
|
||||
for (i= 0; i < 8; i++)
|
||||
if (in6.s6_addr[i] != 0)
|
||||
break;
|
||||
|
||||
/* set WILDCARD if network part all zeros */
|
||||
if (i == 8)
|
||||
new_addr->flags |= ADDRLIST_WILDCARD;
|
||||
|
||||
new->flags |= CONFIG_ADDR6;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
|
||||
if ((newhw->hwaddr_len = parse_hex(arg, newhw->hwaddr, DHCP_CHADDR_MAX,
|
||||
&newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
|
||||
{
|
||||
free(newhw);
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad hex constant"));
|
||||
}
|
||||
else
|
||||
{
|
||||
newhw->next = new->hwaddr;
|
||||
new->hwaddr = newhw;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0))
|
||||
{
|
||||
struct dhcp_config *configs;
|
||||
|
||||
new->addr = in;
|
||||
new->flags |= CONFIG_ADDR;
|
||||
|
||||
/* If the same IP appears in more than one host config, then DISCOVER
|
||||
for one of the hosts will get the address, but REQUEST will be NAKed,
|
||||
since the address is reserved by the other one -> protocol loop. */
|
||||
for (configs = daemon->dhcp_conf; configs; configs = configs->next)
|
||||
if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
|
||||
{
|
||||
new->lease_time = 0xffffffff;
|
||||
new->flags |= CONFIG_TIME;
|
||||
}
|
||||
else if (strcmp(a[j], "ignore") == 0)
|
||||
new->flags |= CONFIG_DISABLE;
|
||||
else
|
||||
{
|
||||
if (!(new->hostname = canonicalise_opt(a[j])) ||
|
||||
!legal_hostname(new->hostname))
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad DHCP host name"));
|
||||
}
|
||||
|
||||
new->flags |= CONFIG_NAME;
|
||||
new->domain = strip_hostname(new->hostname);
|
||||
}
|
||||
}
|
||||
else if (isdig)
|
||||
{
|
||||
new->lease_time = atoi(a[j]) * fac;
|
||||
/* Leases of a minute or less confuse
|
||||
some clients, notably Apple's */
|
||||
if (new->lease_time < 120)
|
||||
new->lease_time = 120;
|
||||
new->flags |= CONFIG_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *cp, *lastp = NULL, last = 0;
|
||||
int fac = 1, isdig = 0;
|
||||
|
||||
if (strlen(arg) > 1)
|
||||
{
|
||||
lastp = arg + strlen(arg) - 1;
|
||||
last = *lastp;
|
||||
switch (last)
|
||||
{
|
||||
case 'w':
|
||||
case 'W':
|
||||
fac *= 7;
|
||||
/* fall through */
|
||||
case 'd':
|
||||
case 'D':
|
||||
fac *= 24;
|
||||
/* fall through */
|
||||
case 'h':
|
||||
case 'H':
|
||||
fac *= 60;
|
||||
/* fall through */
|
||||
case 'm':
|
||||
case 'M':
|
||||
fac *= 60;
|
||||
/* fall through */
|
||||
case 's':
|
||||
case 'S':
|
||||
*lastp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (cp = arg; *cp; cp++)
|
||||
if (isdigit((unsigned char)*cp))
|
||||
isdig = 1;
|
||||
else if (*cp != ' ')
|
||||
break;
|
||||
|
||||
if (*cp)
|
||||
{
|
||||
if (lastp)
|
||||
*lastp = last;
|
||||
if (strcmp(arg, "infinite") == 0)
|
||||
{
|
||||
new->lease_time = 0xffffffff;
|
||||
new->flags |= CONFIG_TIME;
|
||||
}
|
||||
else if (strcmp(arg, "ignore") == 0)
|
||||
new->flags |= CONFIG_DISABLE;
|
||||
else
|
||||
{
|
||||
if (!(new->hostname = canonicalise_opt(arg)) ||
|
||||
!legal_hostname(new->hostname))
|
||||
{
|
||||
dhcp_config_free(new);
|
||||
ret_err(_("bad DHCP host name"));
|
||||
}
|
||||
|
||||
new->flags |= CONFIG_NAME;
|
||||
new->domain = strip_hostname(new->hostname);
|
||||
}
|
||||
}
|
||||
else if (isdig)
|
||||
{
|
||||
new->lease_time = atoi(arg) * fac;
|
||||
/* Leases of a minute or less confuse
|
||||
some clients, notably Apple's */
|
||||
if (new->lease_time < 120)
|
||||
new->lease_time = 120;
|
||||
new->flags |= CONFIG_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
arg = comma;
|
||||
}
|
||||
|
||||
daemon->dhcp_conf = new;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case LOPT_TAG_IF: /* --tag-if */
|
||||
{
|
||||
struct tag_if *new = opt_malloc(sizeof(struct tag_if));
|
||||
|
||||
@@ -1671,68 +1671,72 @@ static int config_implies(struct dhcp_config *config, struct dhcp_context *conte
|
||||
{
|
||||
int prefix;
|
||||
struct in6_addr wild_addr;
|
||||
|
||||
struct addrlist *addr_list;
|
||||
|
||||
if (!config || !(config->flags & CONFIG_ADDR6))
|
||||
return 0;
|
||||
|
||||
prefix = (config->flags & CONFIG_PREFIX) ? config->prefix : 128;
|
||||
wild_addr = config->addr6;
|
||||
|
||||
if (!is_same_net6(&context->start6, addr, context->prefix))
|
||||
return 0;
|
||||
|
||||
if ((config->flags & CONFIG_WILDCARD))
|
||||
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
|
||||
{
|
||||
if (context->prefix != 64)
|
||||
return 0;
|
||||
prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128;
|
||||
wild_addr = addr_list->addr.addr6;
|
||||
|
||||
wild_addr = context->start6;
|
||||
setaddr6part(&wild_addr, addr6part(&config->addr6));
|
||||
if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
|
||||
{
|
||||
wild_addr = context->start6;
|
||||
setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr6));
|
||||
}
|
||||
else if (!is_same_net6(&context->start6, addr, context->prefix))
|
||||
continue;
|
||||
|
||||
if (is_same_net6(&wild_addr, addr, prefix))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (is_same_net6(&wild_addr, addr, prefix))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state)
|
||||
{
|
||||
u64 addrpart;
|
||||
|
||||
struct addrlist *addr_list;
|
||||
|
||||
if (!config || !(config->flags & CONFIG_ADDR6))
|
||||
return 0;
|
||||
|
||||
addrpart = addr6part(&config->addr6);
|
||||
|
||||
if ((config->flags & CONFIG_WILDCARD))
|
||||
for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
|
||||
{
|
||||
if (context->prefix != 64)
|
||||
return 0;
|
||||
|
||||
*addr = context->start6;
|
||||
setaddr6part(addr, addrpart);
|
||||
}
|
||||
else if (is_same_net6(&context->start6, &config->addr6, context->prefix))
|
||||
*addr = config->addr6;
|
||||
else
|
||||
return 0;
|
||||
addrpart = addr6part(&addr_list->addr.addr6);
|
||||
|
||||
while(1) {
|
||||
if (check_address(state, addr))
|
||||
return 1;
|
||||
|
||||
if (!(config->flags & CONFIG_PREFIX))
|
||||
return 0;
|
||||
|
||||
/* config may specify a set of addresses, return first one not in use
|
||||
by another client */
|
||||
|
||||
addrpart++;
|
||||
setaddr6part(addr, addrpart);
|
||||
if (!is_same_net6(addr, &config->addr6, config->prefix))
|
||||
return 0;
|
||||
}
|
||||
if ((addr_list->flags & ADDRLIST_WILDCARD))
|
||||
{
|
||||
if (context->prefix != 64)
|
||||
continue;
|
||||
|
||||
*addr = context->start6;
|
||||
setaddr6part(addr, addrpart);
|
||||
}
|
||||
else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix))
|
||||
*addr = addr_list->addr.addr6;
|
||||
else
|
||||
continue;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (check_address(state, addr))
|
||||
return 1;
|
||||
|
||||
if (!(addr_list->flags & ADDRLIST_PREFIX))
|
||||
break;
|
||||
|
||||
addrpart++;
|
||||
setaddr6part(addr, addrpart);
|
||||
if (!is_same_net6(addr, &addr_list->addr.addr6, addr_list->prefixlen))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate valid and preferred times to send in leases/renewals.
|
||||
|
||||
Reference in New Issue
Block a user