mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Support IPv6 in --bogus-nxdomian and --ignore-address
This commit is contained in:
@@ -327,8 +327,8 @@ are re-written. So
|
||||
maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
|
||||
.TP
|
||||
.B \-B, --bogus-nxdomain=<ipaddr>[/prefix]
|
||||
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
|
||||
Transform replies which contain the specified address or subnet into "No such
|
||||
domain" replies. IPv4 and IPv6 are supported. This is intended to counteract a devious move made by
|
||||
Verisign in September 2003 when they started returning the address of
|
||||
an advertising web page in response to queries for unregistered names,
|
||||
instead of the correct NXDOMAIN response. This option tells dnsmasq to
|
||||
@@ -336,7 +336,7 @@ 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
|
||||
.TP
|
||||
.B --ignore-address=<ipaddr>[/prefix]
|
||||
Ignore replies to A-record queries which include the specified address or subnet.
|
||||
Ignore replies to A or AAAA queries which include the specified address or subnet.
|
||||
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.
|
||||
|
||||
@@ -329,7 +329,8 @@ union all_addr {
|
||||
|
||||
|
||||
struct bogus_addr {
|
||||
struct in_addr addr, mask;
|
||||
int is6, prefix;
|
||||
union all_addr addr;
|
||||
struct bogus_addr *next;
|
||||
};
|
||||
|
||||
@@ -1368,6 +1369,7 @@ int hostname_issubdomain(char *a, char *b);
|
||||
time_t dnsmasq_time(void);
|
||||
int netmask_length(struct in_addr mask);
|
||||
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
|
||||
int is_same_net_prefix(struct in_addr a, struct in_addr b, int prefix);
|
||||
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
|
||||
u64 addr6part(struct in6_addr *addr);
|
||||
void setaddr6part(struct in6_addr *addr, u64 host);
|
||||
|
||||
53
src/option.c
53
src/option.c
@@ -2527,30 +2527,47 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case 'B': /* --bogus-nxdomain */
|
||||
case LOPT_IGNORE_ADDR: /* --ignore-address */
|
||||
{
|
||||
struct in_addr addr;
|
||||
int prefix = 32;
|
||||
union all_addr addr;
|
||||
int prefix, is6 = 0;
|
||||
struct bogus_addr *baddr;
|
||||
|
||||
unhide_metas(arg);
|
||||
|
||||
if (!arg ||
|
||||
((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)) ||
|
||||
(inet_pton(AF_INET, arg, &addr) != 1))
|
||||
ret_err(gen_err); /* error */
|
||||
((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)))
|
||||
ret_err(gen_err);
|
||||
|
||||
if (inet_pton(AF_INET6, arg, &addr.addr6) == 1)
|
||||
is6 = 1;
|
||||
else if (inet_pton(AF_INET, arg, &addr.addr4) != 1)
|
||||
ret_err(gen_err);
|
||||
|
||||
if (!comma)
|
||||
{
|
||||
if (is6)
|
||||
prefix = 128;
|
||||
else
|
||||
prefix = 32;
|
||||
}
|
||||
|
||||
if (prefix > 128 || (!is6 && prefix > 32))
|
||||
ret_err(gen_err);
|
||||
|
||||
baddr = opt_malloc(sizeof(struct bogus_addr));
|
||||
if (option == 'B')
|
||||
{
|
||||
baddr->next = daemon->bogus_addr;
|
||||
daemon->bogus_addr = baddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
|
||||
if (option == 'B')
|
||||
{
|
||||
baddr->next = daemon->bogus_addr;
|
||||
daemon->bogus_addr = baddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
baddr->next = daemon->ignore_addr;
|
||||
daemon->ignore_addr = baddr;
|
||||
}
|
||||
baddr->mask.s_addr = htonl(~((1 << (32 - prefix)) - 1));
|
||||
baddr->addr.s_addr = addr.s_addr & baddr->mask.s_addr;
|
||||
baddr->next = daemon->ignore_addr;
|
||||
daemon->ignore_addr = baddr;
|
||||
}
|
||||
|
||||
baddr->prefix = prefix;
|
||||
baddr->is6 = is6;
|
||||
baddr->addr = addr;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1079,7 +1079,6 @@ static int check_bad_address(struct dns_header *header, size_t qlen, struct bogu
|
||||
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)))
|
||||
@@ -1101,17 +1100,33 @@ static int check_bad_address(struct dns_header *header, size_t qlen, struct bogu
|
||||
if (ttlp)
|
||||
*ttlp = ttl;
|
||||
|
||||
if (qclass == C_IN && qtype == T_A)
|
||||
if (qclass == C_IN)
|
||||
{
|
||||
if (!CHECK_LEN(header, p, qlen, INADDRSZ))
|
||||
return 0;
|
||||
|
||||
for (baddrp = baddr; baddrp; baddrp = baddrp->next)
|
||||
if (qtype == T_A)
|
||||
{
|
||||
struct in_addr addr;
|
||||
|
||||
if (!CHECK_LEN(header, p, qlen, INADDRSZ))
|
||||
return 0;
|
||||
|
||||
memcpy(&addr, p, INADDRSZ);
|
||||
|
||||
if ((addr.s_addr & baddrp->mask.s_addr) == baddrp->addr.s_addr)
|
||||
return 1;
|
||||
for (baddrp = baddr; baddrp; baddrp = baddrp->next)
|
||||
if (!baddrp->is6 && is_same_net_prefix(addr, baddrp->addr.addr4, baddrp->prefix))
|
||||
return 1;
|
||||
}
|
||||
else if (qtype == T_AAAA)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
||||
if (!CHECK_LEN(header, p, qlen, IN6ADDRSZ))
|
||||
return 0;
|
||||
|
||||
memcpy(&addr, p, IN6ADDRSZ);
|
||||
|
||||
for (baddrp = baddr; baddrp; baddrp = baddrp->next)
|
||||
if (baddrp->is6 && is_same_net6(&addr, &baddrp->addr.addr6, baddrp->prefix))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/util.c
10
src/util.c
@@ -438,6 +438,16 @@ int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
|
||||
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
|
||||
}
|
||||
|
||||
int is_same_net_prefix(struct in_addr a, struct in_addr b, int prefix)
|
||||
{
|
||||
struct in_addr mask;
|
||||
|
||||
mask.s_addr = htonl(~((1 << (32 - prefix)) - 1));
|
||||
|
||||
return is_same_net(a, b, mask);
|
||||
}
|
||||
|
||||
|
||||
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen)
|
||||
{
|
||||
int pfbytes = prefixlen >> 3;
|
||||
|
||||
Reference in New Issue
Block a user