HEX
Server: Apache/2.2.34 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141
System: Linux Kou-Etsu-Dou 4.4.59+ #25556 SMP PREEMPT Thu Mar 4 18:03:46 CST 2021 x86_64
User: hosam (1026)
PHP: 7.2.29
Disabled: NONE
Upload Files
File: //usr/syno/bin/miniupnp-tool.sh
#!/bin/sh
# Copyright (c) 2000-2013 Synology Inc. All rights reserved.

CHAIN_FWD="FUPNPD"
CHAIN_NAT="NUPNPD"
IFCONFIG="/sbin/ifconfig"
UNAME="/bin/uname"
UUID_GEN="/usr/bin/uuidgen"
IPTABLES="/sbin/iptables"
IP_SAVE="/sbin/iptables-save"
UPNPD="/usr/bin/miniupnpd"
UPNPD_PID="/tmp/miniupnpd-"
UPNPD_CONFIG_DIR="/etc/sysconfig/miniupnpd"
UPNPD_CONFIG_NAME_FORMAT=".*upnp-\(.*\)-\(.*\).conf"

generate_nat_chain() {
	local if_ext=$1

	if [ -z "${if_ext}" ]; then
		return 0
	fi
	CHAIN_NAT_NAME="${CHAIN_NAT}-${if_ext}"
	return 1
}

generate_fwd_chain() {
	local if_ext=$1

	if [ -z "${if_ext}" ]; then
		return 0
	fi
	CHAIN_FWD_NAME="${CHAIN_FWD}-${if_ext}"
	return 1
}

generate_config_name() {
	local if_ext=$1
	local if_inn=$2

	if [ -z "${if_ext}" -o -z "${if_inn}" ]; then
		return 0
	fi
	if [ ! -d "${UPNPD_CONFIG_DIR}" ]; then
		`mkdir -p ${UPNPD_CONFIG_DIR}`
	fi
	CONFIG_FILENAME="${UPNPD_CONFIG_DIR}/upnp-${if_ext}-${if_inn}.conf"
	return 1
}

check_iface_alive() {
	local if_name=$1

	count=`${IFCONFIG} | grep "^${if_name}" | wc -l`
	if [ $count -gt 0 ]; then
		return 1
	fi

	return 0
}

check_upnpd_started() {
	local if_ext=$1
	local if_inn=$2

	if [ -z "${if_ext}" -o -z "${if_inn}" ]; then
		return 0
	fi
	ret=`ps -w | grep -v grep | grep "${UPNPD}" | grep "${if_ext}" | grep "${if_inn}"`

	if [ "x${ret}" = "x" ]; then
		# means no miniupnpd is running
		return 0
	else
		return 1
	fi
}

prepare_config() {
	local if_ext=$1
	local if_inn=$2

	local listen_ip=""
	local dsm_name=""
	local dsm_version=""
	local dsm_model=""
	local dsm_ui=""
	local dsm_uuid=""
	local mac_addr=""
	local adport=""
	local adip=""

	generate_nat_chain "${if_ext}"
	ifext_ret=$?
	generate_fwd_chain "${if_ext}"
	ifinn_ret=$?
	if [ ${ifext_ret} -eq 0 -o ${ifinn_ret} -eq 0 ]; then
		return 1
	fi
	adport=`get_key_value /etc/synoinfo.conf admin_port`
	adip=`${IFCONFIG} ${if_inn} | grep 'inet addr' | sed -e 's/.*addr:\([.0-9]*\).*/\1/g'`

	listen_ip=`${IFCONFIG} ${if_inn} | grep 'inet addr' | sed -e 's/.*addr:\([.0-9]*\).*Mask:\([.0-9]*\)/\1\/\2/g'`
	mac_addr=`${IFCONFIG} ${if_inn} | grep 'HWaddr' | sed -e 's/.*HWaddr \([:0-9a-zA-Z]*\)/\1/g'`
	dsm_uuid=`${UUID_GEN}`
	dsm_name=`${UNAME} -n`
	dsm_model=`get_key_value /etc/synoinfo.conf upnpmodelname`
	local version_major=`get_key_value /etc.defaults/VERSION majorversion`
	local version_minor=`get_key_value /etc.defaults/VERSION minorversion`
	dsm_version="${version_major}.${version_minor}"
	dsm_ui="http://${adip}:${adport}"

	generate_config_name ${if_ext} ${if_inn}
cat > "${CONFIG_FILENAME}" <<-EOF
ext_ifname=${if_ext}
inn_ifname=${if_inn}
listening_ip=${listen_ip}
port=0
enable_upnp=yes
enable_natpmp=yes
secure_mode=yes
upnp_forward_chain=${CHAIN_FWD_NAME}
upnp_nat_chain=${CHAIN_NAT_NAME}
notify_interval=60
system_uptime=yes
friendly_name=${dsm_name}
model_number=${dsm_version}
model_name=${dsm_model}
serial=${mac_addr}
clean_ruleset_interval=600
clean_ruleset_threshold=20
presentation_url=${dsm_ui}
uuid=${dsm_uuid}
#allow is need to be decided 
allow 0-65535 ${listen_ip} 1-65535
deny 0-65535 0.0.0.0/0 0-65535

EOF
return 0
}

