#!/bin/sh
#
### BEGIN INIT INFO
# Provides:       netconf
# Required-Start: $remote_fs $named $syslog
# Required-Stop:  $remote_fs $named $syslog
# Default-Start:  3 5
# Default-Stop:   0 1 2 6
# Description:    Comb NS Netconfig
### END INIT INFO

OPTIONS_DHCP="-B --inactive"
DAEMON_DHCP=/usr/sbin/dhcpcd

PIDFILE_RADVD=/var/run/radvd/radvd.pid
OPTIONS_RADVD="-m none -u radvd -p ${PIDFILE_RADVD}"
DAEMON_RADVD=/usr/sbin/radvd

FW_DEBUG=0

# Source function library.
. /etc/init.d/functions

HOSTNAME=$(/bin/hostname)

if [ -e /etc/default/wireguard0 ];then
        source /etc/default/wireguard0
else
	WG0_ROUTE="";
	WG0_ENABLE="0";
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}
	LAN_PDSUF=${IPV6PDSUF-0}
else
	STAT_LAN_IP="";
	PREFIX_WIFI=""
	ADDR_WIFI=""
	LAN_IDX="0";
	LAN_PDSUF="0"
fi

if [ -e /etc/default/wifi ];then
	unset IPV6ULANET IPV6PDSUF IPV6ADDR IPV6PREFIX IP IPV6
        source /etc/default/wifi
	STAT_WIFI_IP="${IP}"
	IPV6_DEF_WIFI=${IPV6_DEF-0}
	IPV6_PRIV_WIFI=${IPV6_PRIV-0}
	WIFI_PDSUF=${IPV6PDSUF-0}
	if [ "${WIFI_MODE}" == "STA" ];then
		WIFI_IFACE="wlan0"
		WIFI_SUBPRE=${IPV6ULANET-1}
		IPV6_WIFI=${IPV6-1}
	elif [ "${WIFI_MODE}" == "OFF" ] || [ "${WIFI_MODE}" == "DEF" ];then
		WIFI_IFACE="wlan0"
		WIFI_SUBPRE=${IPV6ULANET-1}
		IPV6_WIFI=0
	else
		IPV6_WIFI=${IPV6-1}
		WIFI_IFACE="wlan1"
		WIFI_SUBPRE=${IPV6ULANET-2}
	fi
	if [ "${IPV6_WIFI}" == "1" ];then
		PREFIX_WIFI=${IPV6PREFIX}
		ADDR_WIFI=${IPV6ADDR}
	else
		PREFIX_WIFI=""
		ADDR_WIFI=""
		IPV64WIFI=0
	fi
else
	PREFIX_WIFI=""
	ADDR_WIFI=""
	IPV6_WIFI=0
	IPV6_DEF_WIFI=0
	IPV6_PRIV_WIFI=0
	STAT_WIFI_IP=""
	IPV64WIFI=0
	WIFI_PDSUF="0"
fi

if [ -e /etc/default/vlans ];then
	source /etc/default/vlans
else
	VLANS=""
fi;

if [ -e /etc/default/ppp ];then
        source /etc/default/ppp
	IPV6_EN=${IPV6-1}
	IPV6_DEF=${IPV6_DEF-0}
	IPV6_PRIV=${IPV6_PRIV-0}
	if [ "${IPV6_EN}" == "0" ];then
  		IPV64LAN="0";
		IPV64WAN="0";
	fi
	EXT_DHCP=${DHCP}
	EXT_DHCP6=${DHCP6:-0}
	if [ "${VLAN}" == "1" ];then
		VLAN="";
	fi;
else
	IPV6_EN="1";
	IPV6_DEF="0";
	IPV6_PRIV="0";
	ENABLE="0";
	IPV64LAN="0";
	IPV64WAN="0";
	EXT_DHCP="0";
	EXT_DHCP6="0";
fi

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

