#!/bin/sh
eval `dbus export shadowsocks`
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

load_tproxy(){
	MODULES="nf_tproxy_core xt_TPROXY xt_socket xt_comment"
	OS=$(uname -r)
	# load Kernel Modules
	echo_date 加载TPROXY模块，用于udp转发...
	checkmoduleisloaded(){
		if lsmod | grep $MODULE &> /dev/null; then return 0; else return 1; fi;
	}
	
	
	for MODULE in $MODULES; do
		if ! checkmoduleisloaded; then
			insmod /lib/modules/${OS}/kernel/net/netfilter/${MODULE}.ko
		fi
	done
	
	modules_loaded=0
	
	for MODULE in $MODULES; do
		if checkmoduleisloaded; then
			modules_loaded=$(( i++ )); 
		fi
	done
	
	if [ $modules_loaded -ne 3 ]; then
		echo "One or more modules are missing, only $(( modules_loaded+1 )) are loaded. Can't start.";
		exit 1;
	fi
}


flush_nat_mangle(){
	echo_date 尝试先清除已存在的iptables规则，防止重复添加
	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 tcp -j SHADOWSOCKS >/dev/null 2>&1
	iptables -t nat -F SHADOWSOCKS >/dev/null 2>&1
	iptables -t nat -X SHADOWSOCKS >/dev/null 2>&1
	iptables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to $lan_ipaddr >/dev/null 2>&1
	iptables -t mangle -D PREROUTING -p udp -j SHADOWSOCKS2 >/dev/null 2>&1
	iptables -t mangle -F SHADOWSOCKS2 >/dev/null 2>&1
	iptables -t mangle -X SHADOWSOCKS2 >/dev/null 2>&1
}

remove_redundant_rule(){
	ip_rule_exist=`ip rule show | grep "fwmark 0x1/0x1 lookup 300" | grep -c 300`
	if [ ! -z "ip_rule_exist" ];then
		echo_date 清除重复的ip rule规则.
		until [ "$ip_rule_exist" = 0 ]
		do 
			ip rule del fwmark 0x01/0x01 table 300
			ip_rule_exist=`expr $ip_rule_exist - 1`
		done
	fi
}

remove_route_table(){
	echo_date 删除ip route规则.
	ip route del local 0.0.0.0/0 dev lo table 300 >/dev/null 2>&1
}

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

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

creat_ipset(){
	echo_date 创建ipset名单：chnroute
	# load chnroute to ipset
	ipset -N router iphash
	chnroute="/koolshare/ss/redchn/chnroute.txt"
	sed -e "s/^/-A chnroute &/g" -e "1 i\-N chnroute nethash --hashsize 80000" $chnroute | awk '{print $0} END{print "COMMIT"}' | ipset -R
}

apply_nat_rules(){
	echo_date 写入iptables规则到nat表中...
	ip1=$(nvram get wan0_ipaddr | cut -d"." -f1,2)
	# create nat chain
	iptables -t nat -N SHADOWSOCKS
	
	# not redirect these
	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
	
	# create ip rules
	ip rule add fwmark 0x01/0x01 table 300
	ip route add local 0.0.0.0/0 dev lo table 300
	
	# creat mangle chain
	iptables -t mangle -N SHADOWSOCKS2
	
	# return these ip
	iptables -t mangle -A SHADOWSOCKS2 -d 0.0.0.0/8 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 10.0.0.0/8 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 100.64.0.0/10 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 127.0.0.0/8 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 169.254.0.0/16 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 172.16.0.0/12 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 192.168.0.0/16 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 224.0.0.0/4 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d 240.0.0.0/4 -j RETURN
	iptables -t mangle -A SHADOWSOCKS2 -d $ip1.0.0/16 -j RETURN
	[ ! -z "$ss_basic_server_ip" ] && iptables -t mangle -A SHADOWSOCKS2 -d $ss_basic_server_ip -j RETURN
	
	
	# Apply the rules
	iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS
	iptables -t mangle -A PREROUTING -p udp -j SHADOWSOCKS2
	
	# router itself
	iptables -t nat -A OUTPUT -p tcp -m set $MATCH_SET router dst -j REDIRECT --to-ports 3333
	
	# 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
				iptables -t mangle -A SHADOWSOCKS2 -p udp -s $balck_ip -j RETURN
			done
			iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute dst -j REDIRECT --to-ports 3333
			iptables -t mangle -A SHADOWSOCKS2 -p udp -m set ! $MATCH_SET chnroute dst -j TPROXY --on-port 3333 --tproxy-mark 0x01/0x01
		else
			echo_date 你开启了局域网黑名单，但是未填写任何内容，跳过！
			iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute dst -j REDIRECT --to-ports 3333
			iptables -t mangle -A SHADOWSOCKS2 -p udp -m set ! $MATCH_SET chnroute dst -j TPROXY --on-port 3333 --tproxy-mark 0x01/0x01
		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
				iptables -t mangle -A SHADOWSOCKS2 -p udp -s $white_ip -m set ! $MATCH_SET chnroute dst -j TPROXY --on-port 3333 --tproxy-mark 0x01/0x01
			done
		else
			echo_date 你开启了局域网白名单，但是未填写任何内容，跳过！
			iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute dst -j REDIRECT --to-ports 3333
			iptables -t mangle -A SHADOWSOCKS2 -p udp -m set ! $MATCH_SET chnroute dst -j TPROXY --on-port 3333 --tproxy-mark 0x01/0x01
		fi
	else 
		echo_date 局域网控制功能未启用！
		iptables -t nat -A SHADOWSOCKS -p tcp -m set ! $MATCH_SET chnroute dst -j REDIRECT --to-ports 3333
		iptables -t mangle -A SHADOWSOCKS2 -p udp -m set ! $MATCH_SET chnroute dst -j TPROXY --on-port 3333 --tproxy-mark 0x01/0x01
	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)
	load_tproxy
	flush_nat_mangle
	remove_redundant_rule
	remove_route_table
	flush_ipset
	ipset -F router >/dev/null 2>&1
	destory_ipset
	creat_ipset
	apply_nat_rules
	chromecast
	;;
start_part_for_addon)
	#ss_basic_action=4
	flush_nat_mangle
	remove_redundant_rule
	remove_route_table
	chromecast
	apply_nat_rules
	;;
*)
	echo "Usage: $0 (start_all|restart_wb_list)"
	exit 1
	;;
esac