remove_config() {
	local if_ext=$1
	local if_inn=$2

	generate_config_name ${if_ext} ${if_inn}
	local ret=$?
	if [ -f "${CONFIG_FILENAME}" -a  ${ret} -eq 1 ]; then
		`rm -f "${CONFIG_FILENAME}"`
		return 0
	fi

	return 1
}

initial_iptables() {
	local if_ext=$1

	generate_nat_chain "${if_ext}"
	ifext_ret=$?
	generate_fwd_chain "${if_ext}"
	ifinn_ret=$?
	if [ ${ifext_ret} -eq 0 -o ${ifinn_ret} -eq 0 ]; then
		return 1
	fi
	check_iptables "${if_ext}"
	ret=$?
	if [ ${ret} -ne 1 ]; then
		# means the iptable is wrong
		release_iptables "${if_ext}"

		# add the nat chain
		`${IPTABLES} -t nat -N ${CHAIN_NAT_NAME} > /dev/null 2>&1`
		# add rules in nat
		`${IPTABLES} -t nat -A PRIMITIVE_PREROUTING -i ${if_ext} -j ${CHAIN_NAT_NAME} > /dev/null 2>&1`

		# add the filter chain
		`${IPTABLES} -t filter -N ${CHAIN_FWD_NAME} > /dev/null 2>&1`
		# add rules in filter
		`${IPTABLES} -t filter -A PRIMITIVE_FORWARD -i ${if_ext} ! -o ${if_ext} -j ${CHAIN_FWD_NAME} > /dev/null 2>&1`
		return 1
	fi
	return 0
}

release_iptables() {
	local if_ext=$1
	local flag=1
	local last_count=0

	generate_nat_chain "${if_ext}"
	ifext_ret=$?
	generate_fwd_chain "${if_ext}"
	ifinn_ret=$?
	if [ ${ifext_ret} -eq 0 -o ${ifinn_ret} -eq 0 ]; then
		return 1
	fi

	while :
	do
		local num=`${IP_SAVE} | grep ${if_ext} | wc -l`
		if [ ${num} -eq 0 -o ${num} -eq ${last_count} ]; then
			break;
		fi
		last_count=${num}
		# flush(remove rules) the nat chain
		`${IPTABLES} -t nat -F ${CHAIN_NAT_NAME} > /dev/null 2>&1`
		# delete rules in nat
		`${IPTABLES} -t nat -D PRIMITIVE_PREROUTING -i ${if_ext} -j ${CHAIN_NAT_NAME} > /dev/null 2>&1`
		# delete chain
		`${IPTABLES} -t nat -X ${CHAIN_NAT_NAME} > /dev/null 2>&1`

		# flush(remove rules) the filter chain
		`${IPTABLES} -t filter -F ${CHAIN_FWD_NAME} > /dev/null 2>&1`
		# delete rules in filter
		`${IPTABLES} -t filter -D PRIMITIVE_FORWARD -i ${if_ext} ! -o ${if_ext} -j ${CHAIN_FWD_NAME} > /dev/null 2>&1`
		# delete chain
		`${IPTABLES} -t filter -X ${CHAIN_FWD_NAME} > /dev/null 2>&1`
	done
	return 0
}

start_upnpd() {
	local if_ext=$1
	local if_inn=$2
	local config=""
	local restart_flag=0

	generate_config_name ${if_ext} ${if_inn}
	local ret=$?
	config=${CONFIG_FILENAME}

	if [ -z ${config} -o ${ret} -eq 0 ]; then
		return 1
	fi
	check_iface_alive ${if_ext}
	ret1=$?
	check_iface_alive ${if_inn}
	ret2=$?

	if [ ${ret1} -eq 0 -o ${ret2} -eq 0 ]; then
		# interface(s) does not exist.
		return 1
	fi

	initial_iptables ${if_ext}
	restart_flag=$?

	check_upnpd_started ${if_ext} ${if_inn}
	ret=$?
	if [ ${ret} -eq 1 ]; then
		if [ ${restart_flag} -ne 1 ]; then
			#no need to start miniupnpd
			return 1
		fi
		# has started, but need to restart
		stop_upnpd ${if_ext} ${if_inn}
	fi
	# now we start miniupnpd by and upstart:miniupnpd
	#`${UPNPD} -f ${config} -P ${UPNPD_PID}${if_ext}.pid > /dev/null 2>&1`

	return 0
}

stop_upnpd() {
	local if_ext=$1
	local if_inn=$2
	local config=""

	generate_config_name ${if_ext} ${if_inn}
	local ret=$?
	config=${CONFIG_FILENAME}

	if [ -z ${config} -o ${ret} -eq 0 ]; then
		return 1
	fi
	#pid=`ps -w | grep -v grep | grep "${UPNPD}" | grep "${CONFIG_FILENAME}" | awk '{print $1}'`
	#if [ -n "${pid}" ]; then
		#`kill -9 ${pid}`
	#fi
	#we use upstart now, so no need to kill daemon

	# release iptable
	release_iptables ${if_ext}
	return 0
}