pidstatus() {
  local pid

  if [ -e "${2}" ];then
    pid=$(cat ${2})
  fi;
  if [ -n "$pid" ] && kill -s 0 ${pid}; then
    echo "$1 (pid $pid) is running..."
    return 0
   elif [ -n "${pid}" ];then
    echo "$1 (pid $pid) is not running..."
    return 0
   else
    echo "$1 is stopped"
  fi
  return 3
}

get_eui64_prefix() {
  IFACE=${1}
  ORIG_IFS=${IFS}
  IFS=:
  m=($(cat /sys/class/net/${IFACE}/address))
  IFS=${ORIG_IFS}

  printf "%s:%s:%x:%x:%x:%x\n" ${2} ${3} $((((0x${m[0]} ^ 2) << 8) + 0x${m[1]}))  0x${m[2]}ff 0xfe${m[3]} 0x${m[4]}${m[5]}
}

get_eui64_link() {
  IFACE=${1}
  ORIG_IFS=${IFS}
  IFS=:
  m=($(cat /sys/class/net/${IFACE}/address))
  IFS=${ORIG_IFS}

  printf "fe80::%x:%x:%x:%x\n" $((((0x${m[0]} ^ 2) << 8) + 0x${m[1]}))  0x${m[2]}ff 0xfe${m[3]} 0x${m[4]}${m[5]}
}

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 3600;
		AdvPreferredLifetime 1440;
	};

__EOF__
}


fixup_pre_pd0() {
  ORIG_IFS=${IFS}
  IFS=:;
  pre_a=(${1})
  IFS=${ORIG_IFS}

  if [ ! "${pre_a[3]}" ];then
    pre_a[3]=0
  fi

  if [ ! "${pre_a[2]}" ];then
    pre_a[2]=0
  fi

  if [ ! "${pre_a[1]}" ];then
    pre_a[1]=0
  fi

  printf "%x:%x:%x:%x:" 0x${pre_a[0]} 0x${pre_a[1]} 0x${pre_a[2]} $((0x${pre_a[3]} + ${2}))
}

prefix_pd0() {
  if [ "${EXT_DHCP6}" != "1" ] || [ ! -e /var/db/dhcpcd/${1}.lease ] || ! pidstatus ${DAEMON_DHCP} /run/dhcpcd-${EIFACE}.pid > /dev/null 2>&1;then
    return 1;
  fi;

  eval $(${DAEMON_DHCP} -f /run/netconf/dhcpcd_${1}.conf -U ${1})
  if [ ! "${dhcp6_ia_pd1_prefix1}" ];then
    return 1
  fi
  ext_prefix=$(grep -E "^#external=" /run/netconf/dhcpcd_${1}.conf |cut -d= -f2)
  if [ "${ext_prefix}" ];then
     fixup_pre_pd0 ${dhcp6_ia_pd1_prefix1} ${ext_prefix}
   else
     fixup_pre_pd0 ${dhcp6_ia_pd1_prefix1} 0
  fi
}

