#!/bin/sh
eval `dbus export shadowsocks`
eval `dbus export ss`
alias echo_date='echo $(date +%Y年%m月%d日\ %X):'
lan_ipaddr=$(nvram get lan_ipaddr)

# Different routers got different iptables syntax
case $(uname -m) in
  armv7l)
    MATCH_SET='--match-set'
    ;;
  mips)
    MATCH_SET='--set'
    ;;
esac


flush_nat(){
	echo_date 尝试先清除已存在的iptables规则，防止重复添加
	# flush and destory ipset if any
	#iptables -t nat -F SHADOWSOCKS > /dev/null 2>&1
	#iptables -t nat -D PREROUTING -p tcp -j SHADOWSOCKS >/dev/null 2>&1
	#iptables -t nat -X SHADOWSOCKS > /dev/null 2>&1
	cd /tmp
	iptables -t nat -S | grep SHADOWSOCKS | sed 's/-A/iptables -t nat -D/g'|sed 1d > clean.sh && chmod 700 clean.sh && ./clean.sh && rm clean.sh
	iptables -t nat -X SHADOWSOCKS > /dev/null 2>&1
	iptables -t nat -D OUTPUT -p tcp -m set --match-set router dst -j REDIRECT --to-ports 3333 >/dev/null 2>&1
	# flush chromecast rule to void mutiple apply
	iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to $lan_ipaddr >/dev/null 2>&1
}

flush_ipset(){
	echo_date 先清空已存在的ipset名单，防止重复添加
	ipset -F router >/dev/null 2>&1
	ipset -F gfwlist >/dev/null 2>&1
	ipset -F white_domain >/dev/null 2>&1
	ipset -F black_cidr >/dev/null 2>&1
}

destory_ipset(){
	echo_date 摧毁ipset名单
	ipset -X router >/dev/null 2>&1
	ipset -X gfwlist >/dev/null 2>&1
	ipset -X white_domain >/dev/null 2>&1
	ipset -X black_cidr >/dev/null 2>&1
}

creat_ipset(){
	# Create new set
	echo_date 创建ipset名单：router，gfwlist，white_domain，black_cidr
	ipset -N router iphash
	ipset -N gfwlist iphash
	ipset -N white_domain iphash
	ipset -N black_cidr nethash
}

add_black_wan_ip(){
	if [ ! -z "$ss_ipset_black_ip" ];then
		ip_format=`dbus get ss_ipset_black_ip|base64_decode|grep -v "/"|sed '/\#/d'`
		cidr_format=`dbus get ss_ipset_black_ip|base64_decode|grep "/"|sed '/\#/d'`
		if [ ! -z "$ip_format" ];then
			echo_date 添加你定义的黑名单IP地址到ipset：gfwlist中.
			for ip in $ip_format
			do
				ipset -A gfwlist $ip >/dev/null 2>&1
			done
		fi
		
		if [ ! -z "$cidr_format" ];then
			echo_date 添加你定义的黑名单CIDR地址到ipset：black_cidr中.
			for cidr in $cidr_format
			do
				ipset -A black_cidr $cidr >/dev/null 2>&1
			done
		fi
	fi
}

apply_nat_rules(){
	echo_date 写入iptables规则到nat表中...
	ip1=$(nvram get wan0_ipaddr | cut -d"." -f1,2)
	# Create new chain
	iptables -t nat -N SHADOWSOCKS
	
	# Ignore LANs and any other addresses you'd like to bypass the proxy
	iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 100.64.0.0/10 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d $ip1.0.0/16 -j RETURN
	[ ! -z "$ss_basic_server_ip" ] && iptables -t nat -A SHADOWSOCKS -d $ss_basic_server_ip -j RETURN
	
	# lan control
	black=$(echo $ss_basic_black_lan | base64_decode | sed "s/,/ /g")
	white=$(echo $ss_basic_white_lan | base64_decode | sed "s/,/ /g")
	if [ "$ss_basic_lan_control" == "1" ];then
		if [ ! -z $ss_basic_black_lan ];then
			echo_date 添加局域网黑名单IP，这些IP地址将不会走ss.
			for balck_ip in $black
			do
				iptables -t nat -A SHADOWSOCKS -p tcp -s $balck_ip -j RETURN
			done
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET white_domain dst -j RETURN 
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET black_cidr dst -j REDIRECT --to-ports 3333
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET gfwlist dst -j REDIRECT --to-ports 3333
		else
			echo_date 你开启了局域网黑名单，但是未填写任何内容，跳过！
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET white_domain dst -j RETURN 
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET black_cidr dst -j REDIRECT --to-ports 3333
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET gfwlist dst -j REDIRECT --to-ports 3333
		fi
	elif [ "$ss_basic_lan_control" == "2" ];then
		if [ ! -z $ss_basic_white_lan ];then
			echo_date 添加局域网白名单IP，这些IP地址将会走ss.
			for white_ip in $white
			do	iptables -t nat -A SHADOWSOCKS -p tcp -s $white_ip -m set $MATCH_SET black_cidr dst -j REDIRECT --to-ports 3333
				iptables -t nat -A SHADOWSOCKS -p tcp -s $white_ip -m set $MATCH_SET gfwlist dst -j REDIRECT --to-ports 3333
			done
		else
			echo_date 你开启了局域网白名单，但是未填写任何内容，跳过！
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET white_domain dst -j RETURN 
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET black_cidr dst -j REDIRECT --to-ports 3333
			iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET gfwlist dst -j REDIRECT --to-ports 3333
		fi
	else
		echo_date 局域网控制功能未启用！
		iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET white_domain dst -j RETURN 
		iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET black_cidr dst -j REDIRECT --to-ports 3333
		iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET gfwlist dst -j REDIRECT --to-ports 3333
	fi
	
	iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS
	
	# Apply the rules for router self
	iptables -t nat -A OUTPUT -p tcp -m set $MATCH_SET router dst -j REDIRECT --to-ports 3333
}
	
chromecast(){
	if [ "$ss_basic_chromecast" == "1" ]; then
		echo_date 开启chromecast功能（DNS劫持功能）
		iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to $lan_ipaddr >/dev/null 2>&1
	else
		echo_date chromecast功能未开启，建议开启哦~
		iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to $lan_ipaddr >/dev/null 2>&1
	fi
}


case $1 in
start_all)
	flush_nat
	flush_ipset
	ipset -F router >/dev/null 2>&1
	destory_ipset
	creat_ipset
	add_black_wan_ip
	apply_nat_rules
	chromecast
	;;
add_black_wan_ip)
	flush_ipset
	add_black_wan_ip
	;;
start_part_for_addon)
	flush_nat
	chromecast
	apply_nat_rules
	;;
*)
	echo "Usage: $0 (start_all|restart_wb_list)"
	exit 1
	;;
esac
