#!/usr/bin/bash
# based heavily on http://naju.se/articles/openvpn-netns

[[ $EUID -ne 0 ]] && {
    printf "%s: this program requires root privileges. try again with \`sudo'?\n" "$0" >&2
    exit 1
}

# convert a dot-decimal mask (e.g., 255.255.255.0) to a bit-count mask
# (like /24) for iproute2. this probably isn't the most beautiful way.
tobitmask() {
    bits=0
    while read -rd . octet; do
        (( col = 2**7 ))
        while (( col > 0 )); do
            (( octet & col )) || break 2
            (( bits++ ))
            (( col >>= 1 ))
        done
    done <<<"$1"
    printf '%d\n' $bits
}

# Inspired by the GPL-licensed /etc/openvpn/update-resolv-conf from the
# openvpn package
generate_resolvconf() {
    printf '# Generated by vpnc-script-netns\n'

    env | grep '^foreign_option_[[:digit:]]\{1,\}=' | cut -d = -f 2- | \
        while read -r foreign_option; do
            pieces=( $foreign_option )
            if [[ ${pieces[0]} = "dhcp-option" \
                  && ${pieces[1]} = "DNS" \
                  && -n ${pieces[2]} ]]; then
                printf 'nameserver %s\n' "${pieces[2]}"
            elif [[ ${pieces[0]} = "dhcp-option" \
                    && ${pieces[1]} = "DOMAIN" \
                    && -n ${pieces[2]} ]]; then
                printf 'search %s\n' "${pieces[2]}"
            fi
        done
}

# guess name of network namespace from name of config file
basename=$(basename "$config")
ns=${basename%.conf}
etc_path=/var/ns-etc/$ns
netmask=$(tobitmask "$ifconfig_netmask")

case $script_type in
    up)
        ip -netns "$ns" link set dev lo up
        ip link set dev $dev up netns "$ns" mtu "$tun_mtu"
        ip -netns "$ns" addr add "$ifconfig_local/$netmask" dev "$dev"

        # Configure resolv.conf
        mkdir -p "$etc_path"
        generate_resolvconf >"$etc_path/resolv.conf"
    ;;
    route-up)
        ip -netns "$ns" route add default via "$route_vpn_gateway"
    ;;
    *)
        printf "%s: unknown \$script_type: \`$script_type'" "$0" >&2
        exit 2;
    ;;
esac
