###!/bin/sh
#
#   Rename this file to ppp_on_boot and pppd will be fired up as
#   soon as the system comes up, connecting to `provider'.
#
#   If you also make this file executable, and replace the first line
#   with just "#!/bin/sh", the commands below will be executed instead.
#

update_secret() {
  if [ ! -e ${1} ];then
    printf "%s\t*\t%s\n" ${2} ${3} > ${1}
   elif ! grep -q -s -E "^${2}\s" ${1};then
    printf "%s\t*\t%s\n" ${2} ${3} >> ${1}
   else
    sed -e 's|'${2}'\s.*|'${2}'\t*\t'${3}'|' -i ${1}
 fi;
}

if [ -e /etc/default/static ];then
        source /etc/default/static
	STAT_LAN_IP="${IP}"
	PREFIX_LAN=${IPV6PREFIX}
	ADDR_LAN=${IPV6ADDR}
	LAN_IDX=${IPV6ULANET-0}
else
	STAT_LAN_IP="";
	PREFIX_WIFI=""
	ADDR_WIFI=""
	LAN_IDX="0";
fi

if [ -e /etc/default/wifi ];then
        source /etc/default/wifi
	STAT_WIFI_IP="${IP}"
	IPV6_WIFI=${IPV6}
	if [ "${IPV6_WIFI}" == "1" ];then
		PREFIX_WIFI=${IPV6PREFIX}
		ADDR_WIFI=${IPV6ADDR}
	else
		PREFIX_WIFI=""
		ADDR_WIFI=""
	fi
	if [ "${WIFI_MODE}" == "STA" ];then
		WIFI_IFACE="wlan0"
		WIFI_SUBPRE=${IPV6ULANET-1}
	else
		WIFI_IFACE="wlan1"
		WIFI_SUBPRE=${IPV6ULANET-2}
	fi
else
	PREFIX_WIFI=""
	ADDR_WIFI=""
	IPV6_WIFI=0
	STAT_WIFI_IP=""
	IPV64WIFI=0
fi

if [ -e /etc/default/vlans ];then
	source /etc/default/vlans
fi;

if [ -e /etc/default/ppp ];then
        source /etc/default/ppp
	IPV6_EN=${IPV6}
else
	IPV6_EN="0";
	ENABLE="0";
fi

if [ "${VLAN}" ] && [ -e /etc/default/vlan_${VLAN} ];then
	source /etc/default/vlan_${VLAN}
	WAN_IFACE="eth0.${VLAN}"
	STAT_WAN_IP="${IP}"
	DEF_ULANET=$(printf "%x" $((${VLAN} << 4)))
	WAN_IDX=${IPV6ULANET-${DEF_ULANET}}
elif [ "${VLAN}" ];then
	WAN_IFACE="eth0.${VLAN}"
	STAT_WAN_IP="";
	WAN_IDX=$(printf "%x" $((${VLAN} << 4)))
elif [ "${IPV64LAN}" != "1" ];then
	WAN_IFACE="eth0"
	STAT_WAN_IP="${STAT_WAN_LAN}"
	WAN_IDX=${LAN_IDX}
else
	WAN_IFACE=""
fi

conf_radvd_64_int() {
  if [ "${3}" ];then
    iface="${1}:${2}"
    presub=${3}
   else
    iface="${1}"
    presub=${2}
  fi;
  cat <<__EOF__
	prefix 0:0:0:${presub}::/64 {
		Base6to4Interface ${iface};
		AdvAutonomous on;
		DeprecatePrefix on;
		AdvValidLifetime 150;
		AdvPreferredLifetime 60;
	};

__EOF__
}

