--- /dev/null
+#!/bin/sh
+#
+# Marta Carbone
+# Copyright (C) 2009 UniPi
+# $Id$
+#
+# This script is the backend to be used with
+# the vsys system.
+# It allows to configure dummynet pipes and queues.
+# In detail it:
+# - read the user's input from the input pipe
+# - validate the input
+# - set the firewall
+# - put results on the output vsys pipe
+#
+# This script expect to read from the input vsys
+# pipe a line formatted as follow:
+# ${PORT} ${TIMEOUT} <dummynet parameters>
+# the timeout value is expressed as:
+# week, day, month or anything else accepted by the date command
+
+# save the slicename
+SLICE=$1
+
+LOG_FILE=/tmp/netconfig.log
+
+# programs
+CUT=/usr/bin/cut
+SED=/bin/sed
+IPFW=/sbin/ipfw
+
+# set to 0 to disable debug messages
+DEBUG=0
+
+debug() { # $1 message to be displayed
+ [ x"${DEBUG}" != x"0" ] && echo $1 >>{LOG_FILE};
+}
+
+abort() { # $1 message to be displayed
+ echo "$1"
+ exit 1
+}
+
+user_error() { # $1 message to be displayed
+ echo "1 User error: $1"
+ exit 1
+}
+
+filter() { # $* variables to be filtered
+ # allowed chars are: numbers, upcase and lowecase
+ # chars, and the following symbols: . _ - /
+ echo "$*" | ${SED} -r 's/[^0-9a-zA-Z. _\/\-]*//g'
+}
+
+# Add ipfw pipe and rules
+# We use the PORT number to configure the
+# pipe, and add rules for that port.
+# The default directory is the slicename root
+add_rules() { # $1 timeout value
+ local EXPIRE
+
+ debug "Add a new rule"
+ # schedule the rule deletion
+ EXPIRE=`date --date="${TIMEOUT}" +%s`
+ [ x"${EXPIRE}" = x"" ] && abort "Date format $1 not valid"
+
+ # prepend the profile name with the vserver directory
+ echo ${CONFIG_STRING} | ${SED} -e "s/ profile \(.[^ ]\)/ profile \/vservers\/${SLICE}\/\1/g"
+ #
+
+ # check syntax, if ok execute
+ # add rules
+ local IPFW_CHECK="${IPFW} -n "
+ local ERROR=0
+
+ [ $ERROR -eq 0 ] && \
+ ${IPFW_CHECK} add ${RULE_N} pipe ${PIPE_N} ip from me to any src-port ${PORT} // ${EXPIRE} ${SLICE}
+ let "ERROR += $?"
+ [ $ERROR -eq 0 ] && \
+ ${IPFW_CHECK} add ${RULE_N} pipe ${PIPE_N} ip from any to me dst-port ${PORT}
+
+ let "ERROR += $?"
+ [ $ERROR -eq 0 ] && \
+ ${IPFW_CHECK} pipe ${PIPE_N} config ${PARSED_CONFIGURATION}
+
+ if [ ! $ERROR -eq 0 ]; then
+ echo "Some errors occurred not executing"
+ user_error "ipfw syntax error"
+ fi
+
+ # add rules
+ ${IPFW} add ${RULE_N} pipe ${PIPE_N} ip from me to any src-port ${PORT} // ${EXPIRE} ${SLICE}
+ ${IPFW} add ${RULE_N} pipe ${PIPE_N} ip from any to me dst-port ${PORT}
+
+ # config pipe
+ ${IPFW} pipe ${PIPE_N} config ${PARSED_CONFIGURATION}
+}
+
+# Delete a given link
+delete_link()
+{
+ ipfw delete ${RULE_N}
+ ipfw pipe delete ${RULE_N}
+}
+
+# The rule we want to configure already exist.
+# Check for slice owner matching.
+modify_rule()
+{
+ local RULE
+
+ RULE=`ipfw list ${PORT} 2>&1 | cut -d ' ' -f 12`;
+ if [ "${RULE}" = "${SLICE}" ] ; then # replace the link configuration
+ debug "The rule already exist, the owner match, delete old rule"
+ echo "Owner match"
+ delete_link
+ add_rules ${TIMEOUT}
+ else
+ user_error "the rule already exist, ant you are not the slice owner, try later"
+ fi
+}
+
+# process a single line of input, a request
+process()
+{
+ local TMP; # temporary var
+
+ debug "Received from the input pipe: $1"
+
+ ARGS=`echo $1 | wc -w`
+ if [ $ARGS -le 3 ]; then
+ abort "One or more input parameter is missing"
+ fi
+
+ # filter input
+ TMP=`echo $1 | cut -d\ -f 1`
+ PORT=`filter $TMP`
+ TMP=`echo $1 | cut -d\ -f 2`
+ TIMEOUT=`filter $TMP`
+ TMP=`echo $1 | cut -d\ -f 3-`
+ CONFIG_STRING=`filter $TMP`
+
+ debug "PORT: $PORT"
+ debug "TIMEOUT: $TIMEOUT"
+ debug "configuration string: $CONFIG_STRING"
+
+ # deny port <= 1024
+ [ ${PORT} -le 1024 ] && user_error "it is not allowed to modify the port range [0-1024]"
+
+ # start to configure pipes and rules
+ PIPE_N=${PORT}
+ RULE_N=${PORT}
+
+ return 0
+ # check if the link is already configured
+ ipfw list ${PORT} 2>&1
+
+ if [ x"$?" != x"0" ]; then # new rule, add and set owner/timeout
+ add_rules
+ else # the rule already exist, check owner
+ modify_rule
+ fi
+
+}
+
+# main starts here
+
+ requests=[]
+ i=0
+
+ while read request
+ do
+ # read -a read arguments in array
+ # XXX skip lines starting with #
+ requests[$i]=$request;
+ let i=$i+1
+ done
+
+ # create the lock
+
+ # process requests
+ for i in `/usr/bin/seq 0 $((${#requests[*]} - 1))`
+ do
+ process "${requests[$i]}"
+ add_rules
+ done
+
+ # delete the lock
+ exit 0