#!/bin/bash
# 
# Parses DHCP options from openvpn to update resolv.conf
# Supports both resolvconf (old) and resolvectl/systemd-resolved (Ubuntu 22.04+)
#
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /usr/sbin/vpnu_update-resolv-conf
# down /usr/sbin/vpnu_update-resolv-conf
#

[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0

# Detect which DNS management tool is available
USE_RESOLVECTL=0
USE_RESOLVCONF=0

if [ -x /usr/bin/resolvectl ]; then
    USE_RESOLVECTL=1
elif [ -x /sbin/resolvconf ]; then
    USE_RESOLVCONF=1
else
    echo "Neither resolvectl nor resolvconf found, skipping DNS configuration"
    exit 0
fi

split_into_parts()
{
    part1="$1"
    part2="$2"
    part3="$3"
}

case "$script_type" in
  up)
    NMSRVRS=""
    SRCHS=""
    for optionvarname in ${!foreign_option_*} ; do
        option="${!optionvarname}"
        echo "$option"
        split_into_parts $option
        if [ "$part1" = "dhcp-option" ] ; then
            if [ "$part2" = "DNS" ] ; then
                NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
            elif [ "$part2" = "DOMAIN" ] ; then
                SRCHS="${SRCHS:+$SRCHS }$part3"
            fi
        fi
    done

    if [ $USE_RESOLVECTL -eq 1 ]; then
        if [ -n "$NMSRVRS" ]; then
            nmcli device set "$dev" managed no
            resolvectl dns "$dev" $NMSRVRS
            resolvectl domain "$dev" ~.
            resolvectl default-route "$dev" yes
            resolvectl llmnr "$dev" no
            resolvectl mdns "$dev" no
            echo "DNS configured via resolvectl: $NMSRVRS"

            for iface in $(resolvectl status | grep "Link " | awk '{print $3}' | tr -d '()'); do
                if [ "$iface" != "$dev" ]; then
                    resolvectl default-route "$iface" no 2>/dev/null || true
                fi
            done
        fi
    else
        R=""
        [ "$SRCHS" ] && R="search $SRCHS
"
        for NS in $NMSRVRS ; do
            R="${R}nameserver $NS
"
        done
        echo -n "$R" | /sbin/resolvconf -a "${dev}.openvpn"

        for NS in $NMSRVRS ; do
            echo 'Adding port 53 redirection...'
            iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to "$NS"
            iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to "$NS"
        done
    fi
    ;;

  down)
    if [ $USE_RESOLVECTL -eq 1 ]; then
        resolvectl revert "$dev"
        nmcli device set "$dev" managed yes 2>/dev/null || true
        echo "DNS reverted via resolvectl for $dev"

        for iface in $(resolvectl status | grep "Link " | awk '{print $3}' | tr -d '()'); do
            if [ "$iface" != "$dev" ]; then
                resolvectl default-route "$iface" yes 2>/dev/null || true
            fi
        done
    else
        /sbin/resolvconf -d "${dev}.openvpn"
        /sbin/resolvconf -u

        NMSRVRS=""
        for optionvarname in ${!foreign_option_*} ; do
            option="${!optionvarname}"
            split_into_parts $option
            if [ "$part1" = "dhcp-option" ] ; then
                if [ "$part2" = "DNS" ] ; then
                    NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
                fi
            fi
        done

        for NS in $NMSRVRS ; do
            echo 'Removing port 53 redirection...'
            iptables -t nat -D OUTPUT -p udp --dport 53 -j DNAT --to "$NS"
            iptables -t nat -D OUTPUT -p tcp --dport 53 -j DNAT --to "$NS"
        done
    fi
    ;;
esac
