Changeset View
Changeset View
Standalone View
Standalone View
contrib/dhcpcd/hooks/20-resolv.conf
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
# 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=" | |||||
" | |||||
: ${resolvconf:=resolvconf} | |||||
build_resolv_conf() | |||||
{ | |||||
cf="$state_dir/resolv.conf.$ifname" | |||||
# Build a list of interfaces | |||||
interfaces=$(list_interfaces "$resolv_conf_dir") | |||||
# Build the resolv.conf | |||||
header= | |||||
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" | |||||
} | |||||
# Extract any ND DNS options from the RA | |||||
# Obey the lifetimes | |||||
eval_nd_dns() | |||||
{ | |||||
eval rdnsstime=\$nd${i}_rdnss${j}_lifetime | |||||
[ -z "$rdnsstime" ] && return 1 | |||||
ltime=$(($rdnsstime - $offset)) | |||||
if [ "$ltime" -gt 0 ]; then | |||||
eval rdnss=\$nd${i}_rdnss${j}_servers | |||||
[ -n "$rdnss" ] && new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss" | |||||
fi | |||||
eval dnssltime=\$nd${i}_dnssl${j}_lifetime | |||||
[ -z "$dnssltime" ] && return 1 | |||||
ltime=$(($dnssltime - $offset)) | |||||
if [ "$ltime" -gt 0 ]; then | |||||
eval dnssl=\$nd${i}_dnssl${j}_search | |||||
[ -n "$dnssl" ] && new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl" | |||||
fi | |||||
j=$(($j + 1)) | |||||
return 0 | |||||
} | |||||
add_resolv_conf() | |||||
{ | |||||
conf="$signature$NL" | |||||
warn=true | |||||
# Loop to extract the ND DNS options using our indexed shell values | |||||
i=1 | |||||
j=1 | |||||
while true; do | |||||
eval acquired=\$nd${i}_acquired | |||||
[ -z "$acquired" ] && break | |||||
eval now=\$nd${i}_now | |||||
[ -z "$now" ] && break | |||||
offset=$(($now - $acquired)) | |||||
while true; do | |||||
eval_nd_dns || break | |||||
done | |||||
i=$(($i + 1)) | |||||
j=1 | |||||
done | |||||
[ -n "$new_rdnss" ] && \ | |||||
new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss" | |||||
[ -n "$new_dnssl" ] && \ | |||||
new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl" | |||||
# 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 we don't have any configuration, remove it | |||||
if [ -z "$new_domain_name_servers" ] && | |||||
[ -z "$new_domain_name" ] && | |||||
[ -z "$new_domain_search" ]; then | |||||
remove_resolv_conf | |||||
return $? | |||||
fi | |||||
if [ -n "$new_domain_name" ]; then | |||||
set -- $new_domain_name | |||||
if valid_domainname "$1"; then | |||||
conf="${conf}domain $1$NL" | |||||
else | |||||
syslog err "Invalid domain name: $1" | |||||
fi | |||||
# If there is no search this, make this one | |||||
if [ -z "$new_domain_search" ]; then | |||||
new_domain_search="$new_domain_name" | |||||
[ "$new_domain_name" = "$1" ] && warn=true | |||||
fi | |||||
fi | |||||
if [ -n "$new_domain_search" ]; then | |||||
if valid_domainname_list $new_domain_search; then | |||||
conf="${conf}search $new_domain_search$NL" | |||||
elif ! $warn; then | |||||
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 |