conf_radvd_int() {
  ORIG_IFS=${IFS}
  IFS=:
  subnet6=(${2})
  IFS=${ORIG_IFS}

  if [ "${subnet6[0]}" == "" ];then
	subnet6[0]="0"
  fi

  if [ "${3}" == "1" ];then
	DEFADV=600
  else
	DEFADV=0
  fi;

  if [ "${1}" == "${EIFACE}" ];then
    PREF="high";
   elif [ "${1}" == "${WIFI_IFACE}" ];then
    PREF="low";
   else
    PREF="medium";
  fi  

  cat <<__EOF__
interface ${1} {
	AdvSendAdvert on;
	AdvOtherConfigFlag on;
#	IgnoreIfMissing on;
#	MinRtrAdvInterval 30;
#	MaxRtrAdvInterval 100;
	AdvReachableTime 30000;
	AdvRetransTimer 10000;
	AdvDefaultLifetime ${DEFADV};
	AdvDefaultPreference ${PREF};

__EOF__

  printf "\tRDNSS %s {\n\t};\n\n" $(get_eui64_link ${1})

  if [ "${4}" == "1" ];then
	for rt6 in 2002:ac10::/28 2002:a00::/24 2002:c0a8::/32 fc00::/7;do
		printf "\troute %s {\n\t\tAdvRouteLifetime 600;\n\t\tAdvRoutePreference ${PREF};\n\t};\n\n" ${rt6}
	done;
  fi;

  if [ "${WG0_ENABLE-0}" == "1" ];then
	for rt6 in ${WG0_ROUTE};do
		if ipcalc -c -s -6 ${rt6};then
			printf "\troute %s {\n\t\tAdvRouteLifetime 600;\n\t\tAdvRoutePreference ${PREF};\n\t};\n\n" ${rt6}
		fi;
	done;
  fi;

  if [ "${IPV6ULA}" ];then
    printf "\tprefix %s:%s::/64 {\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tAdvPreferredLifetime 604800;\n\t\tAdvValidLifetime 2592000;\n\t};\n\n" ${IPV6ULA} ${subnet6[0]}
  fi;

  #printf "\tprefix %s {\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tDeprecatePrefix on;\n\t\tDecrementLifetimes on;\n\t\tAdvPreferredLifetime 604800;\n\t\tAdvValidLifetime 2592000;\n\t};\n\n" "::/64"

  if [ "${1}" == "${EIFACE}" ]  && [ "${EXT_DHCP6}" == "1" ];then
    PREFIX_PD0=$(prefix_pd0 ${1})
    if [ "$?" == "0" ];then
      printf "\tprefix %s:/64 {\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tDeprecatePrefix on;\n\t\tDecrementLifetimes on;\n\t\tAdvPreferredLifetime 604800;\n\t\tAdvValidLifetime 2592000;\n\t};\n\n" ${PREFIX_PD0}
      if [ "${EXT_PDSUF}" != "0" ] && [[ "${EXT_PDSUF}" =~ .*:.*:.*:.* ]]; then
        /sbin/ip -6 addr add ${PREFIX_PD0}${EXT_PDSUF}/64 dev ${1} >/dev/null 2>&1 |:
       else
        /sbin/ip -6 addr add ${PREFIX_PD0}:${EXT_PDSUF}/64 dev ${1} >/dev/null 2>&1 |:
      fi
    fi
  else
    ip -6 route show proto dhcp dev ${1} |awk '{printf "%s\n",$1}' |sort |uniq |\
      awk '{printf "\tprefix %s {\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tDeprecatePrefix on;\n\t\tDecrementLifetimes on;\n\t\tAdvPreferredLifetime 1440;\n\t\tAdvValidLifetime 3600;\n\t};\n\n",$1}'
  fi

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

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

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

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

fixup_prefix(){
  PREFIX=""
  eval $(ipcalc -p --minaddr ${ipaddr} 2>/dev/null);
  if [ "${PREFIX}" ] && [ ${PREFIX} -lt 65 ];then
    echo ${MINADDR}/${PREFIX}
  fi
}

conf_prefixes() {
  (for ipaddr in $@;do
    fixup_prefix ${ipaddr}
  done) |sort |uniq |awk '{printf "\tprefix %s {\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tAdvPreferredLifetime 604800;\n\t\tAdvValidLifetime 2592000;\n\t};\n\n",$1}'
}

conf_radvd_vlan() {
  if [ ! -e /etc/default/vlan_${1} ] || [ ! -d /sys/class/net/eth0.${1} ];then
    return 0;
  fi

  unset IPV6ULANET IPV6PDSUF IPV6ADDR IPV6PREFIX IP IPV6 IPV6_DEF IPV6_PRIV
  IPV6ULANET=$(printf "%x" $((${1} << 4)))

  IPV6="1"
  if [ -e /etc/default/vlan_${1} ];then
    source /etc/default/vlan_${1}
  fi;

  if [ "${IPV6}" != "1" ] && [ "${VLAN}" != "${1}" ];then
    echo 2 >/proc/sys/net/ipv6/conf/eth0.${1}/accept_ra
    return
  fi;

#  if [ "${VLAN}" == "${1}" ]  && [ "${EXT_DHCP6}" == "1" ];then
#    return
#  fi

  conf_radvd_int eth0.${1} ${IPV6ULANET} ${IPV6_DEF-1} ${IPV6_PRIV-0}
  conf_prefixes ${IPV6PREFIX}
  printf "};\n\n";
}

build_radvd_conf() {
  if [ "${IPV6_EN}" == "1" ] && [ -d /sys/class/net/eth0 ];then
    conf_radvd_int eth0 ${LAN_IDX} ${IPV6_DEF} ${IPV6_PRIV}
    conf_prefixes ${PREFIX_LAN}
    printf "};\n\n";
  else
    echo 2 >/proc/sys/net/ipv6/conf/eth0/accept_ra
  fi;

  if [ "${IPV6_WIFI}" == "1" ] && [ -d /sys/class/net/${WIFI_IFACE} ];then
    conf_radvd_int ${WIFI_IFACE} ${WIFI_SUBPRE} ${IPV6_DEF_WIFI} ${IPV6_PRIV_WIFI}
    conf_prefixes ${PREFIX_WIFI}
    printf "};\n\n";
  elif [ -e /proc/sys/net/ipv6/conf/${WIFI_IFACE}/accept_ra ];then
    echo 2 >/proc/sys/net/ipv6/conf/${WIFI_IFACE}/accept_ra
  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})
  elif [ "${VLAN}" ];then
    echo 2 >/proc/sys/net/ipv6/conf/eth0.${VLAN}/accept_ra
  fi;
}

