Enhance --synth-domain to allow names with sequential integers.
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index f4d330a..6773b69 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -839,7 +839,7 @@
#ifdef HAVE_IPV6
struct in6_addr start6, end6;
#endif
- int is6;
+ int is6, indexed;
struct cond_domain *next;
};
diff --git a/src/domain.c b/src/domain.c
index 853dc17..04d7cf8 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -55,83 +55,133 @@
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;
+ *p = 0;
+
+ 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
-
- 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 - */
+ /* 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
- }
+
+ 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 */
for (p = tail; *p; p++)
if (*p == '.' || *p == ':')
*p = '-';
*p = '.';
-
+
+
if (found)
return 1;
}
@@ -149,14 +199,22 @@
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 @@
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);
diff --git a/src/option.c b/src/option.c
index 6b26576..d358d99 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2071,7 +2071,8 @@
char *netpart;
new->prefix = NULL;
-
+ new->indexed = 0;
+
unhide_metas(comma);
if ((netpart = split_chr(comma, '/')))
{
@@ -2208,8 +2209,14 @@
}
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')