IPv6 address range parsing for --domain.

Counted string DHCP option type printing
This commit is contained in:
Simon Kelley
2012-02-07 20:51:56 +00:00
parent 70c5e3e076
commit d74942a03d
3 changed files with 126 additions and 28 deletions

View File

@@ -913,7 +913,8 @@ char *get_domain(struct in_addr addr)
struct cond_domain *c;
for (c = daemon->cond_domain; c; c = c->next)
if (ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
if (!c->is6 &&
ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
return c->domain;
@@ -924,14 +925,15 @@ char *get_domain(struct in_addr addr)
#ifdef HAVE_IPV6
char *get_domain6(struct in6_addr *addr)
{
struct cond_domain6 *c;
struct cond_domain *c;
u64 addrpart = addr6part(addr);
for (c = daemon->cond_domain6; c; c = c->next)
if (is_same_net6(addr, &c->start, 64) &&
addrpart >= addr6part(&c->start) &&
addrpart <= addr6part(&c->end))
for (c = daemon->cond_domain; c; c = c->next)
if (c->is6 &&
is_same_net6(addr, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
return c->domain;
return daemon->domain_suffix;

View File

@@ -588,15 +588,13 @@ struct dhcp_bridge {
struct cond_domain {
char *domain;
struct in_addr start, end;
#ifdef HAVE_IPV6
struct in6_addr start6, end6;
#endif
int is6;
struct cond_domain *next;
};
struct cond_domain6 {
char *domain;
struct in6_addr start, end;
struct cond_domain6 *next;
};
struct dhcp_context {
unsigned int lease_time, addr_epoch;
struct in_addr netmask, broadcast;
@@ -683,7 +681,6 @@ extern struct daemon {
int group_set, osport;
char *domain_suffix;
struct cond_domain *cond_domain;
struct cond_domain6 *cond_domain6;
char *runfile;
char *lease_change_command;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except;

View File

@@ -543,6 +543,30 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
buf[j++] = '.';
}
}
else if ((ot[o].size & OT_CSTRING))
{
int k, len;
unsigned char *p;
i = 0, j = 0;
while (1)
{
p = &val[i];
GETSHORT(len, p);
for (k = 0; k < len && j < buf_len; k++)
{
char c = *p++;
if (isprint((int)c))
buf[j++] = c;
}
i += len +2;
if (i >= opt_len)
break;
if (j < buf_len)
buf[j++] = ',';
}
}
#endif
else
nodecode = 1;
@@ -1628,14 +1652,15 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
unhide_metas(comma);
if ((netpart = split_chr(comma, '/')))
{
int msize, mask;
int msize;
arg = split(netpart);
if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 ||
!atoi_check(netpart, &msize))
if (!atoi_check(netpart, &msize))
option = '?';
else
else if (inet_pton(AF_INET, comma, &new->start))
{
mask = (1 << (32 - msize)) - 1;
int mask = (1 << (32 - msize)) - 1;
new->is6 = 0;
new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
new->end.s_addr = new->start.s_addr | htonl(mask);
if (arg)
@@ -1677,19 +1702,93 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
}
}
}
}
else if ((arg = split(comma)))
#ifdef HAVE_IPV6
else if (inet_pton(AF_INET6, comma, &new->start6))
{
if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 ||
(new->end.s_addr = inet_addr(arg)) == (in_addr_t)-1)
u64 mask = (1LLU << (128 - msize)) - 1LLU;
u64 addrpart = addr6part(&new->start6);
new->is6 = 1;
/* prefix==64 overflows the mask calculation above */
if (msize == 64)
mask = (u64)-1LL;
new->end6 = new->start6;
setaddr6part(&new->start6, addrpart & ~mask);
setaddr6part(&new->end6, addrpart | mask);
if (msize < 64)
option = '?';
else if (arg)
{
/* generate the equivalent of
local=/<domain>/
local=/xxx.yyy.zzz.ip6.arpa/ */
if (strcmp(arg, "local") != 0 || (msize & 4 != 0))
option = '?';
else
{
struct server *serv = opt_malloc(sizeof(struct server));
in_addr_t a = ntohl(new->start.s_addr) >> 8;
char *p;
memset(serv, 0, sizeof(struct server));
serv->domain = d;
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
serv->next = daemon->servers;
daemon->servers = serv;
serv = opt_malloc(sizeof(struct server));
memset(serv, 0, sizeof(struct server));
p = serv->domain = opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
for (i = msize-1; i >= 0; i -= 4)
{
int dig = ((unsigned char *)&new->start6)[i>>3];
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
}
p += sprintf(p, "ip6.arpa");
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
serv->next = daemon->servers;
daemon->servers = serv;
}
}
}
#endif
else
option = '?';
}
else if ((new->start.s_addr = new->end.s_addr = inet_addr(comma)) == (in_addr_t)-1)
else
{
arg = split(comma);
if (inet_pton(AF_INET, comma, &new->start))
{
new->is6 = 0;
if (!arg)
new->end.s_addr = new->start.s_addr;
else if (!inet_pton(AF_INET, arg, &new->end))
option = '?';
}
#ifdef HAVE_IPV6
else if (inet_pton(AF_INET6, comma, &new->start6))
{
new->is6 = 1;
if (!arg)
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
else if (!inet_pton(AF_INET6, arg, &new->end6))
option = '?';
}
#endif
else
option = '?';
new->domain = d;
new->next = daemon->cond_domain;
daemon->cond_domain = new;
}
}
else
daemon->domain_suffix = d;