conf_dhcpcd_vlan() {
  if [ ! -e /etc/default/vlan_${1} ] || [ ! -d /sys/class/net/eth0.${1} ];then
    return 0;
  fi

  unset IPV6ULANET IPV6PDSUF IPV6ADDR IPV6PREFIX IP IPV6
  source /etc/default/vlan_${1}

  if [ "${IPV6}" == "1" ] || [ "${VLAN}" == "${1}" ];then
    echo ${IPV6PDSUF-0}
    return 0
  fi
  return 1
}

build_dhcpcd_conf() {
  PRE=0

  if [ "${1}" ];then
    IAID=${1}
    IFACE=${1}
  elif [ "${EIFACE}" != "eth0" ];then
    IFACE=${WAN_IFACE}
    IAID=$(printf "ff:00:00:%02X" ${VLAN})
   else
    IFACE=${EIFACE}
    IAID=${EIFACE}
  fi;

  if [ "${IPV6_EN}" == "1" ] && [ -d /sys/class/net/eth0 ] && [[ "${EIFACE}" != "${IFACE}" ||  "${VLAN}" != "" ]];then
    PDLIST=" eth0/${PRE}/64/0";
    PRE=$((${PRE} + 1));
  elif [ "${IPV6_EN}" == "1" ] && [ -d /sys/class/net/eth0 ];then
    PRE=$((${PRE} + 1));
  fi;

  for vlanid in ${VLANS};do
    if [ "${vlanid}" == "${VLAN}" ];then
      PDEXT="#external=${PRE}"
      PRE=$((${PRE} + 1));
      continue;
    fi;
    SUFFIX=$(conf_dhcpcd_vlan ${vlanid})
    if [ "$?" == "0" ];then
      PDLIST="${PDLIST} eth0.${vlanid}/${PRE}/64/0";
      PRE=$((${PRE} + 1));
    fi
  done

  if [ "${IPV6_WIFI}" == "1" ] && [ -d /sys/class/net/${WIFI_IFACE} ];then
    PDLIST="${PDLIST} ${WIFI_IFACE}/${PRE}/64/0";
    PRE=$((${PRE} + 1));
  fi

  cat <<__EOF__
duid
noipv6rs
ipv6only
slaac private
logfile /dev/null
ipv6ra_noautoconf
#persistent
#nogateway

nohook resolv.conf, hostname, ntp.conf

background
waitip 6
timeout 15
#debug

allowinterfaces ${IFACE}

interface ${IFACE}
	iaid ${IAID}
	ipv6ra_autoconf
	ipv6rs
	ia_na
	ia_pd ${IAID}${PDLIST}
__EOF__

}

