| #!/bin/sh /etc/rc.common |
| # Copyright (C) 2006-2014 OpenWrt.org |
| |
| START=94 |
| STOP=15 |
| USE_PROCD=1 |
| PROG=/usr/sbin/miniupnpd |
| |
| 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 action int_addr |
| local ext_start ext_end int_start int_end comment |
| |
| 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 |
| config_get comment "$cfg" comment "ACL" # comment |
| |
| # Make a single IP IP/32 so that miniupnpd.conf can use it. |
| [ "${int_addr%/*}" = "$int_addr" ] && int_addr="$int_addr/32" |
| |
| echo "$action $ext_start${ext_end:+-}$ext_end $int_addr $int_start${int_end:+-}$int_end #$comment" |
| } |
| |
| upnpd_write_bool() { |
| local opt="$1" |
| local def="${2:-0}" |
| local alt="${3:-$opt}" |
| local val |
| |
| config_get_bool val config "$opt" "$def" |
| if [ "$val" -eq 0 ]; then |
| echo "$alt=no" |
| else |
| echo "$alt=yes" |
| fi |
| } |
| |
| upnpd() { |
| config_load "upnpd" |
| local external_iface external_iface6 external_zone external_ip internal_iface |
| local upload download log_output port config_file serial_number model_number |
| local use_stun stun_host stun_port uuid notify_interval presentation_url |
| local upnp_lease_file clean_ruleset_threshold clean_ruleset_interval |
| local ipv6_disable |
| |
| local enabled |
| config_get_bool enabled config enabled 1 |
| [ "$enabled" -eq 0 ] && return 1 |
| |
| config_get external_iface config external_iface |
| config_get external_iface6 config external_iface6 |
| config_get external_zone config external_zone |
| config_get external_ip config external_ip |
| config_get internal_iface config internal_iface |
| config_get port config port 5000 |
| config_get upload config upload |
| config_get download config download |
| config_get_bool log_output config log_output 0 |
| config_get config_file config config_file |
| config_get serial_number config serial_number |
| config_get model_number config model_number |
| config_get uuid config uuid |
| config_get use_stun config use_stun 0 |
| config_get stun_host config stun_host |
| config_get stun_port config stun_port |
| 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 |
| config_get ipv6_disable config ipv6_disable 0 |
| |
| local conf ifname ifname6 |
| |
| . /lib/functions/network.sh |
| |
| if [ -n "$external_iface" ] ; then |
| network_get_device ifname "$external_iface" |
| else |
| if [ -n "$external_zone" ] ; then |
| ifname=$(fw3 -q zone "$external_zone" 2>/dev/null | head -1) |
| else |
| network_find_wan external_iface && \ |
| network_get_device ifname "$external_iface" |
| fi |
| fi |
| if [ -n "$external_iface6" ] ; then |
| network_get_device ifname6 "$external_iface6" |
| else |
| if [ -n "$external_zone" ] ; then |
| ifname6=$(fw3 -q zone "$external_zone" 2>/dev/null | head -1) |
| else |
| network_find_wan6 external_iface6 && \ |
| network_get_device ifname6 "$external_iface6" |
| fi |
| fi |
| |
| if [ -n "$config_file" ]; then |
| conf="$config_file" |
| else |
| local tmpconf="/var/etc/miniupnpd.conf" |
| conf="$tmpconf" |
| mkdir -p /var/etc |
| |
| { |
| echo "ext_ifname=$ifname" |
| echo "ext_ifname6=$ifname6" |
| [ -n "$external_ip" ] && echo "ext_ip=$external_ip" |
| |
| local iface |
| for iface in ${internal_iface:-lan}; do |
| local device |
| network_get_device device "$iface" && echo "listening_ip=$device" |
| done |
| |
| 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 |
| upnpd_write_bool igdv1 0 force_igd_desc_v1 |
| upnpd_write_bool use_stun 0 ext_perform_stun |
| upnpd_write_bool ipv6_disable $ipv6_disable |
| |
| [ "$use_stun" -eq 0 ] || { |
| [ -n "$stun_host" ] && echo "ext_stun_host=$stun_host" |
| [ -n "$stun_port" ] && echo "ext_stun_port=$stun_port" |
| } |
| |
| [ -n "$upload" ] && [ -n "$download" ] && { |
| echo "bitrate_down=$((download * 1024 * 8))" |
| echo "bitrate_up=$((upload * 1024 * 8))" |
| } |
| |
| [ -n "$upnp_lease_file" ] && touch "$upnp_lease_file" && echo "lease_file=$upnp_lease_file" |
| [ -n "$presentation_url" ] && echo "presentation_url=$presentation_url" |
| [ -n "$notify_interval" ] && echo "notify_interval=$notify_interval" |
| [ -n "$clean_ruleset_threshold" ] && echo "clean_ruleset_threshold=$clean_ruleset_threshold" |
| [ -n "$clean_ruleset_interval" ] && echo "clean_ruleset_interval=$clean_ruleset_interval" |
| [ -n "$serial_number" ] && echo "serial=$serial_number" |
| [ -n "$model_number" ] && echo "model_number=$model_number" |
| [ -n "$port" ] && echo "port=$port" |
| |
| [ -z "$uuid" ] && { |
| uuid="$(cat /proc/sys/kernel/random/uuid)" |
| uci set upnpd.config.uuid="$uuid" |
| uci commit upnpd |
| } |
| |
| [ "$uuid" = "nocli" ] || echo "uuid=$uuid" |
| |
| config_foreach conf_rule_add perm_rule |
| |
| } > "$tmpconf" |
| fi |
| |
| if [ -n "$ifname" ]; then |
| # start firewall |
| iptables -L MINIUPNPD >/dev/null 2>&1 || fw3 reload |
| else |
| logger -t "upnp daemon" "external interface not found, not starting" |
| fi |
| |
| procd_open_instance |
| procd_set_param command "$PROG" |
| procd_append_param command -f "$conf" |
| [ "$log_output" = "1" ] && procd_append_param command -d |
| procd_close_instance |
| } |
| |
| stop_service() { |
| iptables -t nat -F MINIUPNPD 2>/dev/null |
| iptables -t nat -F MINIUPNPD-POSTROUTING 2>/dev/null |
| iptables -t filter -F MINIUPNPD 2>/dev/null |
| |
| [ -x /usr/sbin/ip6tables ] && ip6tables -t filter -F MINIUPNPD 2>/dev/null |
| } |
| |
| start_service() { |
| config_load "upnpd" |
| config_foreach upnpd "upnpd" |
| } |
| |
| service_triggers() { |
| procd_add_reload_trigger "upnpd" |
| } |