--domain=# is valid. --synth-domain=# isn't.

This commit is contained in:
Simon Kelley
2023-03-31 23:28:56 +01:00
parent c244d92d8a
commit 047256a6d8

View File

@@ -2568,179 +2568,182 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
case 's': /* --domain */ case 's': /* --domain */
case LOPT_SYNTH: /* --synth-domain */ case LOPT_SYNTH: /* --synth-domain */
if (strcmp (arg, "#") == 0) {
set_option_bool(OPT_RESOLV_DOMAIN); char *d, *d_raw = arg;
else comma = split(arg);
{ if (!(d = canonicalise_opt(d_raw)))
char *d, *d_raw = arg; ret_err(gen_err);
comma = split(arg); else
if (!(d = canonicalise_opt(d_raw))) {
ret_err(gen_err); free(d); /* allocate this again below. */
else if (comma)
{ {
free(d); /* allocate this again below. */ struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
if (comma) char *netpart;
{
struct cond_domain *new = opt_malloc(sizeof(struct cond_domain)); new->prefix = NULL;
char *netpart; new->indexed = 0;
new->prefixlen = 0;
new->prefix = NULL;
new->indexed = 0; unhide_metas(comma);
new->prefixlen = 0; if ((netpart = split_chr(comma, '/')))
{
unhide_metas(comma); int msize;
if ((netpart = split_chr(comma, '/')))
{ arg = split(netpart);
int msize; if (!atoi_check(netpart, &msize))
ret_err_free(gen_err, new);
arg = split(netpart); else if (inet_pton(AF_INET, comma, &new->start))
if (!atoi_check(netpart, &msize)) {
ret_err_free(gen_err, new); int mask;
else if (inet_pton(AF_INET, comma, &new->start))
{ if (msize > 32)
int mask; ret_err_free(_("bad prefix length"), new);
if (msize > 32) mask = (1 << (32 - msize)) - 1;
ret_err_free(_("bad prefix length"), new); 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)
{
if (option != 's')
{
if (!(new->prefix = canonicalise_opt(arg)) ||
strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
ret_err_free(_("bad prefix"), new);
}
else if (strcmp(arg, "local") != 0)
ret_err_free(gen_err, new);
else
{
/* local=/xxx.yyy.zzz.in-addr.arpa/ */
domain_rev4(0, NULL, &new->start, msize);
/* local=/<domain>/ */
/* d_raw can't failed to canonicalise here, checked above. */
add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
}
}
}
else if (inet_pton(AF_INET6, comma, &new->start6))
{
u64 mask, addrpart = addr6part(&new->start6);
if (msize > 128)
ret_err_free(_("bad prefix length"), new);
mask = (1LLU << (128 - msize)) - 1LLU;
new->is6 = 1;
new->prefixlen = msize;
/* prefix==64 overflows the mask calculation above */
if (msize <= 64)
mask = (u64)-1LL;
mask = (1 << (32 - msize)) - 1; new->end6 = new->start6;
new->is6 = 0; setaddr6part(&new->start6, addrpart & ~mask);
new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask); setaddr6part(&new->end6, addrpart | mask);
new->end.s_addr = new->start.s_addr | htonl(mask);
if (arg) if (arg)
{ {
if (option != 's') if (option != 's')
{ {
if (!(new->prefix = canonicalise_opt(arg)) || if (!(new->prefix = canonicalise_opt(arg)) ||
strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN) strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN)
ret_err_free(_("bad prefix"), new); ret_err_free(_("bad prefix"), new);
} }
else if (strcmp(arg, "local") != 0) else if (strcmp(arg, "local") != 0)
ret_err_free(gen_err, new); ret_err_free(gen_err, new);
else else
{ {
/* local=/xxx.yyy.zzz.in-addr.arpa/ */ /* generate the equivalent of
domain_rev4(0, NULL, &new->start, msize); local=/xxx.yyy.zzz.ip6.arpa/ */
domain_rev6(0, NULL, &new->start6, msize);
/* local=/<domain>/ */
/* d_raw can't failed to canonicalise here, checked above. */ /* local=/<domain>/ */
add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL); /* d_raw can't failed to canonicalise here, checked above. */
} add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
} }
} }
else if (inet_pton(AF_INET6, comma, &new->start6)) }
{ else
u64 mask, addrpart = addr6part(&new->start6); ret_err_free(gen_err, new);
}
if (msize > 128) else
ret_err_free(_("bad prefix length"), new); {
char *prefstr;
mask = (1LLU << (128 - msize)) - 1LLU; arg = split(comma);
prefstr = split(arg);
new->is6 = 1;
new->prefixlen = msize; if (inet_pton(AF_INET, comma, &new->start))
{
/* prefix==64 overflows the mask calculation above */ new->is6 = 0;
if (msize <= 64) if (!arg)
mask = (u64)-1LL; new->end.s_addr = new->start.s_addr;
else if (!inet_pton(AF_INET, arg, &new->end))
new->end6 = new->start6; ret_err_free(gen_err, new);
setaddr6part(&new->start6, addrpart & ~mask); }
setaddr6part(&new->end6, addrpart | mask); else if (inet_pton(AF_INET6, comma, &new->start6))
{
if (arg) new->is6 = 1;
{ if (!arg)
if (option != 's') memcpy(&new->end6, &new->start6, IN6ADDRSZ);
{ else if (!inet_pton(AF_INET6, arg, &new->end6))
if (!(new->prefix = canonicalise_opt(arg)) || ret_err_free(gen_err, new);
strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN) }
ret_err_free(_("bad prefix"), new); else if (option == 's')
} {
else if (strcmp(arg, "local") != 0) /* subnet from interface. */
ret_err_free(gen_err, new); new->interface = opt_string_alloc(comma);
else new->al = NULL;
{ }
/* generate the equivalent of else
local=/xxx.yyy.zzz.ip6.arpa/ */ ret_err_free(gen_err, new);
domain_rev6(0, NULL, &new->start6, msize);
if (option != 's' && prefstr)
/* local=/<domain>/ */ {
/* d_raw can't failed to canonicalise here, checked above. */ if (!(new->prefix = canonicalise_opt(prefstr)) ||
add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL); strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
} ret_err_free(_("bad prefix"), new);
} }
} }
else
ret_err_free(gen_err, new); new->domain = canonicalise_opt(d_raw);
} if (option == 's')
else {
{ new->next = daemon->cond_domain;
char *prefstr; daemon->cond_domain = new;
arg = split(comma); }
prefstr = split(arg); else
{
if (inet_pton(AF_INET, comma, &new->start)) char *star;
{ if (new->prefix &&
new->is6 = 0; (star = strrchr(new->prefix, '*'))
if (!arg) && *(star+1) == 0)
new->end.s_addr = new->start.s_addr; {
else if (!inet_pton(AF_INET, arg, &new->end)) *star = 0;
ret_err_free(gen_err, new); new->indexed = 1;
} if (new->is6 && new->prefixlen < 64)
else if (inet_pton(AF_INET6, comma, &new->start6)) ret_err_free(_("prefix length too small"), new);
{ }
new->is6 = 1; new->next = daemon->synth_domains;
if (!arg) daemon->synth_domains = new;
memcpy(&new->end6, &new->start6, IN6ADDRSZ); }
else if (!inet_pton(AF_INET6, arg, &new->end6)) }
ret_err_free(gen_err, new); else if (option == 's')
} {
else if (option == 's') if (strcmp (arg, "#") == 0)
{ set_option_bool(OPT_RESOLV_DOMAIN);
/* subnet from interface. */ else
new->interface = opt_string_alloc(comma); daemon->domain_suffix = canonicalise_opt(d_raw);
new->al = NULL; }
} else
else ret_err(gen_err);
ret_err_free(gen_err, new); }
if (option != 's' && prefstr) break;
{ }
if (!(new->prefix = canonicalise_opt(prefstr)) ||
strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
ret_err_free(_("bad prefix"), new);
}
}
new->domain = canonicalise_opt(d_raw);
if (option == 's')
{
new->next = daemon->cond_domain;
daemon->cond_domain = new;
}
else
{
char *star;
if (new->prefix &&
(star = strrchr(new->prefix, '*'))
&& *(star+1) == 0)
{
*star = 0;
new->indexed = 1;
if (new->is6 && new->prefixlen < 64)
ret_err_free(_("prefix length too small"), new);
}
new->next = daemon->synth_domains;
daemon->synth_domains = new;
}
}
else if (option == 's')
daemon->domain_suffix = canonicalise_opt(d_raw);
else
ret_err(gen_err);
}
}
break;
case LOPT_CPE_ID: /* --add-dns-client */ case LOPT_CPE_ID: /* --add-dns-client */
if (arg) if (arg)