summaryrefslogblamecommitdiffstats
path: root/dhcpcd-hooks/20-resolv.conf
blob: 385f850a1b9da11f3427513a2aaee5595da4b066 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                    





                                                                         
                                        
 

                   
                                                    
                                                           

                                    
                                                        
 
                               
                                     

                                          
                                                       


                                       
                                                 
                                                              
                                                 
                                                              


                                    
                                           


                                            
                                                                        
 
                                           
                                               
                                                                  
                                               
                                                           
                    
          
                                                         
 
                                                            

                                   
                                             
                                                  
            
                                                                             
          
                                                
                                             
                                                  
            
                                                                             
          
                                    
                                  
                   
 
 
                 
 
                                    

                                                       


                                               

                                  
          
 

                                          
                                    
                                                       
                                                        
                                                               


                                              

                                                         

                                               
                                             

                                                

                                                              
                         
          
 

                                                     
          

                                            
          
                                                      
                         

 
                    

                                                
                                             
            

                                                             

                                 


          
                 
                                                                         
                                                                            
    
# 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"

build_resolv_conf()
{
	local cf="$state_dir/resolv.conf.$interface"
	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}
		unset domain
		if [ -n "$2" ]; then
			search="$search $@"
		elif [ -n "$1" ]; then
			domain="domain $1\n"
		fi
		[ -n "$search" ] && search="search $(uniqify $search)\n"

		# Build the nameserver list
		srvs=$(cd "$resolv_conf_dir"; \
			key_get_value "nameserver " ${interfaces})
		for x in $(uniqify ${srvs}); do
			servers="${servers}nameserver $x\n"
		done
	fi
	header="$signature_base${header:+ $from }$header"

	# Assemble resolv.conf using our head and tail files
	[ -f "$cf" ] && rm -f "$cf"
	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 "$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
	cat "$cf" > /etc/resolv.conf
	chmod 644 /etc/resolv.conf
	rm -f "$cf"
}

add_resolv_conf()
{
	local x= conf="$signature\n"

	# 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

	if [ -n "$new_domain_name" ]; then
		set -- $new_domain_name
		new_domain_name="$1"
		conf="${conf}domain $new_domain_name\n"
		# 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" ]; then
		conf="${conf}search $new_domain_search\n"
	fi
	for x in ${new_domain_name_servers}; do
		conf="${conf}nameserver $x\n"
	done
	if type resolvconf >/dev/null 2>&1; then
		[ -n "$metric" ] && export IF_METRIC="$metric"
		printf "$conf" | resolvconf -a "$interface"
		return $?
	fi

	if [ -e "$resolv_conf_dir/$interface" ]; then
		rm -f "$resolv_conf_dir/$interface"
	fi
	if [ ! -d "$resolv_conf_dir" ]; then
		mkdir -p "$resolv_conf_dir"
	fi
	printf "$conf" > "$resolv_conf_dir/$interface"
	build_resolv_conf
}

remove_resolv_conf()
{
	if type resolvconf >/dev/null 2>&1; then
		resolvconf -d "$interface" -f
	else
		if [ -e "$resolv_conf_dir/$interface" ]; then
			rm -f "$resolv_conf_dir/$interface"
		fi
		build_resolv_conf
	fi
}

case "$reason" in
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC)	add_resolv_conf;;
PREINIT|EXPIRE|FAIL|IPV4LL|NAK|NOCARRIER|RELEASE|STOP)	remove_resolv_conf;;
esac