dots

git clone git://mattcarlson.org/repos/dots.git
Log | Files | Refs

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 "${@}"