]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/dnsmasq/013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch
BUG11177: pppoe password not required anymore
[ipfire-2.x.git] / src / patches / dnsmasq / 013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch
1 From 094bfaeb4ff69cae99387bc2ea07ff57632c89f5 Mon Sep 17 00:00:00 2001
2 From: Mathias Kresin <dev@kresin.me>
3 Date: Sun, 24 Jul 2016 14:15:22 +0100
4 Subject: [PATCH] auth-zone: allow to exclude ip addresses from answer.
5
6 ---
7 man/dnsmasq.8 | 6 +++++-
8 src/auth.c | 61 ++++++++++++++++++++++++++++++++++++---------------------
9 src/dnsmasq.h | 1 +
10 src/option.c | 21 ++++++++++++++++++--
11 4 files changed, 64 insertions(+), 25 deletions(-)
12
13 diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
14 index ac8d921..8910947 100644
15 --- a/man/dnsmasq.8
16 +++ b/man/dnsmasq.8
17 @@ -739,7 +739,7 @@ a return code of SERVFAIL. Note that
18 setting this may affect DNS behaviour in bad ways, it is not an
19 extra-logging flag and should not be set in production.
20 .TP
21 -.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]]
22 +.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....][,exclude:<subnet>[/<prefix length>]].....]
23 Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain
24 will be served. If subnet(s) are given, A and AAAA records must be in one of the
25 specified subnets.
26 @@ -756,6 +756,10 @@ appear in the zone, but RFC1918 IPv4 addresses which should not.
27 Interface-name and address-literal subnet specifications may be used
28 freely in the same --auth-zone declaration.
29
30 +It's possible to exclude certain IP addresses from responses. It can be
31 +used, to make sure that answers contain only global routeable IP
32 +addresses (by excluding loopback, RFC1918 and ULA addresses).
33 +
34 The subnet(s) are also used to define in-addr.arpa and
35 ip6.arpa domains which are served for reverse-DNS queries. If not
36 specified, the prefix length defaults to 24 for IPv4 and 64 for IPv6.
37 diff --git a/src/auth.c b/src/auth.c
38 index 3c5c37f..f1ca2f5 100644
39 --- a/src/auth.c
40 +++ b/src/auth.c
41 @@ -18,36 +18,53 @@
42
43 #ifdef HAVE_AUTH
44
45 -static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u)
46 +static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct all_addr *addr_u)
47 {
48 - struct addrlist *subnet;
49 -
50 - for (subnet = zone->subnet; subnet; subnet = subnet->next)
51 - {
52 - if (!(subnet->flags & ADDRLIST_IPV6))
53 - {
54 - struct in_addr netmask, addr = addr_u->addr.addr4;
55 -
56 - if (!(flag & F_IPV4))
57 - continue;
58 -
59 - netmask.s_addr = htonl(~(in_addr_t)0 << (32 - subnet->prefixlen));
60 -
61 - if (is_same_net(addr, subnet->addr.addr.addr4, netmask))
62 - return subnet;
63 - }
64 + do {
65 + if (!(list->flags & ADDRLIST_IPV6))
66 + {
67 + struct in_addr netmask, addr = addr_u->addr.addr4;
68 +
69 + if (!(flag & F_IPV4))
70 + continue;
71 +
72 + netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen));
73 +
74 + if (is_same_net(addr, list->addr.addr.addr4, netmask))
75 + return list;
76 + }
77 #ifdef HAVE_IPV6
78 - else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr.addr.addr6, subnet->prefixlen))
79 - return subnet;
80 + else if (is_same_net6(&(addr_u->addr.addr6), &list->addr.addr.addr6, list->prefixlen))
81 + return list;
82 #endif
83 -
84 - }
85 +
86 + } while ((list = list->next));
87 +
88 return NULL;
89 }
90
91 +static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u)
92 +{
93 + if (!zone->subnet)
94 + return NULL;
95 +
96 + return find_addrlist(zone->subnet, flag, addr_u);
97 +}
98 +
99 +static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct all_addr *addr_u)
100 +{
101 + if (!zone->exclude)
102 + return NULL;
103 +
104 + return find_addrlist(zone->exclude, flag, addr_u);
105 +}
106 +
107 static int filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
108 {
109 - /* No zones specified, no filter */
110 + if (find_exclude(zone, flag, addr_u))
111 + return 0;
112 +
113 + /* No subnets specified, no filter */
114 if (!zone->subnet)
115 return 1;
116
117 diff --git a/src/dnsmasq.h b/src/dnsmasq.h
118 index 2bda5d0..27385a9 100644
119 --- a/src/dnsmasq.h
120 +++ b/src/dnsmasq.h
121 @@ -340,6 +340,7 @@ struct auth_zone {
122 struct auth_name_list *next;
123 } *interface_names;
124 struct addrlist *subnet;
125 + struct addrlist *exclude;
126 struct auth_zone *next;
127 };
128
129 diff --git a/src/option.c b/src/option.c
130 index d8c57d6..6cedef3 100644
131 --- a/src/option.c
132 +++ b/src/option.c
133 @@ -1906,6 +1906,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
134 new = opt_malloc(sizeof(struct auth_zone));
135 new->domain = opt_string_alloc(arg);
136 new->subnet = NULL;
137 + new->exclude = NULL;
138 new->interface_names = NULL;
139 new->next = daemon->auth_zones;
140 daemon->auth_zones = new;
141 @@ -1913,6 +1914,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
142 while ((arg = comma))
143 {
144 int prefixlen = 0;
145 + int is_exclude = 0;
146 char *prefix;
147 struct addrlist *subnet = NULL;
148 struct all_addr addr;
149 @@ -1923,6 +1925,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
150 if (prefix && !atoi_check(prefix, &prefixlen))
151 ret_err(gen_err);
152
153 + if (strstr(arg, "exclude:") == arg)
154 + {
155 + is_exclude = 1;
156 + arg = arg+8;
157 + }
158 +
159 if (inet_pton(AF_INET, arg, &addr.addr.addr4))
160 {
161 subnet = opt_malloc(sizeof(struct addrlist));
162 @@ -1960,8 +1968,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
163 if (subnet)
164 {
165 subnet->addr = addr;
166 - subnet->next = new->subnet;
167 - new->subnet = subnet;
168 +
169 + if (is_exclude)
170 + {
171 + subnet->next = new->exclude;
172 + new->exclude = subnet;
173 + }
174 + else
175 + {
176 + subnet->next = new->subnet;
177 + new->subnet = subnet;
178 + }
179 }
180 }
181 break;
182 --
183 1.7.10.4
184