run_dhcpcd() {
  if [ -e /var/run/dhcpcd-${1}.pid ];then
    ${DAEMON_DHCP} -x ${1}
    if [ -e /var/run/dhcpcd-${1}.pid ];then
      /bin/kill $(cat /var/run/dhcpcd-${1}.pid)
      sleep 2
      if [ -e /var/run/dhcpcd-${1}.pid ];then
        /bin/kill -9 $(cat /var/run/dhcpcd-${1}.pid)
        sleep 2
      fi;
    fi
    (for boom in 1 2 3 4;do sleep 1;killall dhcpcd;done) >/dev/null 2>&1
  fi;

  if [ "${2}" == "1" ];then
    start-stop-daemon --start -p /run/dhcpcd-${1}.pid ${DAEMON_DHCP} --background -- ${OPTIONS_DHCP} -f /run/netconf/dhcpcd_${1}.conf ${1}
  fi;
}

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}
   elif ! grep -q -s -E "^${2}\s\*\s${3}$" ${1};then
    sed -e 's|'${2}'\s.*|'${2}'\t*\t'${3}'|' -i ${1}
 fi;
}

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

  if [ "${USER}" ];then
    PPP_OPTS="${PPP_OPTS}user ${USER}\n"
  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;

  PPP_OPTS="${PPP_OPTS}nic-${EIFACE}\n"

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

  printf "${PPP_OPTS}"  > /run/netconf/ns_default

  if [ ! -L /etc/ppp/peers/ns_default ];then
     if [ -e /etc/ppp/peers/ns_default ];then
       rm /etc/ppp/peers/ns_default
     fi;
     ln -rs /run/netconf/ns_default /etc/ppp/peers/ns_default
  fi;
}

ppp_conf() {
  ppp_call_conf

  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
}

start_radvd() {
  build_radvd_conf > /run/netconf/radvd.conf

  if [ ! -L /etc/radvd.conf ];then
    if [ -e /etc/radvd.conf ];then
      rm /etc/radvd.conf
    fi;
    ln -rs /run/netconf/radvd.conf /etc/radvd.conf
  fi;

  if pidstatus ${DAEMON_RADVD} /var/run/radvd/radvd.pid;then
    echo 0 > /proc/sys/net/ipv6/conf/all/forwarding
    start-stop-daemon --stop --signal HUP --quiet --pidfile ${PIDFILE_RADVD} --exec ${DAEMON_RADVD}
    echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
  elif [ -s /run/netconf/radvd.conf ];then
    echo 0 > /proc/sys/net/ipv6/conf/all/forwarding
    start-stop-daemon --start -p ${PIDFILE_RADVD} --oknodo --exec ${DAEMON_RADVD} -- ${OPTIONS_RADVD}
    echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
  fi;
}

start_dhcpcd() {
  build_dhcpcd_conf > /run/netconf/dhcpcd_${EIFACE}.conf
#  /sbin/ip -6 route add default dev ${EIFACE} metric 2048 pref low >/dev/null 2>&1 |:
  if [ "${IPV6_EN}" == "1" ] && [ "${EXT_DHCP6}" == "1" ];then
    run_dhcpcd ${EIFACE} 1
    return 0
   else
    run_dhcpcd ${EIFACE} 0
    return 1
  fi
}