conf_radvd_int() {
  cat <<__EOF__
interface ${1} {
	AdvSendAdvert on;
#	IgnoreIfMissing on;
	MinRtrAdvInterval 30;
	MaxRtrAdvInterval 100;
	AdvReachableTime 30000;
	AdvRetransTimer 10000;
#	AdvDefaultLifetime 0;

__EOF__

  if [ "${IPV6ULA}" ];then
  cat <<__EOF__
	prefix ${IPV6ULA}:${2}::/64 {
		AdvOnLink on;
		AdvAutonomous on;
	};

__EOF__
  fi;

  if [ "${IPV64PPP}" == "1" ];then
    conf_radvd_64_int ppp0 ${2}
  fi;

  if [ "${IPV6_EN}" == "1" ];then
    if [ "${IPV64LAN}" == "1" ];then
      if [ "${STAT_LAN_IP}" ];then
        conf_radvd_64_int eth0 static ${2}
       else
        conf_radvd_64_int eth0 dhcp ${2}
      fi
    fi;

    if [ "${IPV64WAN}" == "1" ] && [ "${WAN_IFACE}" ];then
      if [ "${STAT_WAN_IP}" ];then
        conf_radvd_64_int ${WAN_IFACE} static ${2}
       else
        conf_radvd_64_int ${WAN_IFACE} dhcp ${2}
      fi
    fi;
  fi

  if [ "${IPV6_WIFI}" == "1" ];then
    if [ "${IPV64WIFI}" == "1" ];then
      if [ "${WIFI_MODE}" == "STA" ];then
        if [ "${STAT_WIFI_IP}" ];then
          conf_radvd_64_int ${WIFI_IFACE} static ${2}
         else
          conf_radvd_64_int ${WIFI_IFACE} dhcp ${2}
        fi
       else
        conf_radvd_64_int ${WIFI_IFACE} ${2}
      fi
    fi
  fi
}

conf_radvd_int_pre_list() {
  (for ipaddr in $@;do
    (eval $(ipcalc -p --minaddr ${ipaddr} 2>/dev/null);if [ "${PREFIX}" ] && [ ${PREFIX} -lt 65 ];then echo ${MINADDR}/${PREFIX};fi)
  done) |sort |uniq |awk '{printf "%s ",$1}'
}

conf_radvd_int_pre() {
  cat <<__EOF__
	prefix ${1} {
		AdvOnLink on;
		AdvAutonomous on;
	};

__EOF__
}

conf_prefixes() {
    PRE_LIST="$(conf_radvd_int_pre_list $@)"
    if [ "${PRE_LIST}" ];then
      PRE_LIST=${PRE_LIST:-1}
      for prefix in ${PRE_LIST};do
        conf_radvd_int_pre ${prefix}
      done
    fi;
}

conf_radvd_vlan() {
  if [ ! -e /etc/default/vlan_${1} ];then
    return 0;
  fi

  IPV6ADDR=""
  IPV6PREFIX=""
  IPV6="0"
  IPV6ULANET=$(printf "%x" $((${1} << 4)))

  source /etc/default/vlan_${1}

  if [ "${IPV6}" == "1" ] || [ "${VLAN}" == "${1}" ];then
    conf_radvd_int eth0.${1} ${IPV6ULANET}
    conf_prefixes ${IPV6PREFIX}
    printf "};\n\n";
  fi
}

build_radvd_conf() {
  if [ "${IPV6_EN}" == "1" ] && [ -d /sys/class/net/eth0 ];then
    conf_radvd_int eth0 ${LAN_IDX}
    conf_prefixes ${PREFIX_LAN}
    printf "};\n\n";
  fi;

  if [ "${IPV6_WIFI}" == "1" ] && [ -d /sys/class/net/${WIFI_IFACE} ];then
    conf_radvd_int ${WIFI_IFACE} ${WIFI_SUBPRE}
    conf_prefixes ${PREFIX_WIFI}
    printf "};\n\n";
  fi

  for vlanid in ${VLANS};do
    if [ "${vlanid}" == "${VLAN}" ];then
      continue;
    fi;
    (conf_radvd_vlan ${vlanid})
  done

  if [ "${VLAN}" ] && [ "${IPV6_EN}" == "1" ];then
    (conf_radvd_vlan ${VLAN})
  fi;
}

build_radvd_conf > /etc/radvd.conf

/etc/init.d/radvd reload || /etc/init.d/radvd start

if [ "${1}" == "radvd" ];then
	exit
fi;

if [ "${ENABLE}" != "1" ];then
	echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
	/usr/sbin/iptables -F PPP
	exit 0
fi

PPP_OPTS="noipdefault\nusepeerdns\npersist\nlcp-echo-failure 2\nlcp-echo-interval 60\nnoauth\nholdoff 30\nmaxfail 0\nplugin rp-pppoe.so\n";

# The location of the ppp daemon itself (shouldn't need to be changed)
PPPD=/usr/sbin/pppd

if [ "${USER}" ];then
  PPP_OPTS="${PPP_OPTS}user ${USER}\n"
fi;

if [ "${PASS}" ];then
  update_secret /etc/ppp/pap-secrets ${USER} ${PASS}
  update_secret /etc/ppp/chap-secrets ${USER} ${PASS}
  chown root.root /etc/ppp/pap-secrets /etc/ppp/chap-secrets
  chmod 400 /etc/ppp/pap-secrets /etc/ppp/chap-secrets
fi;

if [ "${MRU}" ];then
  PPP_OPTS="${PPP_OPTS}mru ${MRU}\n"
 else
  PPP_OPTS="${PPP_OPTS}mru 1492\n"
fi;

if [ "${SERVICE}" ];then
  PPP_OPTS="${PPP_OPTS}rp_pppoe_service ${SERVICE}\n"
fi;

if [ "${VLAN}" ];then
  if [ ! -d /sys/class/net/eth0.${VLAN} ];then
    /sbin/ip link add link eth0 name eth0.${VLAN} type vlan id ${VLAN}
    /sbin/ip link set eth0.${VLAN} up
  fi;
  PPP_OPTS="${PPP_OPTS}nic-eth0.${VLAN}\n"
  EIFACE="eth0.${VLAN}"
else
  PPP_OPTS="${PPP_OPTS}nic-eth0\n"
  EIFACE="eth0"
fi;

if [ "${IPV6PPP}" == "1" ];then
  PPP_OPTS="${PPP_OPTS}+ipv6\nipv6cp-use-persistent\n"
fi;

printf "${PPP_OPTS}"  > /etc/ppp/peers/ns_default

/usr/sbin/iptables -F PPP
if [ "${FWALL}" == "1" ];then
  if [ "${DHCP}" == "1" ];then
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${EIFACE} -p udp -d 255.255.255.255 --dport 67:68
   else
    /usr/sbin/iptables -A PPP -j DROP -i ${EIFACE} -p udp -d 255.255.255.255 --dport 67:68
  fi;
  if [ "${FWLOCAL}" == "1" ] && [ "${WWW}" == "0" ];then
    /sbin/ip route show dev ${EIFACE} scope link proto kernel |sort |uniq |\
	awk -v DEV=${EIFACE} \
		'{printf "/usr/sbin/iptables -A PPP -j ACCEPT -p tcp -i %s -d %s -s %s --dport 80\n", DEV, $3, $1, DEV, $3, $1}' |sh
   elif [ "${WWW}" == "1" ];then
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${EIFACE} -p tcp --dport 80
    /usr/sbin/iptables -A PPP -j ACCEPT -i ppp0 -p tcp --dport 80
  fi
  if [ "${FWLOCAL}" == "0" ];then
    /sbin/ip route show dev ${EIFACE} scope link proto kernel |sort |uniq |\
	awk -v DEV=${EIFACE} '{printf "/usr/sbin/iptables -A PPP -j ACCEPT -i %s -s %s -d %s\n\
		/usr/sbin/iptables -A PPP -j ACCEPT -p igmp -i %s -s %s -d 224.0.0.0/4\n", DEV, $1, $1, DEV, $1}' |sh
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${EIFACE} -p udp -d 255.255.255.255
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${EIFACE} -p udp -d 224.0.0.251
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${EIFACE} -d 224.0.0.1
   else
    /sbin/ip route show dev ${EIFACE} scope link proto kernel |sort |uniq |awk -v DEV=${EIFACE} '{printf "\
	/usr/sbin/iptables -A PPP -j ACCEPT -p tcp --sport 0:1023 --dport 2049:2052 -i %s -s %s -d %s\n\
	/usr/sbin/iptables -A PPP -j ACCEPT -p udp --sport 0:1023 --dport 2049:2052 -i %s -s %s -d %s\n\
	/usr/sbin/iptables -A PPP -j ACCEPT -p tcp --sport 0:1023 --dport 111 -i %s -s %s -d %s\n\
	/usr/sbin/iptables -A PPP -j ACCEPT -p udp --sport 0:1023 --dport 111 -i %s -s %s -d %s\n\
	/usr/sbin/iptables -A PPP -j DROP -i %s -s %s -d %s\n\
	/usr/sbin/iptables -A PPP -j DROP -p igmp -i %s -s %s -d 224.0.0.0/4\n", \
		DEV, $1, $1, DEV, $1, $1, DEV, $1, $1, DEV, $1, $1, DEV, $1, $1, DEV, $1}' |sh
    /usr/sbin/iptables -A PPP -j DROP -i ${EIFACE} -p udp -d 255.255.255.255
    /usr/sbin/iptables -A PPP -j DROP -i ${EIFACE} -p udp -d 224.0.0.251
    /usr/sbin/iptables -A PPP -j DROP -i ${EIFACE} -d 224.0.0.1
  fi;

  /usr/sbin/iptables -A PPP -j ACCEPT -i ${EIFACE} -p tcp --tcp-flags SYN,ACK,FIN,RST FIN,ACK
#  /usr/sbin/iptables -A PPP -j LOG -i ${EIFACE}
  /usr/sbin/iptables -A PPP -j DROP -i ${EIFACE}
  echo 1 > /proc/sys/net/ipv4/conf/${EIFACE}/rp_filter
elif [ "${WWW}" == "1" ];then
  echo 0 > /proc/sys/net/ipv4/conf/${EIFACE}/rp_filter
  /usr/sbin/iptables -A PPP -j ACCEPT -i ppp0 -p tcp --dport 80
else
  echo 0 > /proc/sys/net/ipv4/conf/${EIFACE}/rp_filter
fi;

# The default provider to connect to
if [ "${USER}" ] && [ "${PASS}" ];then
  $PPPD call ns_default
fi;

# Additional connections, which would just use settings from
# /etc/ppp/options.<tty>
#$PPPD ttyS0
#$PPPD ttyS1
#$PPPD ttyS2
#$PPPD ttyS3
