Commit 32fc6dbe authored by Glen Huang's avatar Glen Huang Committed by Simon Kelley

Add --ignore-address option.

parent 83d2ed09
...@@ -22,6 +22,14 @@ version 2.73 ...@@ -22,6 +22,14 @@ version 2.73
Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids
for the bug report. for the bug report.
Add --ignore-address option. Ignore replies to A-record
queries which include the specified address. 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 forged answer to a DNS
request for certain domains, before the correct answer can
arrive. Thanks to Glen Huang for the patch.
version 2.72 version 2.72
......
...@@ -293,6 +293,12 @@ an advertising web page in response to queries for unregistered names, ...@@ -293,6 +293,12 @@ an advertising web page in response to queries for unregistered names,
instead of the correct NXDOMAIN response. This option tells dnsmasq to 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
.B \-B, --ignore-address=<ipaddr>
Ignore replies to A-record queries which include the specified address.
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
forged answer to a DNS request for certain domain, before the correct answer can arrive.
.TP .TP
.B \-f, --filterwin2k .B \-f, --filterwin2k
Later versions of windows make periodic DNS requests which don't get sensible answers from Later versions of windows make periodic DNS requests which don't get sensible answers from
......
...@@ -930,7 +930,7 @@ extern struct daemon { ...@@ -930,7 +930,7 @@ extern struct daemon {
char *runfile; char *runfile;
char *lease_change_command; char *lease_change_command;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces; struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
struct bogus_addr *bogus_addr; struct bogus_addr *bogus_addr, *ignore_addr;
struct server *servers; struct server *servers;
struct ipsets *ipsets; struct ipsets *ipsets;
int log_fac; /* log facility */ int log_fac; /* log facility */
...@@ -1093,6 +1093,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, ...@@ -1093,6 +1093,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
time_t now, int *ad_reqd, int *do_bit); time_t now, int *ad_reqd, int *do_bit);
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 *addr, time_t now); struct bogus_addr *addr, time_t now);
int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
size_t *len, unsigned char **p, int *is_sign); size_t *len, unsigned char **p, int *is_sign);
int check_for_local_domain(char *name, time_t now); int check_for_local_domain(char *name, time_t now);
......
...@@ -724,6 +724,10 @@ void reply_query(int fd, int family, time_t now) ...@@ -724,6 +724,10 @@ void reply_query(int fd, int family, time_t now)
if (!(forward = lookup_frec(ntohs(header->id), hash))) if (!(forward = lookup_frec(ntohs(header->id), hash)))
return; return;
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
check_for_ignored_address(header, n, daemon->ignore_addr))
return;
if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) && if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) &&
!option_bool(OPT_ORDER) && !option_bool(OPT_ORDER) &&
forward->forwardall == 0) forward->forwardall == 0)
......
...@@ -147,6 +147,7 @@ struct myoption { ...@@ -147,6 +147,7 @@ struct myoption {
#define LOPT_LOCAL_SERVICE 335 #define LOPT_LOCAL_SERVICE 335
#define LOPT_DNSSEC_TIME 336 #define LOPT_DNSSEC_TIME 336
#define LOPT_LOOP_DETECT 337 #define LOPT_LOOP_DETECT 337
#define LOPT_IGNORE_ADDR 338
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
static const struct option opts[] = static const struct option opts[] =
...@@ -181,6 +182,7 @@ static const struct myoption opts[] = ...@@ -181,6 +182,7 @@ static const struct myoption opts[] =
{ "local-service", 0, 0, LOPT_LOCAL_SERVICE }, { "local-service", 0, 0, LOPT_LOCAL_SERVICE },
{ "bogus-priv", 0, 0, 'b' }, { "bogus-priv", 0, 0, 'b' },
{ "bogus-nxdomain", 1, 0, 'B' }, { "bogus-nxdomain", 1, 0, 'B' },
{ "ignore-address", 1, 0, LOPT_IGNORE_ADDR },
{ "selfmx", 0, 0, 'e' }, { "selfmx", 0, 0, 'e' },
{ "filterwin2k", 0, 0, 'f' }, { "filterwin2k", 0, 0, 'f' },
{ "pid-file", 2, 0, 'x' }, { "pid-file", 2, 0, 'x' },
...@@ -457,6 +459,7 @@ static struct { ...@@ -457,6 +459,7 @@ static struct {
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL }, { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
{ LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks"), NULL }, { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks"), NULL },
{ LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops"), NULL }, { LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops"), NULL },
{ LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
{ 0, 0, NULL, NULL, NULL } { 0, 0, NULL, NULL, NULL }
}; };
...@@ -2119,14 +2122,23 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -2119,14 +2122,23 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break; break;
case 'B': /* --bogus-nxdomain */ case 'B': /* --bogus-nxdomain */
{ case LOPT_IGNORE_ADDR: /* --ignore-address */
{
struct in_addr addr; struct in_addr addr;
unhide_metas(arg); unhide_metas(arg);
if (arg && (inet_pton(AF_INET, arg, &addr) > 0)) if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
{ {
struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr)); struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
baddr->next = daemon->bogus_addr; if (option == 'B')
daemon->bogus_addr = baddr; {
baddr->next = daemon->bogus_addr;
daemon->bogus_addr = baddr;
}
else
{
baddr->next = daemon->ignore_addr;
daemon->ignore_addr = baddr;
}
baddr->addr = addr; baddr->addr = addr;
} }
else else
......
...@@ -1328,6 +1328,43 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, ...@@ -1328,6 +1328,43 @@ 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)
{
unsigned char *p;
int i, qtype, qclass, rdlen;
struct bogus_addr *baddrp;
/* skip over questions */
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)))
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;
}
return 0;
}
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, ...)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment