17827cba2SAaron LI# Generate /etc/resolv.conf 27827cba2SAaron LI# Support resolvconf(8) if available 37827cba2SAaron LI# We can merge other dhcpcd resolv.conf files into one like resolvconf, 47827cba2SAaron LI# but resolvconf is preferred as other applications like VPN clients 57827cba2SAaron LI# can readily hook into it. 67827cba2SAaron LI# Also, resolvconf can configure local nameservers such as bind 77827cba2SAaron LI# or dnsmasq. This is important as the libc resolver isn't that powerful. 87827cba2SAaron LI 97827cba2SAaron LIresolv_conf_dir="$state_dir/resolv.conf" 100aaf6155SRoy Marplesnocarrier_roaming_dir="$state_dir/roaming" 117827cba2SAaron LINL=" 127827cba2SAaron LI" 137827cba2SAaron LI: ${resolvconf:=resolvconf} 14*80aa9461SRoy Marplesif command -v "$resolvconf" >/dev/null 2>&1; then 150aaf6155SRoy Marples have_resolvconf=true 160aaf6155SRoy Marpleselse 170aaf6155SRoy Marples have_resolvconf=false 180aaf6155SRoy Marplesfi 197827cba2SAaron LI 207827cba2SAaron LIbuild_resolv_conf() 217827cba2SAaron LI{ 227827cba2SAaron LI cf="$state_dir/resolv.conf.$ifname" 237827cba2SAaron LI 247827cba2SAaron LI # Build a list of interfaces 257827cba2SAaron LI interfaces=$(list_interfaces "$resolv_conf_dir") 267827cba2SAaron LI 277827cba2SAaron LI # Build the resolv.conf 288d36e1dfSRoy Marples header= 297827cba2SAaron LI if [ -n "$interfaces" ]; then 307827cba2SAaron LI # Build the header 317827cba2SAaron LI for x in ${interfaces}; do 327827cba2SAaron LI header="$header${header:+, }$x" 337827cba2SAaron LI done 347827cba2SAaron LI 357827cba2SAaron LI # Build the search list 367827cba2SAaron LI domain=$(cd "$resolv_conf_dir"; \ 377827cba2SAaron LI key_get_value "domain " ${interfaces}) 387827cba2SAaron LI search=$(cd "$resolv_conf_dir"; \ 397827cba2SAaron LI key_get_value "search " ${interfaces}) 407827cba2SAaron LI set -- ${domain} 417827cba2SAaron LI domain="$1" 427827cba2SAaron LI [ -n "$2" ] && search="$search $*" 437827cba2SAaron LI [ -n "$search" ] && search="$(uniqify $search)" 447827cba2SAaron LI [ "$domain" = "$search" ] && search= 457827cba2SAaron LI [ -n "$domain" ] && domain="domain $domain$NL" 467827cba2SAaron LI [ -n "$search" ] && search="search $search$NL" 477827cba2SAaron LI 487827cba2SAaron LI # Build the nameserver list 497827cba2SAaron LI srvs=$(cd "$resolv_conf_dir"; \ 507827cba2SAaron LI key_get_value "nameserver " ${interfaces}) 516e63cc1fSRoy Marples for x in $(uniqify $srvs); do 527827cba2SAaron LI servers="${servers}nameserver $x$NL" 537827cba2SAaron LI done 547827cba2SAaron LI fi 557827cba2SAaron LI header="$signature_base${header:+ $from }$header" 567827cba2SAaron LI 577827cba2SAaron LI # Assemble resolv.conf using our head and tail files 587827cba2SAaron LI [ -f "$cf" ] && rm -f "$cf" 597827cba2SAaron LI [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" 607827cba2SAaron LI echo "$header" > "$cf" 617827cba2SAaron LI if [ -f /etc/resolv.conf.head ]; then 627827cba2SAaron LI cat /etc/resolv.conf.head >> "$cf" 637827cba2SAaron LI else 647827cba2SAaron LI echo "# /etc/resolv.conf.head can replace this line" >> "$cf" 657827cba2SAaron LI fi 667827cba2SAaron LI printf %s "$domain$search$servers" >> "$cf" 677827cba2SAaron LI if [ -f /etc/resolv.conf.tail ]; then 687827cba2SAaron LI cat /etc/resolv.conf.tail >> "$cf" 697827cba2SAaron LI else 707827cba2SAaron LI echo "# /etc/resolv.conf.tail can replace this line" >> "$cf" 717827cba2SAaron LI fi 727827cba2SAaron LI if change_file /etc/resolv.conf "$cf"; then 737827cba2SAaron LI chmod 644 /etc/resolv.conf 747827cba2SAaron LI fi 757827cba2SAaron LI rm -f "$cf" 767827cba2SAaron LI} 777827cba2SAaron LI 787827cba2SAaron LI# Extract any ND DNS options from the RA 798d36e1dfSRoy Marples# Obey the lifetimes 807827cba2SAaron LIeval_nd_dns() 817827cba2SAaron LI{ 828d36e1dfSRoy Marples 838d36e1dfSRoy Marples eval rdnsstime=\$nd${i}_rdnss${j}_lifetime 848d36e1dfSRoy Marples [ -z "$rdnsstime" ] && return 1 858d36e1dfSRoy Marples ltime=$(($rdnsstime - $offset)) 868d36e1dfSRoy Marples if [ "$ltime" -gt 0 ]; then 877827cba2SAaron LI eval rdnss=\$nd${i}_rdnss${j}_servers 887827cba2SAaron LI [ -n "$rdnss" ] && new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss" 898d36e1dfSRoy Marples fi 908d36e1dfSRoy Marples 918d36e1dfSRoy Marples eval dnssltime=\$nd${i}_dnssl${j}_lifetime 928d36e1dfSRoy Marples [ -z "$dnssltime" ] && return 1 938d36e1dfSRoy Marples ltime=$(($dnssltime - $offset)) 948d36e1dfSRoy Marples if [ "$ltime" -gt 0 ]; then 958d36e1dfSRoy Marples eval dnssl=\$nd${i}_dnssl${j}_search 967827cba2SAaron LI [ -n "$dnssl" ] && new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl" 978d36e1dfSRoy Marples fi 988d36e1dfSRoy Marples 997827cba2SAaron LI j=$(($j + 1)) 1007827cba2SAaron LI return 0 1017827cba2SAaron LI} 1027827cba2SAaron LI 1037827cba2SAaron LIadd_resolv_conf() 1047827cba2SAaron LI{ 1057827cba2SAaron LI conf="$signature$NL" 1067827cba2SAaron LI warn=true 1077827cba2SAaron LI 1087827cba2SAaron LI # Loop to extract the ND DNS options using our indexed shell values 1097827cba2SAaron LI i=1 1107827cba2SAaron LI j=1 1117827cba2SAaron LI while true; do 1128d36e1dfSRoy Marples eval acquired=\$nd${i}_acquired 1138d36e1dfSRoy Marples [ -z "$acquired" ] && break 1148d36e1dfSRoy Marples eval now=\$nd${i}_now 1158d36e1dfSRoy Marples [ -z "$now" ] && break 1168d36e1dfSRoy Marples offset=$(($now - $acquired)) 1177827cba2SAaron LI while true; do 1187827cba2SAaron LI eval_nd_dns || break 1197827cba2SAaron LI done 1207827cba2SAaron LI i=$(($i + 1)) 1217827cba2SAaron LI j=1 1227827cba2SAaron LI done 1237827cba2SAaron LI [ -n "$new_rdnss" ] && \ 1247827cba2SAaron LI new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss" 1257827cba2SAaron LI [ -n "$new_dnssl" ] && \ 1267827cba2SAaron LI new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl" 1277827cba2SAaron LI 1287827cba2SAaron LI # Derive a new domain from our various hostname options 1297827cba2SAaron LI if [ -z "$new_domain_name" ]; then 1307827cba2SAaron LI if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then 1317827cba2SAaron LI new_domain_name="${new_dhcp6_fqdn#*.}" 1327827cba2SAaron LI elif [ "$new_fqdn" != "${new_fqdn#*.}" ]; then 1337827cba2SAaron LI new_domain_name="${new_fqdn#*.}" 1347827cba2SAaron LI elif [ "$new_host_name" != "${new_host_name#*.}" ]; then 1357827cba2SAaron LI new_domain_name="${new_host_name#*.}" 1367827cba2SAaron LI fi 1377827cba2SAaron LI fi 1387827cba2SAaron LI 1397827cba2SAaron LI # If we don't have any configuration, remove it 1408d36e1dfSRoy Marples if [ -z "$new_domain_name_servers" ] && 1418d36e1dfSRoy Marples [ -z "$new_domain_name" ] && 1428d36e1dfSRoy Marples [ -z "$new_domain_search" ]; then 1437827cba2SAaron LI remove_resolv_conf 1447827cba2SAaron LI return $? 1457827cba2SAaron LI fi 1467827cba2SAaron LI 1477827cba2SAaron LI if [ -n "$new_domain_name" ]; then 1487827cba2SAaron LI set -- $new_domain_name 1497827cba2SAaron LI if valid_domainname "$1"; then 1507827cba2SAaron LI conf="${conf}domain $1$NL" 1517827cba2SAaron LI else 1527827cba2SAaron LI syslog err "Invalid domain name: $1" 1537827cba2SAaron LI fi 1547827cba2SAaron LI # If there is no search this, make this one 1557827cba2SAaron LI if [ -z "$new_domain_search" ]; then 1567827cba2SAaron LI new_domain_search="$new_domain_name" 1577827cba2SAaron LI [ "$new_domain_name" = "$1" ] && warn=true 1587827cba2SAaron LI fi 1597827cba2SAaron LI fi 1607827cba2SAaron LI if [ -n "$new_domain_search" ]; then 1616e63cc1fSRoy Marples new_domain_search=$(uniqify $new_domain_search) 1627827cba2SAaron LI if valid_domainname_list $new_domain_search; then 1637827cba2SAaron LI conf="${conf}search $new_domain_search$NL" 1647827cba2SAaron LI elif ! $warn; then 1657827cba2SAaron LI syslog err "Invalid domain name in list:" \ 1667827cba2SAaron LI "$new_domain_search" 1677827cba2SAaron LI fi 1687827cba2SAaron LI fi 1696e63cc1fSRoy Marples new_domain_name_servers=$(uniqify $new_domain_name_servers) 1707827cba2SAaron LI for x in ${new_domain_name_servers}; do 1717827cba2SAaron LI conf="${conf}nameserver $x$NL" 1727827cba2SAaron LI done 1730aaf6155SRoy Marples if $have_resolvconf; then 1747827cba2SAaron LI [ -n "$ifmetric" ] && export IF_METRIC="$ifmetric" 1757827cba2SAaron LI printf %s "$conf" | "$resolvconf" -a "$ifname" 1767827cba2SAaron LI return $? 1777827cba2SAaron LI fi 1787827cba2SAaron LI 1797827cba2SAaron LI if [ -e "$resolv_conf_dir/$ifname" ]; then 1807827cba2SAaron LI rm -f "$resolv_conf_dir/$ifname" 1817827cba2SAaron LI fi 1827827cba2SAaron LI [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" 1837827cba2SAaron LI printf %s "$conf" > "$resolv_conf_dir/$ifname" 1847827cba2SAaron LI build_resolv_conf 1857827cba2SAaron LI} 1867827cba2SAaron LI 1877827cba2SAaron LIremove_resolv_conf() 1887827cba2SAaron LI{ 1890aaf6155SRoy Marples if $have_resolvconf; then 1907827cba2SAaron LI "$resolvconf" -d "$ifname" -f 1917827cba2SAaron LI else 1927827cba2SAaron LI if [ -e "$resolv_conf_dir/$ifname" ]; then 1937827cba2SAaron LI rm -f "$resolv_conf_dir/$ifname" 1947827cba2SAaron LI fi 1957827cba2SAaron LI build_resolv_conf 1967827cba2SAaron LI fi 1977827cba2SAaron LI} 1987827cba2SAaron LI 1997827cba2SAaron LI# For ease of use, map DHCP6 names onto our DHCP4 names 2007827cba2SAaron LIcase "$reason" in 2017827cba2SAaron LIBOUND6|RENEW6|REBIND6|REBOOT6|INFORM6) 2027827cba2SAaron LI new_domain_name_servers="$new_dhcp6_name_servers" 2037827cba2SAaron LI new_domain_search="$new_dhcp6_domain_search" 2047827cba2SAaron LI ;; 2057827cba2SAaron LIesac 2067827cba2SAaron LI 207b2927f2bSRoy Marplesif $if_configured; then 2080aaf6155SRoy Marples if $have_resolvconf && [ "$reason" = NOCARRIER_ROAMING ]; then 2090aaf6155SRoy Marples # avoid calling resolvconf -c on CARRIER unless we roam 2100aaf6155SRoy Marples mkdir -p "$nocarrier_roaming_dir" 2110aaf6155SRoy Marples echo " " >"$nocarrier_roaming_dir/$interface" 2120aaf6155SRoy Marples "$resolvconf" -C "$interface.*" 2130aaf6155SRoy Marples elif $have_resolvconf && [ "$reason" = CARRIER ]; then 2140aaf6155SRoy Marples # Not all resolvconf implementations support -c 2150aaf6155SRoy Marples if [ -e "$nocarrier_roaming_dir/$interface" ]; then 2160aaf6155SRoy Marples rm -f "$nocarrier_roaming_dir/$interface" 2170aaf6155SRoy Marples "$resolvconf" -c "$interface.*" 2180aaf6155SRoy Marples fi 2190aaf6155SRoy Marples elif $if_up || [ "$reason" = ROUTERADVERT ]; then 2207827cba2SAaron LI add_resolv_conf 2217827cba2SAaron LI elif $if_down; then 2227827cba2SAaron LI remove_resolv_conf 2237827cba2SAaron LI fi 224b2927f2bSRoy Marplesfi 225