2 ##############################################################################
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 2 as
6 # published by the Free Software Foundation.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # Copyright (C) 2016 Eric Luehrsen
15 ##############################################################################
17 # This crosses over to the dnsmasq UCI file "dhcp" and parses it for fields
18 # that will allow Unbound to request local host DNS of dnsmasq. We need to look
19 # at the interfaces in "dhcp" and get their subnets. The Unbound conf syntax
20 # makes this a little difficult. First in "server:" we need to create private
21 # zones for the domain and PTR records. Then we need to create numerous
22 # "forward:" clauses to forward those zones to dnsmasq.
24 ##############################################################################
28 DM_LIST_KNOWN_ZONES="invalid"
35 ##############################################################################
39 local partial domain found
41 case $DM_LIST_TRN_ZONES in
48 [A-Za-z0-9]*.[A-Za-z0-9]*)
59 if [ $found -eq 0 ] ; then
60 # New Zone! Bundle local-zones: by first two name tiers "abcd.tld."
61 partial=$( echo "$target" | awk -F. '{ j=NF ; i=j-1; print $i"."$j }' )
62 DM_LIST_TRN_ZONES="$DM_LIST_TRN_ZONES $partial"
63 DM_LIST_KNOWN_ZONES="$DM_LIST_KNOWN_ZONES $partial"
67 ##############################################################################
69 create_host_record() {
71 local ip name debug_ip
73 # basefiles dhcp "domain" clause which means host A, AAAA, and PRT record
74 config_get ip "$cfg" ip
75 config_get name "$cfg" name
78 if [ -n "$name" ] && [ -n "$ip" ] ; then
79 create_local_zone "$name"
83 fe[89ab][0-9a-f]:*|169.254.*)
88 DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@AAAA@@$ip"
89 DM_LIST_LOCAL_PTR="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
93 DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@A@@$ip"
94 DM_LIST_LOCAL_PTR="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
100 ##############################################################################
104 local domain relay pref record
106 # Insert a static MX record
107 config_get domain "$cfg" domain
108 config_get relay "$cfg" relay
109 config_get pref "$cfg" pref 10
112 if [ -n "$domain" ] && [ -n "$relay" ] ; then
113 create_local_zone "$domain"
114 record="$domain.@@300@@IN@@MX@@$pref@@$relay."
115 DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
119 ##############################################################################
121 create_srv_record() {
123 local srv target port class weight record
125 # Insert a static SRV record such as SIP server
126 config_get srv "$cfg" srv
127 config_get target "$cfg" target
128 config_get port "$cfg" port
129 config_get class "$cfg" class 10
130 config_get weight "$cfg" weight 10
133 if [ -n "$srv" ] && [ -n "$target" ] && [ -n "$port" ] ; then
134 create_local_zone "$srv"
135 record="$srv.@@300@@IN@@SRV@@$class@@$weight@@$port@@$target."
136 DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
140 ##############################################################################
142 create_cname_record() {
144 local cname target record
146 # Insert static CNAME record
147 config_get cname "$cfg" cname
148 config_get target "$cfg" target
151 if [ -n "$cname" ] && [ -n "$target" ] ; then
152 create_local_zone "$cname"
153 record="$cname.@@300@@IN@@CNAME@@$target."
154 DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
158 ##############################################################################
160 dnsmasq_local_zone() {
162 local fwd_port fwd_domain wan_fqdn
164 # dnsmasq domain and interface assignment settings will control config
165 config_get fwd_domain "$cfg" domain
166 config_get fwd_port "$cfg" port
167 config_get wan_fqdn "$cfg" add_wan_fqdn
170 if [ -n "$wan_fqdn" ] ; then
171 DM_D_WAN_FQDN=$wan_fqdn
175 if [ -n "$fwd_domain" ] && [ -n "$fwd_port" ] \
176 && [ ! "${fwd_port:-53}" -eq 53 ] ; then
177 # dnsmasq localhost listening ports (possible multiple instances)
178 DM_LIST_FWD_PORTS="$DM_LIST_FWD_PORTS $fwd_port"
179 DM_LIST_FWD_ZONES="$DM_LIST_FWD_ZONES $fwd_domain"
183 ##############################################################################
185 dnsmasq_local_arpa() {
186 local ifarpa ifsubnet
189 if [ -n "$UB_LIST_NETW_LAN" ] ; then
190 for ifsubnet in $UB_LIST_NETW_LAN ; do
191 ifarpa=$( domain_ptr_any "${ifsubnet#*@}" )
192 DM_LIST_FWD_ZONES="$DM_LIST_FWD_ZONES $ifarpa"
197 if [ -n "$UB_LIST_NETW_WAN" ] && [ "$DM_D_WAN_FQDN" -gt 0 ] ; then
198 for ifsubnet in $UB_LIST_NETW_WAN ; do
199 ifarpa=$( domain_ptr_any "${ifsubnet#*@}" )
200 DM_LIST_FWD_ZONES="$DM_LIST_FWD_ZONES $ifarpa"
205 ##############################################################################
211 if [ "$UB_D_EXTRA_DNS" -gt 0 ] ; then
212 # Parasite from the uci.dhcp.domain clauses
213 DM_LIST_KNOWN_ZONES="$DM_LIST_KNOWN_ZONES $UB_TXT_DOMAIN"
215 config_foreach create_host_record domain
218 if [ "$UB_D_EXTRA_DNS" -gt 1 ] ; then
219 config_foreach create_srv_record srvhost
220 config_foreach create_mx_record mxhost
224 if [ "$UB_D_EXTRA_DNS" -gt 2 ] ; then
225 config_foreach create_cname_record cname
230 echo "# $UB_SRVMASQ_CONF generated by UCI $( date -Is )"
231 if [ -n "$DM_LIST_TRN_ZONES" ] ; then
232 for record in $DM_LIST_TRN_ZONES ; do
233 echo " local-zone: $record transparent"
237 if [ -n "$DM_LIST_LOCAL_DATA" ] ; then
238 for record in $DM_LIST_LOCAL_DATA ; do
239 echo " local-data: \"${record//@@/ }\""
243 if [ -n "$DM_LIST_LOCAL_PTR" ] ; then
244 for record in $DM_LIST_LOCAL_PTR ; do
245 echo " local-data-ptr: \"${record//@@/ }\""
253 ##############################################################################
256 # Look at dnsmasq settings
258 # Zone for DHCP / SLAAC-PING DOMAIN
259 config_foreach dnsmasq_local_zone dnsmasq
260 # Zone for DHCP / SLAAC-PING ARPA
264 if [ -n "$DM_LIST_FWD_PORTS" ] && [ -n "$DM_LIST_FWD_ZONES" ] ; then
266 # Forward to dnsmasq on same host for DHCP lease hosts
267 echo "# $UB_SRVMASQ_CONF generated by UCI $( date -Is )"
268 echo " do-not-query-localhost: no"
272 echo "# $UB_EXTMASQ_CONF generated by UCI $( date -Is )" > $UB_EXTMASQ_CONF
275 for fwd_domain in $DM_LIST_FWD_ZONES ; do
277 # This creates a domain with local privledges
278 echo " domain-insecure: $fwd_domain"
279 echo " private-domain: $fwd_domain"
280 echo " local-zone: $fwd_domain transparent"
282 } >> $UB_SRVMASQ_CONF
285 # This is derived from dnsmasq local domain and dhcp service subnets
287 echo " name: $fwd_domain"
288 echo " forward-first: no"
289 for port in $DM_LIST_FWD_PORTS ; do
290 echo " forward-addr: 127.0.0.1@$port"
293 } >> $UB_EXTMASQ_CONF
298 ##############################################################################
301 if [ "$UB_D_DHCP_LINK" = "dnsmasq" ] ; then
309 ##############################################################################