#! /bin/sh

# Developer mode Wifi replacement:
read roku_dev_mode rest < /proc/cmdline
if [ "$roku_dev_mode" = 'dev=1' ] && [ -f /nvram/captive ]
then
    echo
    echo "=== CAPTIVE from /nvram/captive"
    source /nvram/captive
    exit
fi

# Usage captive <start|stop> <LAN interface name> <P2P interface name>
ACTION=$1
LAN_INTF=$2
CAPTIVE_INTF=$3

. /lib/wlan/networking-functions

# Some platforms build iptables as dynamically loaded library
if [ -f /lib/xtables ]; then
    export XTABLES_LIBDIR=/lib/xtables/
fi

if [ "$ACTION" == "start" ]; then

    # Generate udhcpd config file, except for DNS entries
    cat <<-EOF >/tmp/udhcpd-captive.conf
	pidfile /var/run/udhcpd-p2p.pid
	start 172.29.243.226
	end 172.29.243.254
	interface $CAPTIVE_INTF
	remaining yes
	lease_file /tmp/udhcpd-p2p.leases
	option subnet 255.255.255.224
	option router 172.29.243.225
	option lease 600
	auto_time 0
	EOF

    # Add DNS entries from our own resolv.conf to pass to DHCP client
    while IFS= read -r line; do
        if [ ${line:0:1} != ';' ]; then
            echo $line | sed 's/nameserver/option dns/' >> /tmp/udhcpd-captive.conf
        fi
    done < /etc/resolv.conf

    # Some platforms don't put modules in the 'right' place so can't be autoloaded by iptables
    if [ -f /lib/modules/nf_nat.ko ]; then
	insmod /lib/modules/nf_nat.ko
	insmod /lib/modules/ipt_MASQUERADE.ko
	if [ -f /lib/modules/nf_nat_ipv4.ko ]; then
	insmod /lib/modules/nf_nat_ipv4.ko
	fi
	insmod /lib/modules/iptable_nat.ko
    fi
    
    echo "=== Captive Start ==="
    # Save any existing rules (e.g. P2P firewall)
    if [ -f /bin/iptables-save ]; then
	iptables-save > /tmp/iptables.backup
    fi
    
    /bin/iptables -t nat -A POSTROUTING -o $LAN_INTF -j MASQUERADE
    
    ifconfig $CAPTIVE_INTF 172.29.243.225 netmask 255.255.255.224 up
    /bin/iptables -A FORWARD -i $LAN_INTF -o $CAPTIVE_INTF -m state --state RELATED,ESTABLISHED -j ACCEPT
    /bin/iptables -A FORWARD -i $CAPTIVE_INTF -o $LAN_INTF -j ACCEPT
    sysctl -w net.ipv4.ip_forward=1
    killall -9 udhcpd
    /usr/sbin/udhcpd /tmp/udhcpd-captive.conf
    touch /tmp/captive_in_prog
fi

if [ "$ACTION" == "stop" ]; then
    echo "=== Captive Stop ==="
    rm -f /tmp/captive_in_prog
    ifconfig $CAPTIVE_INTF 0.0.0.0
    sysctl -w net.ipv4.ip_forward=0
    killall -9 udhcpd
    if [ -s /tmp/iptables.backup ]; then
	iptables-restore < /tmp/iptables.backup
    else
	# We couldn't save any rules, so clear all of them to make sure that the FORWARD rules above are flushed
	iptables -F
    fi
    iptables -t nat -F

    # Some platforms don't put modules in the 'right' place so modprobe -r doesn't work
    if [ -f /lib/modules/nf_nat.ko ]; then
        rmmod iptable_nat
        rmmod ipt_MASQUERADE
        rmmod nf_nat
		if [ -f /lib/modules/nf_nat_ipv4.ko ]; then
			rmmod nf_nat_ipv4
		fi
    else
        modprobe -r iptable_nat ipt_MASQUERADE nf_nat
    fi

    init_udhcpd $CAPTIVE_INTF
fi
