o***@sigexec.com
2017-02-13 23:31:21 UTC
From: Olivier Gayot <***@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 <***@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;
[ 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 <***@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
2.11.1