#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org

START=95
tmpconf="/var/etc/miniupnpd.conf"
export PROCLINE="/usr/sbin/miniupnpd -f $tmpconf"
#export PROCLINE="/usr/sbin/miniupnpd -f $tmpconf -d"
export PROCFLAG=$PROCLINE

upnpd_get_port_range() {
    local _var="$1"
    shift
    local _val

    config_get _val "$@"

    case "$_val" in
    [0-9]*[:-][0-9]*)
        export -n -- "${_var}_start=${_val%%[:-]*}"
        export -n -- "${_var}_end=${_val##*[:-]}"
        ;;
    [0-9]*)
        export -n -- "${_var}_start=$_val"
        export -n -- "${_var}_end="
        ;;
    esac
}

conf_rule_add() {
    local cfg="$1"
    local tmpconf="$2"
    local action external_port_start external_port_end int_addr
    local internal_port_start internal_port_end

    config_get action "$cfg" action "deny"                # allow or deny
    upnpd_get_port_range "ext" "$cfg" ext_ports "0-65535" # external ports: x, x-y, x:y
    config_get int_addr "$cfg" int_addr "0.0.0.0/0"       # ip or network and subnet mask (internal)
    upnpd_get_port_range "int" "$cfg" int_ports "0-65535" # internal ports: x, x-y, x:y or range

    # Make a single IP IP/32 so that miniupnpd.conf can use it.
    case "$int_addr" in
    */*) ;;
    *) int_addr="$int_addr/32" ;;
    esac

    echo "${action} ${ext_start}${ext_end:+-}${ext_end} ${int_addr} ${int_start}${int_end:+-}${int_end}" >>$tmpconf
}

upnpd_write_bool() {
    local opt="$1"
    local def="${2:-0}"
    local alt="$3"
    local val

    config_get_bool val config "$opt" "$def"
    if [ "$val" -eq 0 ]; then
        echo "${alt:-$opt}=no" >>$tmpconf
    else
        echo "${alt:-$opt}=yes" >>$tmpconf
    fi
}

boot() {
    return 0
}

enabled() {
    if [ -f /etc/config/upnpd ]; then
        local val=`grep disable_upnp /etc/config/upnpd`
        if [ "$val" != "" ]; then
            /etc/init.d/miniupnpd disable
        fi
    fi
    name="$(basename "${initscript}")"
    [ -x "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}" ]
}

start() {
    if [ -f /etc/config/upnpd ]; then
        local val=`grep disable_upnp /etc/config/upnpd`
        [ "$val" != "" ] && return 0
    fi
    config_load "upnpd"
    local extiface intiface upload download logging secure enabled natpmp
    local extip port usesysuptime serial_number model_number
    local uuid notify_interval presentation_url enable_upnp
    local upnp_lease_file clean_ruleset_threshold clean_ruleset_interval

    config_get extiface config external_iface
    config_get intiface config internal_iface
    config_get extip config external_ip
    config_get port config port 5000
    config_get upload config upload
    config_get download config download
    config_get_bool logging config log_output 0
    config_get serial_number config serial_number
    config_get model_number config model_number
    config_get uuid config uuid
    config_get notify_interval config notify_interval
    config_get presentation_url config presentation_url
    config_get upnp_lease_file config upnp_lease_file
    config_get clean_ruleset_threshold config clean_ruleset_threshold
    config_get clean_ruleset_interval config clean_ruleset_interval

    local args

    . /lib/functions/network.sh

    local ifname
    network_get_device ifname ${extiface:-wan}

    mkdir -p /var/etc

    echo "ext_ifname=$ifname" >$tmpconf

    [ -n "$extip" ] &&
        echo "ext_ip=$extip" >>$tmpconf

    local iface
    for iface in ${intiface:-lan}; do
        local device
        network_get_device device "$iface" && {
            echo "listening_ip=$device" >>$tmpconf
        }
    done

    [ "$port" != "auto" ] &&
        echo "port=$port" >>$tmpconf

    config_load "upnpd"
    upnpd_write_bool enable_natpmp 1
    upnpd_write_bool enable_upnp 1
    upnpd_write_bool secure_mode 1
    upnpd_write_bool system_uptime 1

    [ -n "$upnp_lease_file" ] && {
        touch $upnp_lease_file
        echo "lease_file=$upnp_lease_file" >>$tmpconf
    }

    [ -n "$upload" -a -n "$download" ] && {
        echo "bitrate_down=$(($download * 1024 * 8))" >>$tmpconf
        echo "bitrate_up=$(($upload * 1024 * 8))" >>$tmpconf
    }

    [ -n "${presentation_url}" ] &&
        echo "presentation_url=${presentation_url}" >>$tmpconf

    [ -n "${notify_interval}" ] &&
        echo "notify_interval=${notify_interval}" >>$tmpconf

    [ -n "${clean_ruleset_threshold}" ] &&
        echo "clean_ruleset_threshold=${clean_ruleset_threshold}" >>$tmpconf

    [ -n "${clean_ruleset_interval}" ] &&
        echo "clean_ruleset_interval=${clean_ruleset_interval}" >>$tmpconf

    [ -z "$uuid" ] && {
        uuid="$(cat /proc/sys/kernel/random/uuid)"
        uci set upnpd.config.uuid=$uuid
        uci commit upnpd
    }

    [ "$uuid" = "nocli" ] ||
        echo "uuid=$uuid" >>$tmpconf

    [ -n "${serial_number}" ] &&
        echo "serial=${serial_number}" >>$tmpconf

    [ -n "${model_number}" ] &&
        echo "model_number=${model_number}" >>$tmpconf

    config_foreach conf_rule_add perm_rule "$tmpconf"

    if [ -n "$ifname" ]; then
        # start firewall
        iptables -L MINIUPNPD >/dev/null 2>/dev/null || fw3 reload

        /usr/sbin/supervisord start
    else
        logger -t "upnp daemon" "external interface not found, not starting"
    fi
    return 0
}

stop() {
    /usr/sbin/supervisord stop

    iptables -t nat -F MINIUPNPD 2>/dev/null
    iptables -t filter -F MINIUPNPD 2>/dev/null
    return 0
}
