From f2ed769880271654297a4be420f26ab94d39666b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 30 Jan 2014 13:29:46 +0100 Subject: DHCPCD(8): Import Import DHCPCD(8) from: http://roy.marples.name/projects/dhcpcd/ The upstream sources can be obtained via: fossil clone http://roy.marples.name/projects/dhcpcd The imported version is 2014-01-29 19:46:44 [6b209507bb]. --- dhcpcd/dhcpcd-hooks/20-resolv.conf | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 dhcpcd/dhcpcd-hooks/20-resolv.conf (limited to 'dhcpcd/dhcpcd-hooks/20-resolv.conf') diff --git a/dhcpcd/dhcpcd-hooks/20-resolv.conf b/dhcpcd/dhcpcd-hooks/20-resolv.conf new file mode 100644 index 00000000..05316c9f --- /dev/null +++ b/dhcpcd/dhcpcd-hooks/20-resolv.conf @@ -0,0 +1,165 @@ +# Generate /etc/resolv.conf +# Support resolvconf(8) if available +# We can merge other dhcpcd resolv.conf files into one like resolvconf, +# but resolvconf is preferred as other applications like VPN clients +# can readily hook into it. +# Also, resolvconf can configure local nameservers such as bind +# or dnsmasq. This is important as the libc resolver isn't that powerful. + +resolv_conf_dir="$state_dir/resolv.conf" +NL=" +" + +build_resolv_conf() +{ + local cf="$state_dir/resolv.conf.$ifname" + local interfaces= header= search= srvs= servers= x= + + # Build a list of interfaces + interfaces=$(list_interfaces "$resolv_conf_dir") + + # Build the resolv.conf + if [ -n "$interfaces" ]; then + # Build the header + for x in ${interfaces}; do + header="$header${header:+, }$x" + done + + # Build the search list + domain=$(cd "$resolv_conf_dir"; \ + key_get_value "domain " ${interfaces}) + search=$(cd "$resolv_conf_dir"; \ + key_get_value "search " ${interfaces}) + set -- ${domain} + domain="$1" + [ -n "$2" ] && search="$search $*" + [ -n "$search" ] && search="$(uniqify $search)" + [ "$domain" = "$search" ] && search= + [ -n "$domain" ] && domain="domain $domain$NL" + [ -n "$search" ] && search="search $search$NL" + + # Build the nameserver list + srvs=$(cd "$resolv_conf_dir"; \ + key_get_value "nameserver " ${interfaces}) + for x in $(uniqify ${srvs}); do + servers="${servers}nameserver $x$NL" + done + fi + header="$signature_base${header:+ $from }$header" + + # Assemble resolv.conf using our head and tail files + [ -f "$cf" ] && rm -f "$cf" + [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" + echo "$header" > "$cf" + if [ -f /etc/resolv.conf.head ]; then + cat /etc/resolv.conf.head >> "$cf" + else + echo "# /etc/resolv.conf.head can replace this line" >> "$cf" + fi + printf %s "$domain$search$servers" >> "$cf" + if [ -f /etc/resolv.conf.tail ]; then + cat /etc/resolv.conf.tail >> "$cf" + else + echo "# /etc/resolv.conf.tail can replace this line" >> "$cf" + fi + if change_file /etc/resolv.conf "$cf"; then + chmod 644 /etc/resolv.conf + fi + rm -f "$cf" +} + +add_resolv_conf() +{ + local x= conf="$signature$NL" i=${ra_count:-0} ra= + + while [ $i -ne 0 ]; do + eval ra=\$ra${i}_rdnss + new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$ra" + eval ra=\$ra${i}_dnssl + new_domain_search="$new_domain_search${new_domain_search:+ }$ra" + i=$(($i - 1)) + done + + # If we don't have any configuration, remove it + if [ -z "$new_domain_name_servers" -a \ + -z "$new_domain_name" -a \ + -z "$new_domain_search" ]; then + remove_resolv_conf + return $? + fi + + # Derive a new domain from our various hostname options + if [ -z "$new_domain_name" ]; then + if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then + new_domain_name="${new_dhcp6_fqdn#*.}" + elif [ "$new_fqdn" != "${new_fqdn#*.}" ]; then + new_domain_name="${new_fqdn#*.}" + elif [ "$new_host_name" != "${new_host_name#*.}" ]; then + new_domain_name="${new_host_name#*.}" + fi + fi + + if [ -n "$new_domain_name" ]; then + set -- $new_domain_name + new_domain_name="$1" + if valid_domainname "$new_domain_name"; then + conf="${conf}domain $new_domain_name$NL" + else + syslog err "Invalid domain name: $new_domain_name" + fi + # Support RFC violating search in domain + if [ -z "$new_domain_search" -a -n "$2" ]; then + new_domain_search="$*" + fi + fi + if [ -n "$new_domain_search" -a \ + "$new_domain_search" != "$new_domain_name" ] + then + if valid_domainname_list $new_domain_search; then + conf="${conf}search $new_domain_search$NL" + else + syslog err "Invalid domain name in list: $new_domain_search" + fi + fi + for x in ${new_domain_name_servers}; do + conf="${conf}nameserver $x$NL" + done + if type resolvconf >/dev/null 2>&1; then + [ -n "$ifmetric" ] && export IF_METRIC="$ifmetric" + printf %s "$conf" | resolvconf -a "$ifname" + return $? + fi + + if [ -e "$resolv_conf_dir/$ifname" ]; then + rm -f "$resolv_conf_dir/$ifname" + fi + [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" + printf %s "$conf" > "$resolv_conf_dir/$ifname" + build_resolv_conf +} + +remove_resolv_conf() +{ + if type resolvconf >/dev/null 2>&1; then + resolvconf -d "$ifname" -f + else + if [ -e "$resolv_conf_dir/$ifname" ]; then + rm -f "$resolv_conf_dir/$ifname" + fi + build_resolv_conf + fi +} + +# For ease of use, map DHCP6 names onto our DHCP4 names +case "$reason" in +BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6) + new_domain_name_servers="$new_dhcp6_name_servers" + new_domain_search="$new_dhcp6_domain_search" + ;; +esac + +if $if_up || [ "$reason" = ROUTERADVERT ]; then + add_resolv_conf +elif $if_down; then + remove_resolv_conf +fi -- cgit v1.2.3