#!/bin/bash
# 
# /usr/sbin/dnsmasq-portforward
#
# A script which gets run when the dnsmasq DHCP lease database changes.
# It logs to $LOGFILE, if it exists, and maintains port-forwards using
# IP-tables so that they always point to the correct host. See
# $PORTSFILE for details on configuring this. dnsmasq must be version 2.34 
# or later.
#
# To enable this script, add 
#    dhcp-script=/usr/sbin/dnsmasq-portforward
# to /etc/dnsmasq.conf
#
# To enable logging, touch $LOGFILE
#

PORTSFILE=/etc/portforward
LOGFILE=/var/log/dhcp.log
IPTABLES=/sbin/iptables

action=${1:-0}
hostname=${4}

# log what's going on.
if [ -f ${LOGFILE} ] ; then
    date +"%D %T $*" >>${LOGFILE}
fi

# If a lease gets stripped of a name, we see that as an "old" action
# with DNSMASQ_OLD_HOSTNAME set, convert it into a "del" 
if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then
    action=del
    hostname=${DNSMASQ_OLD_HOSTNAME}
fi

# IPv6 leases are not our concern. no NAT there!
if [ ${DNSMASQ_IAID} ] ; then
   exit 0
fi

# action init is not relevant, and will only be seen when leasefile-ro is set.
if [ ${action} = init ] ; then
    exit 0
fi

# action tftp is not relevant.
if [ ${action} = tftp ] ; then
    exit 0
fi

if [ ${hostname} ]; then
    ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE})

    for port in $ports; do
	verb=removed
	protocol=tcp
	if [ ${port:0:1} = u ] ; then
	    protocol=udp 
	    port=${port/u/}
	fi
	src=${port/:*/}
	dst=${port/*:/}
# delete first, to avoid multiple copies of rules.
	${IPTABLES} -t nat -D PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst
        if [ ${action} != del ] ; then
	    ${IPTABLES} -t nat -A PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst
	    verb=added
	fi
	if [ -f ${LOGFILE} ] ; then
	    echo "     DNAT $protocol $src to ${3}:$dst ${verb}." >>${LOGFILE}
	fi
    done
fi
    
exit 0


