#!/bin/bash
# adhoc_wifi_gateway
# (c) Paul Mansfield 2009,2010,2011
# release under GNU Public License Latest Revision
# 
# History
#   20090719
#	PM
#	first release into the wild
#   20110305
#	PM
#	lots of updates to make it more robust and handle
#	both suse and debian linuxes, as well as either
#	atheros or intel wifi cards

##### CONSTANTS ####

# these are all you should need to change
WIFI=ath0
WIFI=wlan0
WIFI_ESSID=adhoc_testing
WIFI_WEP=11111111111111111111111111
WIFI_CHANNEL=11

#WAN=ppp0
WAN=eth0

# need to be root
MYID=`id -u`
if [ $MYID -ne 0 ] ; then
	echo "This script needs root privileges"
	exit
fi

#############################################################################
# location of files and directories - somewhat platform specific
# if DHCP daemon is running chroot, all files could be under here
SUSE=0
lsb-release -a | grep -i suse > /dev/null
if [ $? -eq 0 ] ; then
	echo "Setting program paths for suse"
	SUSE=1
	DHCP_DAEMON='/usr/sbin/dhcpd'
else
	# some ubuntu platforms will have dhcpd3, others udhcpd
	DHCP_DAEMON='/usr/sbin/dhcpd3'
	DHCP_DAEMON='/usr/sbin/udhcpd'
fi


DHCP_ROOT=/var/lib/dhcp
DHCP_CHROOT=/var/lib/dhcp
#DHCP_CONFIG=/etc/dhcpd.adhoc-wifi-ap.conf
DHCP_CONFIG=etc/dhcpd.adhoc-wifi-ap.conf
DHCP_USER=dhcpd
DHCP_GROUP=nogroup
DHCP_LEASES=/db/dhcpd.wlan0.leases
DHCP_PID=/db/dhcpd.wlan0.pid


#############################################################################
# shutdown function
if [ "$1" = "STOP" -o "$1" = "stop" ] ; then
	echo "Shutting down the wifi interface completely"
	if [ "$WIFI" = "ath0" ] ; then
		echo "Wifi card is atheros, removing ath0 and replacing with station interface"
		wlanconfig ath0 destroy
		wlanconfig ath0 create wlandev wifi0 wlanmode sta
	else
		echo "Putting card into managed mode"
		# set up ad-hoc wifi "access point"
		# most wifi drivers won't allow changing mode whilst up
		ifconfig $WIFI down
		iwconfig $WIFI mode managed
		ifconfig $WIFI up
	fi
	ps -ef | grep -v grep | grep "$DHCP_DAEMON -cf $DHCP_CONFIG" > /dev/null
	if [ $? -eq 0 ] ; then
		PID=`ps -ef | grep -v grep | grep "$DHCP_DAEMON -cf $DHCP_CONFIG" | awk '{print $2}'`
		echo "Killing $DHCP_DAEMON which has PID $PID"
		kill $PID
	fi
	exit 0
fi

#############################################################################
# shouldn't need to change these unless you're already using 172.16.31.0/24
WIFI_IP=172.16.31.1
WIFI_MASK=255.255.255.0
WIFI_NET=172.16.31.0
WIFI_DHCP="172.16.31.2 172.16.31.254"


## ROUTING ##

# set up routing
echo "Permitting ip forwarding"
echo 1 > /proc/sys/net/ipv4/ip_forward

# need to NAT outbound packets
echo "Setting up NAT"
iptables -t nat -F					# kill existing NAT
iptables -t nat -I POSTROUTING -o $WAN -j MASQUERADE	# nat to WAN IP
iptables -t nat -I POSTROUTING -o tun0 -j MASQUERADE	# nat to VPN tunnel



## SECURITY ##
echo "Setting up iptables with new chain for wifi"
iptables --new WIFI_ACCESS
iptables -F WIFI_ACCESS
iptables -I INPUT	-j WIFI_ACCESS
iptables -I FORWARD	-j WIFI_ACCESS
iptables -A WIFI_ACCESS	-j RETURN

# allow traffic already in progress
iptables -I WIFI_ACCESS	-m state --state established,related	-j ACCEPT

# permit DHCP
iptables -I WIFI_ACCESS	-i $WIFI -p udp --dport 67:68		-j ACCEPT

# permit openvpn
iptables -I WIFI_ACCESS	-i $WIFI -p udp --dport 1194		-j ACCEPT

# permit specific wireless clients to input and forward - not ideal, but WPA
# isn't possible in ad-hoc mode
CLIENTETHERS="00:25:48:e6:49:5d"
for E in $CLIENTETHERS
do
	echo "Allowing $E access"
	iptables -I WIFI_ACCESS	-i $WIFI	 -m mac --mac-source "$E" -j ACCEPT
done

## WIRELESS ##

if [ "$WIFI" = "ath0" ] ; then
	echo "Wifi card is atheros, removing ath0 and replacing with adhoc interface"
	wlanconfig ath0 destroy
        wlanconfig ath0 create wlandev wifi0 wlanmode adhoc
else
	echo "Putting card into ad-hoc mode"
	# set up ad-hoc wifi "access point"
	# most wifi drivers won't allow changing mode whilst up
	ifconfig $WIFI down
	iwconfig $WIFI mode ad-hoc
	ifconfig $WIFI up
fi

echo "Setting power to minimum, essid, channel, wep key"
iwconfig $WIFI txpower 1
iwconfig $WIFI essid $WIFI_ESSID
iwconfig $WIFI channel $WIFI_CHANNEL
iwconfig $WIFI enc $WIFI_WEP

echo "setting $WIFI ip to $WIFI_IP"
ifconfig $WIFI $WIFI_IP netmask 255.255.255.0


# suse runs dhcp chrooted
VLDP=$DHCP_ROOT/proc
echo "checking for $VLDP"
mount | grep $VLDP > /dev/null
if [ $? -ne 0 ] ; then
	echo "mounting/bind /proc to $VLDP"
	mount -o bind /proc $VLDP
fi


## SERVICES ##


# test if already running a DHCP server
ps -ef | grep -v grep | grep "$DHCP_DAEMON -cf $DHCP_CONFIG" > /dev/null
if [ $? -ne 0 ] ; then
	echo "No $DHCP_DAEMON config running, starting one"
	# set up a DHCP server

	# some dhcp servers need their leases file initialising
	touch		$DHCP_ROOT/$DHCP_LEASES
	chown dhcpd	$DHCP_ROOT/$DHCP_LEASES

	# create a DHCP server config
	cat > $DHCP_ROOT/$DHCP_CONFIG << EOF 
option domain-name-servers 154.32.105.18,154.32.107.18,154.32.109.18;
default-lease-time 86400;
ddns-update-style none;
subnet $WIFI_NET netmask $WIFI_MASK {
	range			dynamic-bootp	$WIFI_DHCP;
	option	routers		$WIFI_IP;
	default-lease-time	86400;
	max-lease-time		172800;
}
EOF
	echo "No dhcpd running, starting one"

	# fire up DHCP daemon with the config
	cd $DHCP_ROOT
	$DHCP_DAEMON	-cf	$DHCP_CONFIG	\
			-chroot $DHCP_CHROOT	\
			-group	$DHCP_GROUP	\
			-lf	$DHCP_LEASES	\
			-pf	$DHCP_PID	\
			-user	$DHCP_USER	\
			$WIFI
else
	echo "dhcpd appears to be already running on wifi, not started"
fi

# end of adhoc_wifi_gateway
