[Dnsmasq-discuss] [PATCH] Accept /32 and /0 as valid CIDR prefixes for rev-server directive

olivier.gayot at sigexec.com olivier.gayot at sigexec.com
Mon Feb 13 23:31:21 GMT 2017


From: Olivier Gayot <olivier.gayot at sigexec.com>

[ excerpt from the man page ]
The rev-server directive provides a syntactic sugar to make specifying
address-to-name queries easier. For example
--rev-server=1.2.3.0/24,192.168.0.1 is exactly equivalent to
--server=/3.2.1.in-addr.arpa/192.168.0.1

It is not mentioned in the man page but specifying anything but /8 or
/24 as the CIDR prefix has the same effect as specifying /16.

It is not a big deal for subnets on non-octet boundaries since they
cannot be represented using a single in-addr.arpa address. However, it
is unconvenient for /32 and /0 prefixes while their analogous server
directives behave as expected. E.g. the following server directives work
as expected:

    server=/42.10.168.192.in-addr.arpa/1.2.3.4
    server=/in-addr.arpa/1.2.3.4

but the following do not:

    rev-server=192.168.10.42/32,1.2.3.4
    rev-server=192.168.10.42/0,1.2.3.4

and, in practice, they behave the same as:

    server=/168.192.in-addr.arpa/1.2.3.4
    server=/168.192.in-addr.arpa/1.2.3.4

This strange behaviour is fixed by accepting /32 and /0 CIDR prefixes as
valid values. Any other value will still be considered the same as /16.

Signed-off-by: Olivier Gayot <olivier.gayot at sigexec.com>
---
 src/option.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/option.c b/src/option.c
index 4a5ef5f..eeca3d6 100644
--- a/src/option.c
+++ b/src/option.c
@@ -850,19 +850,30 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
 static struct server *add_rev4(struct in_addr addr, int msize)
 {
   struct server *serv = opt_malloc(sizeof(struct server));
-  in_addr_t  a = ntohl(addr.s_addr) >> 8;
+  in_addr_t  a = ntohl(addr.s_addr);
   char *p;
 
   memset(serv, 0, sizeof(struct server));
-  p = serv->domain = opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
-  
-  if (msize == 24)
-    p += sprintf(p, "%d.", a & 0xff);
-  a = a >> 8;
-  if (msize != 8)
-    p += sprintf(p, "%d.", a & 0xff);
-  a = a >> 8;
-  p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
+  p = serv->domain = opt_malloc(29); /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
+
+  switch (msize)
+    {
+    case 32:
+      p += sprintf(p, "%d.", a & 0xff);
+      /* fall through */
+    case 24:
+      p += sprintf(p, "%d.", (a >> 8) & 0xff);
+      /* fall through */
+    default:
+    case 16:
+      p += sprintf(p, "%d.", (a >> 16) & 0xff);
+      /* fall through */
+    case 8:
+      p += sprintf(p, "%d.in-addr.arpa", (a >> 24) & 0xff);
+      break;
+    case 0:
+      p += sprintf(p, "in-addr.arpa");
+    }
   
   serv->flags = SERV_HAS_DOMAIN;
   serv->next = daemon->servers;
-- 
2.11.1




More information about the Dnsmasq-discuss mailing list