blob: d5bcbcbe5f53716bb87ca84c11e9d03bb45c6214 [file] [log] [blame] [raw]
#!/bin/sh
#
IPFBASE=/etc/opt/ipf
PATH=/bin:/sbin:/usr/sbin:${PATH}:/opt/ipf/bin
IPFILCONF=${IPFBASE}/ipf.conf
IP6FILCONF=${IPFBASE}/ipf6.conf
IPNATCONF=${IPFBASE}/ipnat.conf
IPPOOLCONF=${IPFBASE}/ippool.conf
PFILCHECKED=no
if [ -d /var/run ] ; then
PIDFILE=/var/run/ipmon.pid
else
PIDFILE=${IPFBASE}/ipmon.pid
fi
getpid()
{
if [ -f /usr/bin/pgrep ] ; then
rval=`pgrep $1`
else
rval=`ps -ef | awk "/$1/ { print \\$2; } " -`
fi
return $rval
}
logmsg()
{
logger -p local0.emerg -t ipfilter "$1"
echo "$1" >&2
}
checkpfil()
{
if [ $PFILCHECKED = yes ] ; then
return
fi
if [ -z "`ndd /dev/pfil qif_status 2>/dev/null`" ] ; then
logmsg "pfil not available to support ipfilter"
exit 1
fi
if [ `uname -r|cut -d. -f2` -gt 7 ] ; then
realnic=`/sbin/ifconfig -a modlist 2>/dev/null | grep -c pfil`
else
for i in `ifconfig -a | cut -d: -f1 | egrep -v '[ ]|^lo'`
do
if strconf -m pfil < /dev/$i >/dev/null 2>&1 ; then
realnic=1;
break;
fi
done
fi
if [ $realnic -eq 0 ] ; then
logmsg "pfil not configured for firewall/NAT operation"
fi
PFILCHECKED=yes
}
getids()
{
ipfid=`modinfo 2>&1 | awk '/ipf / { print $1 } ' - 2>/dev/null`
ipfruleid=`modinfo 2>&1 | awk '/ipfrule/ { print $1 } ' - 2>/dev/null`
if [ -f $PIDFILE ] ; then
pid=`cat $PIDFILE 2>/dev/null`
else
getpid ipmon
pid=$?
fi
}
block_default_workaround() {
ipf -F a
echo "constructing minimal name resolution rules..."
NAMESERVERS=`cat /etc/resolv.conf 2>/dev/null| \
nawk '/nameserver/ {printf "%s ", $2}' 2>/dev/null`
if [ -z "$NAMESERVERS" ] ; then
return
fi
for NS in $NAMESERVERS ; do
IF_TO_NS=`route -n get $NS 2>/dev/null| \
nawk '$1 == "interface:" { print $NF ; exit }' \
2>/dev/null`
if [ -z "$IF_TO_NS" ] ; then
continue
fi
IP_TO_NS=`ifconfig $IF_TO_NS 2>/dev/null| \
nawk 'NR == "2" { print $2 ; exit }' 2>/dev/null`
if [ -z "$IP_TO_NS" ] ; then
continue
fi
echo "pass out quick on $IF_TO_NS proto udp from $IP_TO_NS to $NS port = 53 keep state" | \
ipf -f -
done
}
load_ipf_config() {
bad=0
if [ -r ${IPFILCONF} ]; then
checkpfil
if `ipf -V | \
nawk '$1 == "Default:" && $2 == "pass" { exit 1 }'` ; then
block_default_workaround
fi
ipf -IFa -f ${IPFILCONF}
if [ $? != 0 ]; then
echo "$0: load of ${IPFILCONF} into alternate set failed"
bad=1
fi
fi
if [ -r ${IP6FILCONF} ]; then
checkpfil
ipf -6IFa -f ${IP6FILCONF}
if [ $? != 0 ]; then
echo "$0: load of ${IPFILCONF} into alternate set failed"
bad=1
fi
fi
if [ $bad -eq 0 ] ; then
ipf -s -y
else
echo Not switching config due to load error.
fi
}
load_ipnat_config() {
if [ -r ${IPNATCONF} ]; then
checkpfil
ipnat -CF -f ${IPNATCONF}
if [ $? != 0 ]; then
echo "$0: load of ${IPNATCONF} failed"
else
ipf -y
fi
fi
}
load_ippool_config() {
if [ -r ${IPPOOLCONF} ]; then
checkpfil
ippool -F
ippool -f ${IPPOOLCONF}
if [ $? != 0 ]; then
echo "$0: load of ${IPPOOLCONF} failed"
fi
fi
}
case "$1" in
start)
getids
[ -n "$pid" ] && kill -TERM $pid 2>/dev/null
[ -n "$ipfruleid" ] && modunload -i $ipfruleid 2>/dev/null
[ -n "$ipfid" ] && modunload -i $ipfid 2>/dev/null
modload /usr/kernel/drv/ipf
if [ -f /usr/kernel/drv/ipfrule ] ; then
modload /usr/kernel/drv/ipfrule
fi
load_ippool_config
load_ipf_config
load_ipnat_config
ipmon -Ds
;;
stop)
getids
[ -n "$pid" ] && kill -TERM $pid
/bin/rm -f $PIDFILE
[ -n "$ipfruleid" ] && modunload -i $ipfruleid 2>/dev/null
[ -n "$ipfid" ] && modunload -i $ipfid
;;
pause)
getids
ipfs -l
ipfs -NS -w
ipf -D
if [ -f $PIDFILE ] ; then
if kill -0 $pid; then
kill -TERM $pid
else
cp /dev/null $PIDFILE
fi
fi
;;
resume)
getids
ipf -E
ipfs -R
load_ippool_config
load_ipf_config
load_ipnat_config
if [ -f $PIDFILE -a x$pid != x ] ; then
ipmon -Ds
fi
;;
reload)
load_ippool_config
load_ipf_config
load_ipnat_config
;;
reipf)
load_ipf_config
;;
reipnat)
load_ipnat_config
;;
*)
echo "Usage: $0 (start|stop|reload|reipf|reipnat|pause|resume)" >&2
exit 1
;;
esac
exit 0