sync_ppp() {
	local need_start=""
	local need_stop=""

	local ppp_list=`${IFCONFIG} | grep "^ppp" | awk '{print $1}'`
	local files=`ls ${UPNPD_CONFIG_DIR}/* | grep ppp`
	for configs in ${files}; do
		local flag=""
		for if_ext in ${ppp_list}; do
			local ret=`echo ${configs} | grep ${if_ext}`
			if [ -n ${ret} ]; then
				# means ${configs} and ${if_ext} exists, need to start it
				need_start="${need_start} ${configs}"
				flag="${configs}"
				break;
			fi
		done
		if [ -z ${flag} ]; then
			# means ${configs} exists, but no ${if_ext} mapping to, need to stop it
			need_stop="${need_stop} ${configs}"
		fi
	done
	for config in ${need_start}; do
		start_config ${config}
	done
	for config in ${need_stop}; do
		stop_config ${config}
	done
}

parse_config() {
	# will assign IF_EXT & IF_INN variable
	IF_EXT=""
	IF_INN=""
	local config=$1
	ret=`echo ${config} | sed -e "s/${UPNPD_CONFIG_NAME_FORMAT}/\1 \2/g"`
	if [ "x${ret}" = "x${config}" ]; then
		return 1;
	fi
		
	for iface in $ret; do
		if [ "x${IF_EXT}" = "x" ]; then
			IF_EXT=${iface}
		elif [ "x${IF_INN}" = "x" ]; then
			IF_INN=${iface}
		fi
	done
	return 0
}

start_config() {
	parse_config "$@"

	local ret=$?
	if [ ${ret} -ne 0 ]; then
		return ${ret}
	else
		prepare_config ${IF_EXT} ${IF_INN}
		ret=$?
		if [ ${ret} -ne 0 ]; then
			return ${ret}
		fi
		start_upnpd ${IF_EXT} ${IF_INN}
		ret=$?
		if [ ${ret} -ne 0 ]; then
			return ${ret}
		fi
	fi
	return 0
}

stop_config() {
	parse_config "$@"

	local ret=$?
	if [ ${ret} -eq 0 ]; then
		stop_upnpd ${IF_EXT} ${IF_INN}
	fi
	return 0
}

check_iptables() {
	local if_name=$1

	generate_nat_chain "${if_name}"
	ifext_ret=$?
	generate_fwd_chain "${if_name}"
	ifinn_ret=$?
	if [ ${ifext_ret} -eq 0 -o ${ifinn_ret} -eq 0 ]; then
		return 1
	fi
	local num_nat=`${IP_SAVE} | grep ${CHAIN_NAT_NAME} | wc -l`
	local num_fwd=`${IP_SAVE} | grep ${CHAIN_FWD_NAME} | wc -l`

	if [ ${num_nat} -lt 2 -o ${num_fwd} -lt 2 ]; then
		return 0
	else
		return 1
	fi
}

action=$1
shift;

case $action in
	[Pp][Rr][Ee][Pp][Aa][Rr][Ee])
		prepare_config "$@"
		;;
	[Rr][Ee][Mm][Oo][Vv][Ee])
		remove_config "$@"
		;;
	[Ii][Nn][Ii][Tt][Ii][Aa][Ll])
		initial_iptables "$@"
		;;
	[Rr][Ee][Ll][Ee][Aa][Ss][Ee])
		release_iptables "$@"
		;;
	[Cc][Hh][Ee][Cc][Kk])
		check_iptables "$@"
		;;
	[Ss][Tt][Aa][Rr][Tt])
		start_upnpd "$@"
		;;
	[Ss][Tt][Oo][Pp])
		stop_upnpd "$@"
		;;
	[Ss][Yy][Nn][Cc]-[Pp][Pp][Pp])
		sync_ppp "$@"
		;;
	[Ss][Tt][Aa][Rr][Tt]-[Cc][Oo][Nn][Ff][Ii][Gg])
		start_config "$@"
		;;
	[Ss][Tt][Oo][Pp]-[Cc][Oo][Nn][Ff][Ii][Gg])
		stop_config "$@"
		;;
	*)
		echo "Usage: [prepare|initial|release|start|stop]"
		echo "	prepare: Prepare the config file with [ext_if inn_if]"
		echo "	remove: Remove the config file with [ext_if inn_if]"
		echo "	initial: Initial the iptables for the interface [ext_if]"
		echo "	release: Release the iptables for the interface [ext_if]"
		echo "	start: Start the miniupnpd with [ext_if inn_if]"
		echo "	stop: Stop the miniupnpd with [ext_if inn_if]"
		echo "	sync-ppp: Sync ppp and miniupnpd"
		echo "	start-config: Stop the miniupnpd with [config]"
		echo "	stop-config: Stop the miniupnpd with [config]"
		;;
esac

ret=$?
exit ${ret}