1 # $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $
3 # Generate /etc/resolv.conf
4 # Support resolvconf(8) if available
5 # We can merge other dhcpcd resolv.conf files into one like resolvconf,
6 # but resolvconf is preferred as other applications like VPN clients
7 # can readily hook into it.
8 # Also, resolvconf can configure local nameservers such as bind
9 # or dnsmasq. This is important as the libc resolver isn't that powerful.
11 resolv_conf_dir="$state_dir/resolv.conf"
17 local cf="$state_dir/resolv.conf.$ifname"
18 local interfaces= header= search= srvs= servers= x=
20 # Build a list of interfaces
21 interfaces=$(list_interfaces "$resolv_conf_dir")
23 # Build the resolv.conf
24 if [ -n "$interfaces" ]; then
26 for x in ${interfaces}; do
27 header="$header${header:+, }$x"
30 # Build the search list
31 domain=$(cd "$resolv_conf_dir"; \
32 key_get_value "domain " ${interfaces})
33 search=$(cd "$resolv_conf_dir"; \
34 key_get_value "search " ${interfaces})
37 [ -n "$2" ] && search="$search $*"
38 [ -n "$search" ] && search="$(uniqify $search)"
39 [ "$domain" = "$search" ] && search=
40 [ -n "$domain" ] && domain="domain $domain$NL"
41 [ -n "$search" ] && search="search $search$NL"
43 # Build the nameserver list
44 srvs=$(cd "$resolv_conf_dir"; \
45 key_get_value "nameserver " ${interfaces})
46 for x in $(uniqify ${srvs}); do
47 servers="${servers}nameserver $x$NL"
50 header="$signature_base${header:+ $from }$header"
52 # Assemble resolv.conf using our head and tail files
53 [ -f "$cf" ] && rm -f "$cf"
54 [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir"
55 echo "$header" > "$cf"
56 if [ -f /etc/resolv.conf.head ]; then
57 cat /etc/resolv.conf.head >> "$cf"
59 echo "# /etc/resolv.conf.head can replace this line" >> "$cf"
61 printf %s "$domain$search$servers" >> "$cf"
62 if [ -f /etc/resolv.conf.tail ]; then
63 cat /etc/resolv.conf.tail >> "$cf"
65 echo "# /etc/resolv.conf.tail can replace this line" >> "$cf"
67 if change_file /etc/resolv.conf "$cf"; then
68 chmod 644 /etc/resolv.conf
73 # Extract any ND DNS options from the RA
74 # For now, we ignore the lifetime of the DNS options unless they
76 # In this case they are removed from consideration.
77 # See draft-gont-6man-slaac-dns-config-issues-01 for issues
78 # regarding DNS option lifetime in ND messages.
82 eval ltime=\$nd${i}_rdnss${j}_lifetime
83 if [ -z "$ltime" -o "$ltime" = 0 ]; then
86 eval rdnss=\$nd${i}_rdnss${j}_servers
88 eval ltime=\$nd${i}_dnssl${j}_lifetime
89 if [ -z "$ltime" -o "$ltime" = 0 ]; then
92 eval dnssl=\$nd${i}_dnssl${j}_search
95 [ -z "$rdnss" -a -z "$dnssl" ] && return 1
97 new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss"
98 new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl"
105 local x= conf="$signature$NL" warn=true
106 local i j ltime rdnss dnssl new_rdnss new_dnssl
108 # Loop to extract the ND DNS options using our indexed shell values
119 new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
120 new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
122 # Derive a new domain from our various hostname options
123 if [ -z "$new_domain_name" ]; then
124 if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then
125 new_domain_name="${new_dhcp6_fqdn#*.}"
126 elif [ "$new_fqdn" != "${new_fqdn#*.}" ]; then
127 new_domain_name="${new_fqdn#*.}"
128 elif [ "$new_host_name" != "${new_host_name#*.}" ]; then
129 new_domain_name="${new_host_name#*.}"
133 # If we don't have any configuration, remove it
134 if [ -z "$new_domain_name_servers" -a \
135 -z "$new_domain_name" -a \
136 -z "$new_domain_search" ]; then
141 if [ -n "$new_domain_name" ]; then
142 set -- $new_domain_name
143 if valid_domainname "$1"; then
144 conf="${conf}domain $1$NL"
146 syslog err "Invalid domain name: $1"
148 # If there is no search this, make this one
149 if [ -z "$new_domain_search" ]; then
150 new_domain_search="$new_domain_name"
151 [ "$new_domain_name" = "$1" ] && warn=true
154 if [ -n "$new_domain_search" ]; then
155 if valid_domainname_list $new_domain_search; then
156 conf="${conf}search $new_domain_search$NL"
158 syslog err "Invalid domain name in list:" \
162 for x in ${new_domain_name_servers}; do
163 conf="${conf}nameserver $x$NL"
165 if type resolvconf >/dev/null 2>&1; then
166 [ -n "$ifmetric" ] && export IF_METRIC="$ifmetric"
167 printf %s "$conf" | resolvconf -a "$ifname"
171 if [ -e "$resolv_conf_dir/$ifname" ]; then
172 rm -f "$resolv_conf_dir/$ifname"
174 [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir"
175 printf %s "$conf" > "$resolv_conf_dir/$ifname"
181 if type resolvconf >/dev/null 2>&1; then
182 resolvconf -d "$ifname" -f
184 if [ -e "$resolv_conf_dir/$ifname" ]; then
185 rm -f "$resolv_conf_dir/$ifname"
191 # For ease of use, map DHCP6 names onto our DHCP4 names
193 BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
194 new_domain_name_servers="$new_dhcp6_name_servers"
195 new_domain_search="$new_dhcp6_domain_search"
199 if $if_up || [ "$reason" = ROUTERADVERT ]; then