#!/bin/sh

# Note: your PATH is inherited from the gateway process
#

# clear all packet filter rules
pfctl -F all > /dev/null

#########################
# Set NAT and RDR rules #
#########################


# Setup basic nat rule, any traffic out ExternalDevice with the IP from
# $LocalNetwork gets rewritten to the ip of the $ExternalDevice

NAT="nat on $ExternalDevice from $LocalNetwork to any -> $ExternalDevice\n"

# redir all web traffic to the gateway
NAT="${NAT}\n rdr on $InternalDevice proto tcp from any to any port 80 -> $ExternalDevice port $GatewayPort\n"
if [ $AuthServiceAddr != "" ]; then
	NAT="${NAT}\n rdr on $InternalDevice proto tcp from any to ! $AuthServiceAddr port 443 -> $ExternalDevice port $GatewayPort\n"
else
	NAT="${NAT}\n rdr on $InternalDevice proto tcp from any to any port 443 -> $ExternalDevice port $GatewayPort\n"
fi

# Setup rdr for ftp-proxy(8) incase we decide it's needed.
# (I turned this off by default -- I'm afraid it'll confuse people who aren't expecting it -- SDE)
# NAT="${NAT}\n rdr on $InternalDevice from any to any port 21 -> $ExternalDevice port 8081\n"

# this should eventually be pfctl -N "$NAT"
print "$NAT" | pfctl -N -



############################
# Setup PacketFilter Rules #
############################

PF=""
# setup our default deny
# PF="${PF}\n block out log  on $InternalDevice all\n";
PF="${PF}\n block in log on $InternalDevice all\n";

#
# Lock down more ports for public users, if specified.
#
# There are two philosophies in restricting access:  That Which Is Not
# Specifically Permitted Is Denied, and That Which Is Not Specifically
# Denied Is Permitted.
#
# If "IncludePorts" is defined, the default policy will be to deny all
# traffic, and only allow the ports mentioned.
#
# If "ExcludePorts" is defined, the default policy will be to allow all
# traffic, except to the ports mentioned.
#
# If both are defined, ExcludePorts will be ignored, and the default policy
# will be to deny all traffic, allowing everything in IncludePorts, and
# issue a warning.
#
if [[ "$IncludePorts" != "" ]]; then
	if [[ "$ExcludePorts" != "" ]]; then
		print "Warning: ExcludePorts and IncludePorts are both defined.\n"
		print "Ignoring 'ExcludePorts'.  Please check your nocat.conf.\n"
	fi

	#
	# Enable all ports in IncludePorts
	#
	for port in "$IncludePorts"
	do
		PF="${PF}\n pass in on $InternalDevice proto tcp from any to any port = $port keep state\n"
	done
	
	# Block all other ports
  	PF="${PF}\n block in on $InternalDevice proto tcp all\n"

elif [[ "$ExcludePorts" != "" ]]; then
	#
	# If ExcludePorts has entries, simply deny access to them.
	#
	for port in "$ExcludePorts"
	do
		PF="${PF}\n block in on $InternalDevice proto tcp from any to any port = $port\n"
  	done
fi

# Setup the DNS and other goodies AFTER the include/exclude ports
# just-in-case someone does something dumb like excluding the dns port.

if [[ "$DNSAddr" != "" ]]; then
	# Use external DNS server
	for a in $DNSAddr; do
		PF="${PF}\n pass in quick on $InternalDevice proto { tcp, udp } from any to $a port = 53 keep state\n";
		PF="${PF}\n pass out quick on $InternalDevice proto { tcp, udp } from any to $a port = 53 keep state\n";
	done
else 
    # Use local DNS server on gateway
	PF="${PF}\n pass in quick on $InternalDevice proto { tcp, udp } from any to $LocalNetwork port = 53 keep state\n";
	#PF="${PF}\n pass in on $InternalDevice proto tcp from any to $LocalNetwork port = 53 keep state\n";
	#PF="${PF}\n pass in on $InternalDevice proto udp from any to $LocalNetwork port = 53 keep state\n";
fi

# Allow port 80/443 to go, so they can be redirected in nat to the login page
#
PF="${PF}\n pass in quick on $InternalDevice proto tcp from any to $ExternalDevice/32 port { 80, 443 } keep state\n";

# Always permit access to the GatewayPort (or we can't logout)
#
PF="${PF}\n pass in quick on $InternalDevice proto tcp from any to any port = $GatewayPort keep state\n";
PF="${PF}\n pass out quick on $InternalDevice proto tcp from any to any port = $GatewayPort keep state\n";

PF="${PF}\n pass in quick on $InternalDevice proto tcp from any to $AuthServiceAddr port = https keep state\n";

# Allow external interface to talk to the outside.  This is for outbound requests
#PF="${PF}\n pass in on $ExternalDevice all\n";
#PF="${PF}\n pass out on $ExternalDevice all\n";
# keep ssh open while debuging
#PF="${PF}\n pass in quick on $InternalDevice proto tcp from any to any port = 22 keep state\n";
#PF="${PF}\n pass out quick on $InternalDevice proto tcp from any to any port = 22 keep state\n";

PF="${PF}\n pass out quick on $InternalDevice from any to any\n";
# allow them to ping us. Some PDA's 802.11b cards/tcpstack send icmp to test the link
PF="${PF}\n pass in quick on $InternalDevice proto icmp from any to $InternalDevice/32\n";
PF="${PF}\n pass in quick on $InternalDevice proto icmp from any to $ExternalDevice/32\n";

print "$PF" | pfctl -R -
