Added ipfw backend script.
Marta Carbone [Thu, 11 Jun 2009 09:12:42 +0000 (09:12 +0000)]
exec/ipfw-be [new file with mode: 0755]
vsys-scripts.spec

diff --git a/exec/ipfw-be b/exec/ipfw-be
new file mode 100755 (executable)
index 0000000..7e22a7c
--- /dev/null
@@ -0,0 +1,189 @@
+#!/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
index f67a198..40338ad 100644 (file)
@@ -8,7 +8,7 @@
 
 %define name vsys-scripts
 %define version 0.95
-%define taglevel 3
+%define taglevel 4
 
 %define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
 
@@ -54,6 +54,9 @@ rm -rf $RPM_BUILD_ROOT
 %postun
 
 %changelog
+* Thu Jun 11 2009 Marta Carbone <marta.carbone@iet.unipi.it> - vsys-scripts-0.95-4
+- Added the ipfw backend script
+
 * Fri Jun 05 2009 Faiyaz Ahmed <faiyaza@cs.princeton.edu> - vsys-scripts-0.95-3
 - rsync authlogs to ~/