dns.sh (3682B)
1 #!/bin/sh 2 # 3 # dns 4 5 # system copy of /etc/resolv.conf 6 RESOLV_SYS='/etc/resolv.conf' 7 # nm's copy of resolv.conf 8 RESOLV_NM='/var/run/NetworkManager/resolv.conf' 9 10 # check to see whether ethernet interface is up 11 eth_is_up() { 12 # show active interfaces via nmcli and grep for the one we want 13 nmcli -t -f DEVICE connection show --active | grep "${1}" >/dev/null 14 15 #shellcheck disable=SC2046 16 return $(get_interface_status "${?}") 17 } 18 19 get_interface_status() { 20 status="${1}" 21 # interface is up 22 if [ "${status}" = '0' ]; then 23 return 0 24 # interface is down 25 else 26 return 1 27 fi 28 } 29 30 # get wlan interface name 31 get_wlan_interface() { 32 # loop over interfaces in /sys/class/net 33 for interface in '/sys/class/net/'*; do 34 # wireless interfaces will have a subfolder called 'wireless' 35 # if carrier = 1, then the interface is up 36 if [ -d "${interface}/wireless/" ] && [ "$(cat "${interface}/carrier")" = '1' ]; then 37 printf '%s\n' "${interface##*/}" 38 fi 39 done 40 41 return 0 42 } 43 44 # check to see whether wifi is up 45 wifi_is_up() { 46 # get ssid of wlan via iw 47 ssid="$(iw dev "${1}" info 2>/dev/null | grep -i '\<ssid\>' | awk '{ print $2 }')" 48 49 # if no ssid, then the wifi is down and /etc/resolv.conf may be blank 50 if [ -z "${ssid}" ]; then 51 return 1 52 else 53 return 0 54 fi 55 } 56 57 main() { 58 # this script requires iwd and nm 59 if ! command -v iw >/dev/null && ! command -v nmcli >/dev/null; then 60 printf '%s\n' 'iw and NetworkManager are required to run this script.' 61 return 1 62 fi 63 64 # get name of eth interface 65 eth_interface="$(basename '/sys/class/net/eth'*)" 66 # get name of wlan interface 67 wlan_interface="$(get_wlan_interface)" 68 69 # automatically get nameservers if wifi goes down but ethernet remains 70 while :; do 71 # if eth interface is up, then check for nameservers 72 if eth_is_up "${eth_interface}"; then 73 grep 'nameserver' "${RESOLV_SYS}" >/dev/null 74 has_dns="${?}" 75 76 # if there are nameservers, then the wifi interface must be up (or the ethernet interface was manually enabled) 77 # do nothing 78 if [ "${has_dns}" = '0' ]; then 79 : 80 # if there are no nameservers, then replace /etc/resolv.conf with nm's resolv.conf 81 else 82 cp "${RESOLV_NM}" "${RESOLV_SYS}" 83 fi 84 # if eth interface is down, then it could've been disabled manually 85 # if wifi is still up, then add the nameserver(s) from dhcpcd's resolv.conf 86 else 87 # if wifi is up, then check for nameserver(s) 88 if wifi_is_up "${wlan_interface}"; then 89 grep 'nameserver' "${RESOLV_SYS}" >/dev/null 90 has_dns="${?}" 91 92 # if there is a nameserver or if there are nameservers, then do nothing 93 if [ "${has_dns}" = '0' ]; then 94 : 95 # if there aren't any nameservers, then copy dhcpcd's resolv.conf to /etc/resolv.conf 96 else 97 # dhcpcd's resolv.conf contents for the wlan interface should be located here 98 resolv_dhcpcd="/var/run/dhcpcd/hook-state/resolv.conf/${wlan_interface}.dhcp" 99 # if dhcpcd does have a resolv.conf, then proceed 100 if [ -e "${resolv_dhcpcd}" ]; then 101 cp "${resolv_dhcpcd}" "${RESOLV_SYS}" 102 else 103 : 104 fi 105 fi 106 else 107 : 108 fi 109 fi 110 sleep 10 111 done 112 113 return 0 114 } 115 116 main "${@}"