Commit 6b2b564a authored by Simon Kelley's avatar Simon Kelley

Enhance --synth-domain to allow names with sequential integers.

parent 4f7bb57e
......@@ -49,7 +49,17 @@ version 2.79
Fix failure to delete dynamically created dhcp options
from files in -dhcp-optsdir directories. Thanks to
Lindgren Fredrik for the bug report.
Add to --synth-domain the ability to create names using
sequential numbers, as well as encodings of IP addresses.
For instance,
--synth-domain=thekelleys.org.uk,192.168.0.50,192.168.0.70,internal-*
creates 21 domain names of the form
internal-4.thekelleys.org.uk over the address range given, with
internal-0.thekelleys.org.uk being 192.168.0.50 and
internal-20.thekelleys.org.uk being 192.168.0.70
Thanks to Andy Hawkins for the suggestion.
version 2.78
Fix logic of appending ".<layer>" to PXE basename. Thanks to Chris
......
......@@ -626,13 +626,16 @@ address by repeating the flag; in that case the first instance is used
for the reverse address-to-name mapping. Note that a name used in
--interface-name may not appear in /etc/hosts.
.TP
.B --synth-domain=<domain>,<address range>[,<prefix>]
.B --synth-domain=<domain>,<address range>[,<prefix>[*]]
Create artificial A/AAAA and PTR records for an address range. The
records use the address, with periods (or colons for IPv6) replaced
with dashes.
records either seqential numbers or the address, with periods (or colons for IPv6) replaced with dashes.
An example should make this clearer.
.B --synth-domain=thekelleys.org.uk,192.168.0.0/24,internal-
An examples should make this clearer. First sequential numbers.
.B --synth-domain=thekelleys.org.uk,192.168.0.50,192.168.0.70,internal-*
results in the name internal-0.thekelleys.org.uk. returning 192.168.0.50, internal-1.thekelleys.org.uk returning 192.168.0.51 and so on. (note the *) The same principle applies to IPv6 addresses (where the numbers may be very large). Reverse lookups from address to name behave as expected.
Second,
.B --synth-domain=thekelleys.org.uk,192.168.0.0/24,internal- (no *)
will result in a query for internal-192-168-0-56.thekelleys.org.uk returning
192.168.0.56 and a reverse query vice versa. The same applies to IPv6,
but IPv6 addresses may start with '::'
......@@ -642,7 +645,7 @@ configured a zero is added in front of the label. ::1 becomes 0--1.
V4 mapped IPv6 addresses, which have a representation like ::ffff:1.2.3.4 are handled specially, and become like 0--ffff-1-2-3-4
The address range can be of the form
<ip address>,<ip address> or <ip address>/<netmask>
<ip address>,<ip address> or <ip address>/<netmask> in both forms of the option.
.TP
.B --add-mac[=base64|text]
Add the MAC address of the requestor to DNS queries which are
......
......@@ -839,7 +839,7 @@ struct cond_domain {
#ifdef HAVE_IPV6
struct in6_addr start6, end6;
#endif
int is6;
int is6, indexed;
struct cond_domain *next;
};
......
......@@ -55,83 +55,133 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
if (pref && *pref != 0)
continue; /* prefix match fail */
/* NB, must not alter name if we return zero */
for (p = tail; *p; p++)
if (c->indexed)
{
char c = *p;
for (p = tail; *p; p++)
{
char c = *p;
if (c < '0' || c > '9')
break;
}
if ((c >='0' && c <= '9') || c == '-')
if (*p != '.')
continue;
#ifdef HAVE_IPV6
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
continue;
#endif
*p = 0;
break;
}
if (*p != '.')
continue;
*p = 0;
#ifdef HAVE_IPV6
if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
{
/* special hack for v4-mapped. */
memcpy(tail, "::ffff:", 7);
for (p = tail + 7; *p; p++)
if (*p == '-')
*p = '.';
if (hostname_isequal(c->domain, p+1))
{
if (prot == AF_INET)
{
unsigned int index = atoi(tail);
if (!c->is6 &&
index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr))
{
addr->addr.addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
found = 1;
}
}
#ifdef HAVE_IPV6
else
{
u64 index = atoll(tail);
if (c->is6 &&
index <= addr6part(&c->end6) - addr6part(&c->start6))
{
u64 start = addr6part(&c->start6);
addr->addr.addr6 = c->start6;
setaddr6part(&addr->addr.addr6, start + index);
found = 1;
}
}
#endif
}
}
else
#endif
{
/* swap . or : for - */
/* NB, must not alter name if we return zero */
for (p = tail; *p; p++)
if (*p == '-')
{
if (prot == AF_INET)
*p = '.';
{
char c = *p;
if ((c >='0' && c <= '9') || c == '-')
continue;
#ifdef HAVE_IPV6
else
*p = ':';
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
continue;
#endif
}
}
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
{
if (prot == AF_INET)
{
if (!c->is6 &&
ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
found = 1;
break;
}
if (*p != '.')
continue;
*p = 0;
#ifdef HAVE_IPV6
if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
{
/* special hack for v4-mapped. */
memcpy(tail, "::ffff:", 7);
for (p = tail + 7; *p; p++)
if (*p == '-')
*p = '.';
}
else
#endif
{
u64 addrpart = addr6part(&addr->addr.addr6);
if (c->is6 &&
is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
found = 1;
/* swap . or : for - */
for (p = tail; *p; p++)
if (*p == '-')
{
if (prot == AF_INET)
*p = '.';
#ifdef HAVE_IPV6
else
*p = ':';
#endif
}
}
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
{
if (prot == AF_INET)
{
if (!c->is6 &&
ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
found = 1;
}
#ifdef HAVE_IPV6
else
{
u64 addrpart = addr6part(&addr->addr.addr6);
if (c->is6 &&
is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
found = 1;
}
#endif
}
}
/* restore name */
for (p = tail; *p; p++)
if (*p == '.' || *p == ':')
*p = '-';
*p = '.';
if (found)
return 1;
}
......@@ -149,14 +199,22 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
char *p;
*name = 0;
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
if (c->indexed)
{
unsigned int index = ntohl(addr->addr.addr4.s_addr) - ntohl(c->start.s_addr);
snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index);
}
else
{
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
for (p = name; *p; p++)
if (*p == '.')
*p = '-';
}
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
for (p = name; *p; p++)
if (*p == '.')
*p = '-';
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
......@@ -169,23 +227,32 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
char *p;
*name = 0;
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
/* IPv6 presentation address can start with ":", but valid domain names
cannot start with "-" so prepend a zero in that case. */
if (!c->prefix && *name == ':')
if (c->indexed)
{
*name = '0';
inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
u64 index = addr6part(&addr->addr.addr6) - addr6part(&c->start6);
snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
}
else
{
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
/* V4-mapped have periods.... */
for (p = name; *p; p++)
if (*p == ':' || *p == '.')
*p = '-';
/* IPv6 presentation address can start with ":", but valid domain names
cannot start with "-" so prepend a zero in that case. */
if (!c->prefix && *name == ':')
{
*name = '0';
inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
}
/* V4-mapped have periods.... */
for (p = name; *p; p++)
if (*p == ':' || *p == '.')
*p = '-';
}
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
......
......@@ -2071,7 +2071,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
char *netpart;
new->prefix = NULL;
new->indexed = 0;
unhide_metas(comma);
if ((netpart = split_chr(comma, '/')))
{
......@@ -2208,8 +2209,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
else
{
char *star;
new->next = daemon->synth_domains;
daemon->synth_domains = new;
if ((star = strrchr(new->prefix, '*')) && *(star+1) == 0)
{
*star = 0;
new->indexed = 1;
}
}
}
else if (option == 's')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment