mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Teach --bogus-nxdomain and --ignore-address to take a subnet argument.
This commit is contained in:
@@ -325,7 +325,7 @@ union all_addr {
|
||||
|
||||
|
||||
struct bogus_addr {
|
||||
struct in_addr addr;
|
||||
struct in_addr addr, mask;
|
||||
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,
|
||||
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);
|
||||
|
||||
@@ -738,7 +738,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
}
|
||||
|
||||
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 @@ void reply_query(int fd, int family, time_t now)
|
||||
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
|
||||
|
||||
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 */
|
||||
{
|
||||
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 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
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 */
|
||||
|
||||
@@ -1017,30 +1017,33 @@ int check_for_local_domain(char *name, time_t now)
|
||||
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 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||
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 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||
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, ...)
|
||||
|
||||
Reference in New Issue
Block a user