aboutsummaryrefslogtreecommitdiff
path: root/net/miniupnpd/files/miniupnpd.init
blob: de3504529b600cfad52f70199e9cb36b40baa183 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2014 OpenWrt.org

START=94
STOP=15
USE_PROCD=1
PROG=/usr/sbin/miniupnpd
[ -x "$(command -v nft)" ] && FW="fw4" || FW="fw3"

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=$($FW -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=$($FW -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

		if [ "$FW" = "fw4" ]; then
			#When using nftables configure miniupnpd to use its own table and chains
			echo "upnp_table_name=fw4"
			echo "upnp_nat_table_name=fw4"
			echo "upnp_forward_chain=upnp_forward"
			echo "upnp_nat_chain=upnp_prerouting"
			echo "upnp_nat_postrouting_chain=upnp_postrouting"
		fi

		} > "$tmpconf"
	fi

	if [ -n "$ifname" ]; then
		# start firewall
		if [ "$FW" = "fw4" ]; then
			nft -s -t -n list chain inet fw4 upnp_forward >/dev/null 2>&1 || fw4 reload
		else
			iptables -L MINIUPNPD >/dev/null 2>&1 || fw3 reload
		fi
	else
		logger -t "upnp daemon" "external interface not found, not starting"
	fi

	procd_open_instance
	procd_set_param file "$conf" "/etc/config/firewall"
	procd_set_param command "$PROG"
	procd_append_param command -f "$conf"
	[ "$log_output" = "1" ] && procd_append_param command -d
	procd_close_instance
}

stop_service() {
	if [ "$FW" = "fw3" ]; then
		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
	else
		nft flush chain inet fw4 upnp_forward 2>/dev/null
		nft flush chain inet fw4 upnp_prerouting 2>/dev/null
		nft flush chain inet fw4 upnp_postrouting 2>/dev/null
	fi
}

start_service() {
	config_load "upnpd"
	config_foreach upnpd "upnpd"
}

service_triggers() {
	procd_add_reload_trigger "upnpd"
}