start_ipv6_firewall() {
  if [ "${FWLOCAL}" == "1" ] && [ "${WWW}" == "0" ];then
    if [ "${IPV6ULA}" ];then
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p tcp --dport 80
    fi;
   elif [ "${WWW}" == "1" ];then
    /usr/sbin/ip6tables -A PPP -j ACCEPT -p tcp --dport 80
  fi;

  if [ "${FWLOCAL}" == "0" ];then
    if [ "${IPV6ULA}" ];then
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48
    fi;
    for lip64 in 2002:ac10::/28 2002:a00::/24 2002:c0a8::/32 fc00::/7;do
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${lip64}
    done
   else
    if [ "${IPV6ULA}" ];then
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p icmpv6
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p tcp --sport 0:1023 --dport 2049:2052
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p udp --sport 0:1023 --dport 2049:2052
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p tcp --sport 0:1023 --dport 111
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p udp --sport 0:1023 --dport 111
    fi;
    for lip64 in 2002:ac10::/28 2002:a00::/24 2002:c0a8::/32 fc00::/7;do
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${lip64} -p icmpv6
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${lip64} -p tcp --sport 0:1023 --dport 2049:2052
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${lip64} -p udp --sport 0:1023 --dport 2049:2052
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${lip64} -p tcp --sport 0:1023 --dport 111
      /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${lip64} -p udp --sport 0:1023 --dport 111
    done
  fi;
  if [ "${FW_DEBUG}" == "1" ];then
    /usr/sbin/ip6tables -A PPP -j LOG
    /usr/sbin/ip6tables -A PPP -j ACCEPT
  fi
}

start_ipv4_firewall() {
  if [ "${EXT_DHCP}" == "0" ];then
    /usr/sbin/iptables -A PPP -j DROP -i ${1} -p udp -d 255.255.255.255 --dport 67:68
   else
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${1} -p udp -d 255.255.255.255 --dport 67:68
  fi;

  if [ "${FWLOCAL}" == "1" ] && [ "${WWW}" == "0" ];then
    /sbin/ip route show dev ${1} scope link proto kernel |sort |uniq |\
	awk -v DEV=${1} \
		'{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 ${1} -p tcp --dport 80
    /usr/sbin/iptables -A PPP -j ACCEPT -i ppp0 -p tcp --dport 80
    /usr/sbin/iptables -A PPP -j ACCEPT -i wg0 -p tcp --dport 80
  fi

  if [ "${FWLOCAL}" == "0" ];then
    /sbin/ip route show dev ${1} scope link proto kernel |sort |uniq |\
	awk -v DEV=${1} '{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 ${1} -p udp -d 255.255.255.255
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${1} -p udp -d 224.0.0.251
    /usr/sbin/iptables -A PPP -j ACCEPT -i ${1} -d 224.0.0.1
   else
    /sbin/ip route show dev ${1} scope link proto kernel |sort |uniq |awk -v DEV=${1} '{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 ${1} -p udp -d 255.255.255.255
    /usr/sbin/iptables -A PPP -j DROP -i ${1} -p udp -d 224.0.0.251
    /usr/sbin/iptables -A PPP -j DROP -i ${1} -d 224.0.0.1
  fi;

  /usr/sbin/iptables -A PPP -j ACCEPT -i ${1} -p tcp --tcp-flags SYN,ACK,FIN,RST FIN,ACK
#  /usr/sbin/iptables -A PPP -j LOG -i ${1}
  /usr/sbin/iptables -A PPP -j DROP -i ${1}
}

