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

# 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 rules and set 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
	iptables -t nat -D OUTPUT -p tcp -m set $MATCH_SET router dst -j REDIRECT --to-ports 3333 >/dev/null 2>&1
	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 chnroute >/dev/null 2>&1
	ipset -F white_domain >/dev/null 2>&1
	ipset -F black_domain >/dev/null 2>&1
	ipset -F white_ip >/dev/null 2>&1
	ipset -F black_ip >/dev/null 2>&1
	ipset -F white_cidr >/dev/null 2>&1
}

destory_ipset(){
	echo_date 摧毁ipset名单
	ipset -X router >/dev/null 2>&1
	ipset -X chnroute >/dev/null 2>&1
	ipset -X white_domain >/dev/null 2>&1
	ipset -X black_domain >/dev/null 2>&1
	ipset -X white_ip >/dev/null 2>&1
	ipset -X black_ip >/dev/null 2>&1
	ipset -X white_cidr >/dev/null 2>&1
}

# creat ipset rules
creat_ipset(){
	echo_date 创建ipset名单：router，white_domain，black_domain，white_ip，black_ip
	use_chnroute="/koolshare/ss/redchn/chnroute.txt"
	sed -e "s/^/-A chnroute &/g" -e "1 i\-N chnroute nethash --hashsize 81920" $use_chnroute | awk '{print $0} END{print "COMMIT"}' | ipset -R
	ipset -N router iphash
	ipset -N white_domain iphash
	ipset -N black_domain iphash
	ipset -N white_ip iphash
	ipset -N white_cidr nethash
	ipset -N black_ip iphash
}

add_white_black_ip(){
	# black ip/cidr
	if [ ! -z "$ss_redchn_wan_black_ip" ];then
		ip_format=`dbus get ss_redchn_wan_black_ip|base64_decode|grep -v "/"`
		cidr_format=`dbus get ss_redchn_wan_black_ip|base64_decode|grep "/"`
		if [ ! -z "$ip_format" ];then
			echo_date 添加你定义的黑名单IP地址到ipset：black_ip中.
			for ip in $ip_format
			do
				ipset -A black_ip $ip >/dev/null 2>&1
			done
		fi
		
		if [ ! -z "$cidr_format" ];then
			echo_date 添加你定义的黑名单CIDR地址到ipset：chnroute中.
			for cidr in $cidr_format
			do
				ipset -A chnroute $cidr >/dev/null 2>&1
			done
		fi
	fi
	# white ip/cidr
	if [ ! -z "$ss_redchn_wan_white_ip" ];then
		ip_format=`dbus get ss_redchn_wan_white_ip|base64_decode|grep -v "/"`
		cidr_format=`dbus get ss_redchn_wan_white_ip|base64_decode|grep "/"`
		if [ ! -z "$ip_format" ];then
			echo_date 添加你定义的白名单IP地址到ipset：white_ip中.
			for ip in $ip_format
			do
				ipset -A white_ip $ip >/dev/null 2>&1
			done
		fi
		
		if [ ! -z "$cidr_format" ];then
			echo_date 添加你定义的白名单CIDR地址到ipset：white_cidr中.
			for cidr in $cidr_format
			do
				ipset -A white_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)
	# 创建SHADOWSOCKS nat rule
	iptables -t nat -N SHADOWSOCKS
	
	# 重定所有流量到 SHADOWSOCKS
	iptables -t nat -I PREROUTING 1 -p tcp -j SHADOWSOCKS
	
	# default wan_blacklist 强制局域网ip，DNS ip地址不走代理
	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
	
	# IP白名单控制（不走ss）
	iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set white_ip dst -j RETURN

	# cidr白名单控制（不走kcptun）
	iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set white_cidr dst -j RETURN
	
	# 域名白名单控制（不走ss）
	iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET white_domain dst -j RETURN

	# IP黑名单控制（走ss）
	iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET black_ip dst -j REDIRECT --to-ports 3333
	
	# 域名黑名单控制（走ss）
	iptables -t nat -A SHADOWSOCKS -p tcp -m set $MATCH_SET black_domain dst -j REDIRECT --to-ports 3333
	
	# router itself
	iptables -t nat -A OUTPUT -p tcp -m set $MATCH_SET router dst -j REDIRECT --to-ports 3333
	
	# lan black_white list
	black=$(echo $ss_basic_black_lan | base64_decode | sed "s/,/\n/g")
	white=$(echo $ss_basic_white_lan | base64_decode | sed "s/,/\n/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 chnroute dst -j REDIRECT --to-ports 3333
		else
			echo_date 你开启了局域网黑名单，但是未填写任何内容，跳过！
			iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute 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 chnroute dst -j REDIRECT --to-ports 3333
			done
		else
			echo_date 你开启了局域网白名单，但是未填写任何内容，跳过！
			iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute dst -j REDIRECT --to-ports 3333
		fi
	else
		echo_date 局域网控制功能未启用！
		iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute dst -j REDIRECT --to-ports 3333
	fi
}

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 chnroute >/dev/null 2>&1
	ipset -F router >/dev/null 2>&1
	destory_ipset
	creat_ipset
	add_white_black_ip
	apply_nat_rules
	chromecast
	;;
add_new_ip)
	flush_ipset
	add_white_black_ip
	;;
start_part_for_addon)
	#ss_basic_action=4
	flush_nat
	chromecast
	apply_nat_rules
	;;
*)
	echo "Usage: $0 (start_all|restart_wb_list)"
	exit 1
	;;
esac

