#!/bin/sh
#
# Script to generate ipf rules based on /etc/ipf.rc and /var/spool/ipscomp
#                                                     cheesy@sackheads.org
# 
# ***WARNING***
# Probably got mega races in it. Needs to be run as root, so just
# chmod 700 $0
# Also, no checks are made that /var/spool/ipscromp/* are valid IPs
# ***WARNING***

MAX_IP_AGE=8
IP_LIST_DIR=/var/spool/ipscromp
ETHER_DEV=fxp0

IPF_RC=/etc/ipf.rc
TMP_IPF_RC=/tmp/ipf.rc
IPF=/sbin/ipf

umask 077

PATH=/usr/bin:/bin:/usr/sbin:/sbin

if [ ! -r $IPF_RC ]
then
  echo Cannot read "'$IPF_RC'" - aborting. >&2
  exit 1
fi

## Remove old IPs
find $IP_LIST_DIR -cmin +$(($MAX_IP_AGE * 60)) -type f -maxdepth 1 -print0 |\
  xargs -0 rm

## Now generate the new rules

## *very* basic race condition safety feature
rm -f $TMP_IPF_RC

cat $IPF_RC > $TMP_IPF_RC

cmp -s $IPF_RC $TMP_IPF_RC
if [ $? -ne 0 ]
then
  echo "'$TMP_IPF_RC'" corrupted in transit - aborting. >&2
  exit 1
fi

echo -e "\n##\n## Lines below auto generated by $0\n##" >> $TMP_IPF_RC

for ip in $(cd $IP_LIST_DIR && /bin/ls)
do
  ## If the directory is empty, $ip = *
  if [ "$ip" != '*' ]
  then
    echo pass in quick on $ETHER_DEV proto tcp from $ip to any >> $TMP_IPF_RC
  fi
done

# Now we have the rules, lets attempt a syntax check.
# Unfortunately, -n seems MEGA lame and syntax errs dont affect $?
# so we have to do bogusness...
errors=$($IPF -Fa -n -f $TMP_IPF_RC 2>&1)
rc=$?

if [ -n "$errors" ]
then
  echo $errors >&2
fi

if [ $rc -ne 0 -o -n "$errors" ]
then
  echo ipf -n returned non zero - aborting. >&2
  exit $rc
fi

# Bend over... ;)
$IPF -Fa -f $TMP_IPF_RC
rc=$?

# If the rules are bogus, leave them for inspection...
if [ $rc -eq 0 ]
then
  rm -f $TMP_IPF_RC
fi

exit $rc
