mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Teach --bogus-nxdomain and --ignore-address to take a subnet argument.
This commit is contained in:
@@ -25,7 +25,9 @@ version 2.85
|
|||||||
for routers with dynamically prefixes. Thanks
|
for routers with dynamically prefixes. Thanks
|
||||||
to Fred F for the suggestion.
|
to Fred F for the suggestion.
|
||||||
|
|
||||||
|
Teach --bogus-nxdomain and --ignore-address to take an IPv4 subnet.
|
||||||
|
|
||||||
|
|
||||||
version 2.84
|
version 2.84
|
||||||
Fix a problem, introduced in 2.83, which could see DNS replies
|
Fix a problem, introduced in 2.83, which could see DNS replies
|
||||||
being sent via the wrong socket. On machines running both
|
being sent via the wrong socket. On machines running both
|
||||||
|
|||||||
@@ -326,8 +326,8 @@ are re-written. So
|
|||||||
.B --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
|
.B --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
|
||||||
maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
|
maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
|
||||||
.TP
|
.TP
|
||||||
.B \-B, --bogus-nxdomain=<ipaddr>
|
.B \-B, --bogus-nxdomain=<ipaddr>[/prefix]
|
||||||
Transform replies which contain the IP address given into "No such
|
Transform replies which contain the IP specified address or subnet into "No such
|
||||||
domain" replies. This is intended to counteract a devious move made by
|
domain" replies. This is intended to counteract a devious move made by
|
||||||
Verisign in September 2003 when they started returning the address of
|
Verisign in September 2003 when they started returning the address of
|
||||||
an advertising web page in response to queries for unregistered names,
|
an advertising web page in response to queries for unregistered names,
|
||||||
@@ -335,8 +335,8 @@ instead of the correct NXDOMAIN response. This option tells dnsmasq to
|
|||||||
fake the correct response when it sees this behaviour. As at Sept 2003
|
fake the correct response when it sees this behaviour. As at Sept 2003
|
||||||
the IP address being returned by Verisign is 64.94.110.11
|
the IP address being returned by Verisign is 64.94.110.11
|
||||||
.TP
|
.TP
|
||||||
.B --ignore-address=<ipaddr>
|
.B --ignore-address=<ipaddr>[/prefix]
|
||||||
Ignore replies to A-record queries which include the specified address.
|
Ignore replies to A-record queries which include the specified address or subnet.
|
||||||
No error is generated, dnsmasq simply continues to listen for another reply.
|
No error is generated, dnsmasq simply continues to listen for another reply.
|
||||||
This is useful to defeat blocking strategies which rely on quickly supplying a
|
This is useful to defeat blocking strategies which rely on quickly supplying a
|
||||||
forged answer to a DNS request for certain domain, before the correct answer can arrive.
|
forged answer to a DNS request for certain domain, before the correct answer can arrive.
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ union all_addr {
|
|||||||
|
|
||||||
|
|
||||||
struct bogus_addr {
|
struct bogus_addr {
|
||||||
struct in_addr addr;
|
struct in_addr addr, mask;
|
||||||
struct bogus_addr *next;
|
struct bogus_addr *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1241,8 +1241,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
struct in_addr local_addr, struct in_addr local_netmask,
|
struct in_addr local_addr, struct in_addr local_netmask,
|
||||||
time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
|
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,
|
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||||
struct bogus_addr *baddr, time_t now);
|
time_t now);
|
||||||
int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
|
int check_for_ignored_address(struct dns_header *header, size_t qlen);
|
||||||
int check_for_local_domain(char *name, time_t now);
|
int check_for_local_domain(char *name, time_t now);
|
||||||
size_t resize_packet(struct dns_header *header, size_t plen,
|
size_t resize_packet(struct dns_header *header, size_t plen,
|
||||||
unsigned char *pheader, size_t hlen);
|
unsigned char *pheader, size_t hlen);
|
||||||
|
|||||||
@@ -738,7 +738,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (daemon->bogus_addr && rcode != NXDOMAIN &&
|
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;
|
munged = 1;
|
||||||
SET_RCODE(header, NXDOMAIN);
|
SET_RCODE(header, NXDOMAIN);
|
||||||
@@ -866,7 +866,7 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
daemon->log_source_addr = &forward->frec_src.source;
|
daemon->log_source_addr = &forward->frec_src.source;
|
||||||
|
|
||||||
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
|
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
|
||||||
check_for_ignored_address(header, n, daemon->ignore_addr))
|
check_for_ignored_address(header, n))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Note: if we send extra options in the EDNS0 header, we can't recreate
|
/* Note: if we send extra options in the EDNS0 header, we can't recreate
|
||||||
|
|||||||
17
src/option.c
17
src/option.c
@@ -2487,8 +2487,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
case LOPT_IGNORE_ADDR: /* --ignore-address */
|
case LOPT_IGNORE_ADDR: /* --ignore-address */
|
||||||
{
|
{
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
int prefix = 32;
|
||||||
unhide_metas(arg);
|
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));
|
struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
|
||||||
if (option == 'B')
|
if (option == 'B')
|
||||||
@@ -2501,12 +2507,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
baddr->next = daemon->ignore_addr;
|
baddr->next = daemon->ignore_addr;
|
||||||
daemon->ignore_addr = baddr;
|
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
|
break;
|
||||||
ret_err(gen_err); /* error */
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'a': /* --listen-address */
|
case 'a': /* --listen-address */
|
||||||
case LOPT_AUTHPEER: /* --auth-peer */
|
case LOPT_AUTHPEER: /* --auth-peer */
|
||||||
|
|||||||
@@ -1017,30 +1017,33 @@ int check_for_local_domain(char *name, time_t now)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the packet a reply with the answer address equal to addr?
|
static int check_bad_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, char *name, unsigned long *ttlp)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
int i, qtype, qclass, rdlen;
|
int i, qtype, qclass, rdlen;
|
||||||
unsigned long ttl;
|
unsigned long ttl;
|
||||||
struct bogus_addr *baddrp;
|
struct bogus_addr *baddrp;
|
||||||
|
struct in_addr addr;
|
||||||
|
|
||||||
/* skip over questions */
|
/* skip over questions */
|
||||||
if (!(p = skip_questions(header, qlen)))
|
if (!(p = skip_questions(header, qlen)))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
for (i = ntohs(header->ancount); i != 0; i--)
|
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 */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
|
if (!name && !(p = skip_name(p, header, qlen, 10)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
GETSHORT(qclass, p);
|
GETSHORT(qclass, p);
|
||||||
GETLONG(ttl, p);
|
GETLONG(ttl, p);
|
||||||
GETSHORT(rdlen, p);
|
GETSHORT(rdlen, p);
|
||||||
|
|
||||||
|
if (ttlp)
|
||||||
|
*ttlp = ttl;
|
||||||
|
|
||||||
if (qclass == C_IN && qtype == T_A)
|
if (qclass == C_IN && qtype == T_A)
|
||||||
{
|
{
|
||||||
@@ -1048,16 +1051,12 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (baddrp = baddr; baddrp; baddrp = baddrp->next)
|
for (baddrp = baddr; baddrp; baddrp = baddrp->next)
|
||||||
if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
|
{
|
||||||
{
|
memcpy(&addr, p, INADDRSZ);
|
||||||
/* Found a bogus address. Insert that info here, since there no SOA record
|
|
||||||
to get the ttl from in the normal processing */
|
if ((addr.s_addr & baddrp->mask.s_addr) == baddrp->addr.s_addr)
|
||||||
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 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ADD_RDLEN(header, p, qlen, rdlen))
|
if (!ADD_RDLEN(header, p, qlen, rdlen))
|
||||||
@@ -1067,43 +1066,31 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
|||||||
return 0;
|
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;
|
unsigned long ttl;
|
||||||
int i, qtype, qclass, rdlen;
|
|
||||||
struct bogus_addr *baddrp;
|
|
||||||
|
|
||||||
/* skip over questions */
|
if (check_bad_address(header, qlen, daemon->bogus_addr, name, &ttl))
|
||||||
if (!(p = skip_questions(header, qlen)))
|
|
||||||
return 0; /* bad packet */
|
|
||||||
|
|
||||||
for (i = ntohs(header->ancount); i != 0; i--)
|
|
||||||
{
|
{
|
||||||
if (!(p = skip_name(p, header, qlen, 10)))
|
/* Found a bogus address. Insert that info here, since there no SOA record
|
||||||
return 0; /* bad packet */
|
to get the ttl from in the normal processing */
|
||||||
|
cache_start_insert();
|
||||||
GETSHORT(qtype, p);
|
cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
|
||||||
GETSHORT(qclass, p);
|
cache_end_insert();
|
||||||
p += 4; /* TTL */
|
|
||||||
GETSHORT(rdlen, p);
|
return 1;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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,
|
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, ...)
|
unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
|
||||||
|
|||||||
Reference in New Issue
Block a user