setup_firewall() {
  /usr/sbin/iptables -F SIP
  /usr/sbin/iptables -F PPP
  /usr/sbin/ip6tables -F PPP

  /usr/sbin/ip6tables -F IPv6LOCAL
  if [ "${IPV6ULA}" ];then
    /usr/sbin/ip6tables -A IPv6LOCAL -j ACCEPT -s ${IPV6ULA}::/48
  fi;
  for lip64 in 2002:ac10::/28 2002:a00::/24 2002:c0a8::/32 fc00::/7;do
    /usr/sbin/ip6tables -A IPv6LOCAL -j ACCEPT -s ${lip64}
  done

  if [ "${ENABLE}" == "1" ] || [ "${FWALL}" == "1" ];then
    start_ipv4_firewall ${EIFACE}
    start_ipv6_firewall
    if [ "${WWW}" == "1" ];then
      /usr/sbin/iptables -A PPP -j ACCEPT -i ppp0 -p tcp --dport 80
      /usr/sbin/iptables -A PPP -j ACCEPT -i wg0 -p tcp --dport 80
    fi
    echo 1 > /proc/sys/net/ipv4/conf/${EIFACE}/rp_filter
   else
    if [ "${WWW}" == "0" ] && [ "${WIFI_MODE}" != "DEF" ];then
      if [ "${IPV6ULA}" ];then
        /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d ${IPV6ULA}::/48 -p tcp --dport 80
       else
        /usr/sbin/ip6tables -A PPP -j IPv6LOCAL -d fc00::/7 -p tcp --dport 80
      fi
      /usr/sbin/ip6tables -A PPP -j REJECT --reject-with icmp6-adm-prohibited -p tcp --dport 80
    fi;
    /usr/sbin/ip6tables -A PPP -j ACCEPT
    echo 0 > /proc/sys/net/ipv4/conf/${EIFACE}/rp_filter
  fi;
  if [ "${SIP-0}" == "0" ];then
    /usr/sbin/iptables -A SIP -j DROP
  fi;
}

if [ ! -d /run/netconf ];then
  mkdir -p /run/netconf
fi;

case "$1" in
	start)
		setup_firewall

		if [ "${HOSTNAME}" ];then
			/usr/bin/avahi-set-host-name ${HOSTNAME} >/dev/null 2>&1 || :
		fi;

		if [ "${ENABLE}" == "1" ] && [ "${USER}" ] && [ "${PASS}" ];then
			start_dhcpcd || start_radvd
			ppp_conf
		else
			start_dhcpcd || :
			start_radvd || :
		fi;
	;;
	stop)
		if pidstatus ${DAEMON_DHCP} /run/dhcpcd-${EIFACE}.pid;then
			${DAEMON_DHCP} -f /run/netconf/dhcpcd_${EIFACE}.conf -x ${EIFACE}
			if [ -e /run/dhcpcd-${1}.pid ];then
				start-stop-daemon --oknodo --stop --pidfile /run/dhcpcd-${EIFACE}.pid  --exec ${DAEMON_DHCP}
			fi;
		fi;
		start-stop-daemon --oknodo --stop --pidfile ${PIDFILE_RADVD}  --exec ${DAEMON_RADVD}
	;;
	status)
		pidstatus ${DAEMON_DHCP} /run/dhcpcd-${EIFACE}.pid && pidstatus ${DAEMON_RADVD} ${PIDFILE_RADVD}
		exit $?
        ;;
	reload)
		if pidstatus ${DAEMON_DHCP} /run/dhcpcd-${EIFACE}.pid;then
			start-stop-daemon --oknodo --stop --pidfile ${PIDFILE_RADVD}  --exec ${DAEMON_RADVD} | :
			build_dhcpcd_conf > /run/netconf/dhcpcd_${EIFACE}.conf
			${DAEMON_DHCP} -f /run/netconf/dhcpcd_${EIFACE}.conf -n ${EIFACE}
		else
			start_dhcpcd || start_radvd
		fi
	;;
	radvd)
		start_radvd
	;;
	firewall)
		setup_firewall
	;;
	dhcpcd)
		shift
		build_dhcpcd_conf ${1}
	;;
	ppp)
		ppp_conf
	;;
	*)
		N=/etc/init.d/$NAME
		echo "Usage: $N {start|stop|status|reload|radvd}" >&2
		exit 1
	;;
esac
