mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-20 02:38:32 +00:00
Enhance --synth-domain to allow names with sequential integers.
This commit is contained in:
12
CHANGELOG
12
CHANGELOG
@@ -49,7 +49,17 @@ version 2.79
|
|||||||
Fix failure to delete dynamically created dhcp options
|
Fix failure to delete dynamically created dhcp options
|
||||||
from files in -dhcp-optsdir directories. Thanks to
|
from files in -dhcp-optsdir directories. Thanks to
|
||||||
Lindgren Fredrik for the bug report.
|
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
|
version 2.78
|
||||||
Fix logic of appending ".<layer>" to PXE basename. Thanks to Chris
|
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
|
for the reverse address-to-name mapping. Note that a name used in
|
||||||
--interface-name may not appear in /etc/hosts.
|
--interface-name may not appear in /etc/hosts.
|
||||||
.TP
|
.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
|
Create artificial A/AAAA and PTR records for an address range. The
|
||||||
records use the address, with periods (or colons for IPv6) replaced
|
records either seqential numbers or the address, with periods (or colons for IPv6) replaced with dashes.
|
||||||
with dashes.
|
|
||||||
|
|
||||||
An example should make this clearer.
|
An examples should make this clearer. First sequential numbers.
|
||||||
.B --synth-domain=thekelleys.org.uk,192.168.0.0/24,internal-
|
.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
|
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,
|
192.168.0.56 and a reverse query vice versa. The same applies to IPv6,
|
||||||
but IPv6 addresses may start with '::'
|
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
|
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
|
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
|
.TP
|
||||||
.B --add-mac[=base64|text]
|
.B --add-mac[=base64|text]
|
||||||
Add the MAC address of the requestor to DNS queries which are
|
Add the MAC address of the requestor to DNS queries which are
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ struct cond_domain {
|
|||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
struct in6_addr start6, end6;
|
struct in6_addr start6, end6;
|
||||||
#endif
|
#endif
|
||||||
int is6;
|
int is6, indexed;
|
||||||
struct cond_domain *next;
|
struct cond_domain *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
225
src/domain.c
225
src/domain.c
@@ -55,83 +55,133 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
|
|||||||
|
|
||||||
if (pref && *pref != 0)
|
if (pref && *pref != 0)
|
||||||
continue; /* prefix match fail */
|
continue; /* prefix match fail */
|
||||||
|
|
||||||
/* NB, must not alter name if we return zero */
|
if (c->indexed)
|
||||||
for (p = tail; *p; p++)
|
|
||||||
{
|
{
|
||||||
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;
|
continue;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
*p = 0;
|
||||||
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
|
|
||||||
continue;
|
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
|
#endif
|
||||||
|
}
|
||||||
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
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* swap . or : for - */
|
/* NB, must not alter name if we return zero */
|
||||||
for (p = tail; *p; p++)
|
for (p = tail; *p; p++)
|
||||||
if (*p == '-')
|
{
|
||||||
{
|
char c = *p;
|
||||||
if (prot == AF_INET)
|
|
||||||
*p = '.';
|
if ((c >='0' && c <= '9') || c == '-')
|
||||||
|
continue;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else
|
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
|
||||||
*p = ':';
|
continue;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/* 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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
/* restore name */
|
||||||
for (p = tail; *p; p++)
|
for (p = tail; *p; p++)
|
||||||
if (*p == '.' || *p == ':')
|
if (*p == '.' || *p == ':')
|
||||||
*p = '-';
|
*p = '-';
|
||||||
|
|
||||||
*p = '.';
|
*p = '.';
|
||||||
|
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -149,14 +199,22 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
*name = 0;
|
*name = 0;
|
||||||
if (c->prefix)
|
if (c->indexed)
|
||||||
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
|
{
|
||||||
|
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, ".", MAXDNAME);
|
||||||
strncat(name, c->domain, MAXDNAME);
|
strncat(name, c->domain, MAXDNAME);
|
||||||
|
|
||||||
@@ -169,23 +227,32 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
*name = 0;
|
*name = 0;
|
||||||
if (c->prefix)
|
if (c->indexed)
|
||||||
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 == ':')
|
|
||||||
{
|
{
|
||||||
*name = '0';
|
u64 index = addr6part(&addr->addr.addr6) - addr6part(&c->start6);
|
||||||
inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
|
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.... */
|
/* IPv6 presentation address can start with ":", but valid domain names
|
||||||
for (p = name; *p; p++)
|
cannot start with "-" so prepend a zero in that case. */
|
||||||
if (*p == ':' || *p == '.')
|
if (!c->prefix && *name == ':')
|
||||||
*p = '-';
|
{
|
||||||
|
*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, ".", MAXDNAME);
|
||||||
strncat(name, c->domain, 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;
|
char *netpart;
|
||||||
|
|
||||||
new->prefix = NULL;
|
new->prefix = NULL;
|
||||||
|
new->indexed = 0;
|
||||||
|
|
||||||
unhide_metas(comma);
|
unhide_metas(comma);
|
||||||
if ((netpart = split_chr(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
|
else
|
||||||
{
|
{
|
||||||
|
char *star;
|
||||||
new->next = daemon->synth_domains;
|
new->next = daemon->synth_domains;
|
||||||
daemon->synth_domains = new;
|
daemon->synth_domains = new;
|
||||||
|
if ((star = strrchr(new->prefix, '*')) && *(star+1) == 0)
|
||||||
|
{
|
||||||
|
*star = 0;
|
||||||
|
new->indexed = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (option == 's')
|
else if (option == 's')
|
||||||
|
|||||||
Reference in New Issue
Block a user