Teach --bogus-nxdomain and --ignore-address to take a subnet argument.
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index e201b7a..20d687a 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -325,7 +325,7 @@
struct bogus_addr {
- struct in_addr addr;
+ struct in_addr addr, mask;
struct bogus_addr *next;
};
@@ -1241,8 +1241,8 @@
struct in_addr local_addr, struct in_addr local_netmask,
time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
- struct bogus_addr *baddr, time_t now);
-int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
+ time_t now);
+int check_for_ignored_address(struct dns_header *header, size_t qlen);
int check_for_local_domain(char *name, time_t now);
size_t resize_packet(struct dns_header *header, size_t plen,
unsigned char *pheader, size_t hlen);
diff --git a/src/forward.c b/src/forward.c
index 6bbf8a4..0ea829c 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -738,7 +738,7 @@
}
if (daemon->bogus_addr && rcode != NXDOMAIN &&
- check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
+ check_for_bogus_wildcard(header, n, daemon->namebuff, now))
{
munged = 1;
SET_RCODE(header, NXDOMAIN);
@@ -866,7 +866,7 @@
daemon->log_source_addr = &forward->frec_src.source;
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
- check_for_ignored_address(header, n, daemon->ignore_addr))
+ check_for_ignored_address(header, n))
return;
/* Note: if we send extra options in the EDNS0 header, we can't recreate
diff --git a/src/option.c b/src/option.c
index bfda212..b6ab7ce 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2487,8 +2487,14 @@
case LOPT_IGNORE_ADDR: /* --ignore-address */
{
struct in_addr addr;
+ int prefix = 32;
unhide_metas(arg);
- if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
+
+ if (!arg ||
+ ((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)) ||
+ (inet_pton(AF_INET, arg, &addr) != 1))
+ ret_err(gen_err); /* error */
+ else
{
struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
if (option == 'B')
@@ -2501,12 +2507,11 @@
baddr->next = daemon->ignore_addr;
daemon->ignore_addr = baddr;
}
- baddr->addr = addr;
+ baddr->mask.s_addr = htonl(~((1 << (32 - prefix)) - 1));
+ baddr->addr.s_addr = addr.s_addr & baddr->mask.s_addr;
}
- else
- ret_err(gen_err); /* error */
- break;
- }
+ break;
+ }
case 'a': /* --listen-address */
case LOPT_AUTHPEER: /* --auth-peer */
diff --git a/src/rfc1035.c b/src/rfc1035.c
index ea438c2..5a961b8 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1017,30 +1017,33 @@
return 0;
}
-/* Is the packet a reply with the answer address equal to addr?
- If so mung is into an NXDOMAIN reply and also put that information
- in the cache. */
-int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
- struct bogus_addr *baddr, time_t now)
+static int check_bad_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, char *name, unsigned long *ttlp)
{
unsigned char *p;
int i, qtype, qclass, rdlen;
unsigned long ttl;
struct bogus_addr *baddrp;
-
+ struct in_addr addr;
+
/* skip over questions */
if (!(p = skip_questions(header, qlen)))
return 0; /* bad packet */
for (i = ntohs(header->ancount); i != 0; i--)
{
- if (!extract_name(header, qlen, &p, name, 1, 10))
+ if (name && !extract_name(header, qlen, &p, name, 1, 10))
return 0; /* bad packet */
-
+
+ if (!name && !(p = skip_name(p, header, qlen, 10)))
+ return 0;
+
GETSHORT(qtype, p);
GETSHORT(qclass, p);
GETLONG(ttl, p);
GETSHORT(rdlen, p);
+
+ if (ttlp)
+ *ttlp = ttl;
if (qclass == C_IN && qtype == T_A)
{
@@ -1048,16 +1051,12 @@
return 0;
for (baddrp = baddr; baddrp; baddrp = baddrp->next)
- if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
- {
- /* Found a bogus address. Insert that info here, since there no SOA record
- to get the ttl from in the normal processing */
- cache_start_insert();
- cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
- cache_end_insert();
-
+ {
+ memcpy(&addr, p, INADDRSZ);
+
+ if ((addr.s_addr & baddrp->mask.s_addr) == baddrp->addr.s_addr)
return 1;
- }
+ }
}
if (!ADD_RDLEN(header, p, qlen, rdlen))
@@ -1067,43 +1066,31 @@
return 0;
}
-int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
+/* Is the packet a reply with the answer address equal to addr?
+ If so mung is into an NXDOMAIN reply and also put that information
+ in the cache. */
+int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, time_t now)
{
- unsigned char *p;
- int i, qtype, qclass, rdlen;
- struct bogus_addr *baddrp;
+ unsigned long ttl;
- /* skip over questions */
- if (!(p = skip_questions(header, qlen)))
- return 0; /* bad packet */
-
- for (i = ntohs(header->ancount); i != 0; i--)
+ if (check_bad_address(header, qlen, daemon->bogus_addr, name, &ttl))
{
- if (!(p = skip_name(p, header, qlen, 10)))
- return 0; /* bad packet */
-
- GETSHORT(qtype, p);
- GETSHORT(qclass, p);
- p += 4; /* TTL */
- GETSHORT(rdlen, p);
-
- if (qclass == C_IN && qtype == T_A)
- {
- if (!CHECK_LEN(header, p, qlen, INADDRSZ))
- return 0;
-
- for (baddrp = baddr; baddrp; baddrp = baddrp->next)
- if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
- return 1;
- }
-
- if (!ADD_RDLEN(header, p, qlen, rdlen))
- return 0;
+ /* Found a bogus address. Insert that info here, since there no SOA record
+ to get the ttl from in the normal processing */
+ cache_start_insert();
+ cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
+ cache_end_insert();
+
+ return 1;
}
-
+
return 0;
}
+int check_for_ignored_address(struct dns_header *header, size_t qlen)
+{
+ return check_bad_address(header, qlen, daemon->ignore_addr, NULL, NULL);
+}
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)