1# Generate /etc/resolv.conf 2# Support resolvconf(8) if available 3# We can merge other dhcpcd resolv.conf files into one like resolvconf, 4# but resolvconf is preferred as other applications like VPN clients 5# can readily hook into it. 6# Also, resolvconf can configure local nameservers such as bind 7# or dnsmasq. This is important as the libc resolver isn't that powerful. 8 9resolv_conf_dir="$state_dir/resolv.conf" 10NL=" 11" 12 13build_resolv_conf() 14{ 15 local cf="$state_dir/resolv.conf.$ifname" 16 local interfaces= header= search= srvs= servers= x= 17 18 # Build a list of interfaces 19 interfaces=$(list_interfaces "$resolv_conf_dir") 20 21 # Build the resolv.conf 22 if [ -n "$interfaces" ]; then 23 # Build the header 24 for x in ${interfaces}; do 25 header="$header${header:+, }$x" 26 done 27 28 # Build the search list 29 domain=$(cd "$resolv_conf_dir"; \ 30 key_get_value "domain " ${interfaces}) 31 search=$(cd "$resolv_conf_dir"; \ 32 key_get_value "search " ${interfaces}) 33 set -- ${domain} 34 domain="$1" 35 [ -n "$2" ] && search="$search $*" 36 [ -n "$search" ] && search="$(uniqify $search)" 37 [ "$domain" = "$search" ] && search= 38 [ -n "$domain" ] && domain="domain $domain$NL" 39 [ -n "$search" ] && search="search $search$NL" 40 41 # Build the nameserver list 42 srvs=$(cd "$resolv_conf_dir"; \ 43 key_get_value "nameserver " ${interfaces}) 44 for x in $(uniqify ${srvs}); do 45 servers="${servers}nameserver $x$NL" 46 done 47 fi 48 header="$signature_base${header:+ $from }$header" 49 50 # Assemble resolv.conf using our head and tail files 51 [ -f "$cf" ] && rm -f "$cf" 52 [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" 53 echo "$header" > "$cf" 54 if [ -f /etc/resolv.conf.head ]; then 55 cat /etc/resolv.conf.head >> "$cf" 56 else 57 echo "# /etc/resolv.conf.head can replace this line" >> "$cf" 58 fi 59 printf %s "$domain$search$servers" >> "$cf" 60 if [ -f /etc/resolv.conf.tail ]; then 61 cat /etc/resolv.conf.tail >> "$cf" 62 else 63 echo "# /etc/resolv.conf.tail can replace this line" >> "$cf" 64 fi 65 if change_file /etc/resolv.conf "$cf"; then 66 chmod 644 /etc/resolv.conf 67 fi 68 rm -f "$cf" 69} 70 71add_resolv_conf() 72{ 73 local x= conf="$signature$NL" i=${ra_count:-0} ra= warn=true 74 75 while [ $i -ne 0 ]; do 76 eval ra=\$ra${i}_rdnss 77 new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$ra" 78 eval ra=\$ra${i}_dnssl 79 new_domain_search="$new_domain_search${new_domain_search:+ }$ra" 80 i=$(($i - 1)) 81 done 82 83 # If we don't have any configuration, remove it 84 if [ -z "$new_domain_name_servers" -a \ 85 -z "$new_domain_name" -a \ 86 -z "$new_domain_search" ]; then 87 remove_resolv_conf 88 return $? 89 fi 90 91 # Derive a new domain from our various hostname options 92 if [ -z "$new_domain_name" ]; then 93 if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then 94 new_domain_name="${new_dhcp6_fqdn#*.}" 95 elif [ "$new_fqdn" != "${new_fqdn#*.}" ]; then 96 new_domain_name="${new_fqdn#*.}" 97 elif [ "$new_host_name" != "${new_host_name#*.}" ]; then 98 new_domain_name="${new_host_name#*.}" 99 fi 100 fi 101 102 if [ -n "$new_domain_name" ]; then 103 set -- $new_domain_name 104 if valid_domainname "$1"; then 105 conf="${conf}domain $1$NL" 106 else 107 syslog err "Invalid domain name: $1" 108 fi 109 # If there is no search this, make this one 110 if [ -z "$new_domain_search" ]; then 111 new_domain_search="$new_domain_name" 112 [ "$new_domain_name" = "$1" ] && warn=true 113 fi 114 fi 115 if [ -n "$new_domain_search" ]; then 116 if valid_domainname_list $new_domain_search; then 117 conf="${conf}search $new_domain_search$NL" 118 elif ! $warn; then 119 syslog err "Invalid domain name in list:" \ 120 "$new_domain_search" 121 fi 122 fi 123 for x in ${new_domain_name_servers}; do 124 conf="${conf}nameserver $x$NL" 125 done 126 if type resolvconf >/dev/null 2>&1; then 127 [ -n "$ifmetric" ] && export IF_METRIC="$ifmetric" 128 printf %s "$conf" | resolvconf -a "$ifname" 129 return $? 130 fi 131 132 if [ -e "$resolv_conf_dir/$ifname" ]; then 133 rm -f "$resolv_conf_dir/$ifname" 134 fi 135 [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" 136 printf %s "$conf" > "$resolv_conf_dir/$ifname" 137 build_resolv_conf 138} 139 140remove_resolv_conf() 141{ 142 if type resolvconf >/dev/null 2>&1; then 143 resolvconf -d "$ifname" -f 144 else 145 if [ -e "$resolv_conf_dir/$ifname" ]; then 146 rm -f "$resolv_conf_dir/$ifname" 147 fi 148 build_resolv_conf 149 fi 150} 151 152# For ease of use, map DHCP6 names onto our DHCP4 names 153case "$reason" in 154BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6) 155 new_domain_name_servers="$new_dhcp6_name_servers" 156 new_domain_search="$new_dhcp6_domain_search" 157 ;; 158esac 159 160if $if_up || [ "$reason" = ROUTERADVERT ]; then 161 add_resolv_conf 162elif $if_down; then 163 remove_resolv_conf 164fi 165