Site Home Page The UML Wiki UML Community Site The UML roadmap What it's good for Case Studies Kernel Capabilities Downloading it Running it Compiling Installation Skas Mode Incremental Patches Test Suite Host memory use Building filesystems Troubles User Contributions Related Links The ToDo list Projects Diary Thanks Contacts
Tutorials The HOWTO (html) The HOWTO (text) Host file access Device inputs Sharing filesystems Creating filesystems Resizing filesystems Virtual Networking Management Console Kernel Debugging UML Honeypots gprof and gcov Running X Diagnosing problems Configuration Installing Slackware Porting UML IO memory emulation UML on 2G/2G hosts Adding a UML system call Running nested UMLs
How you can help Overview Documentation Utilities Kernel bugs Kernel projects
Screenshots A virtual network An X session
Transcripts A login session A debugging session Slackware installation
Reference Kernel switches Slackware README
Papers ALS 2000 paper (html) ALS 2000 paper (TeX) ALS 2000 slides LCA 2001 slides OLS 2001 paper (html) OLS 2001 paper (TeX) ALS 2001 paper (html) ALS 2001 paper (TeX) UML security (html) LCA 2002 (html) WVU 2002 (html) Security Roundtable (html) OLS 2002 slides LWE 2005 slides
Fun and Games Kernel Hangman Disaster of the Month

### CPIT Case Study Cont'd

Building such a network, involving such subnetting is quite complex. I have therefore written some shell scripts to build the network almost automatically. The complexity of the scripts is such that it would have been easier to implement them using awk or perl or such like but currently they are in plain bash syntax. They have been rapidly prepared so are far from elegant, but being in plain bash syntax has the advantage that more people are likely to understand them. The scripts are quite flexible - any values for the subnet x.y.z can be given as a parameter (though the current script is fixed for a sub(sub)net mask of 225.255.255.240).
[ The scripts below are available in a tarball here - jdike]

Rather than going into long discussions of how the setup is implemented I have instead carefully commented the scripts themselves in explanation.

One of the most important things in the design is to decide on a suitable directory structure including the permissions used in that structure.

    		/
                    |
          ----------+---------+-----------
                              |
                             home
                              |
                    ----------+---------
                              |
                             uml
                              |
                         -----+-----+------------+------------+-----------+----- etc...
                                    |            |            |           |
                                 umlfw224_225   uml16_17    uml16_18     uml32_33

1. I have therefore created a user "uml" with a home directory /home/uml as the principal operator of the build scripts. The arrangement chosen requires that ALL scripts and the root_fs MUST be stored in this /home/uml directory. The cow files however are kept in separate directories (one per virtual machine). This helps protect them from other users.

2. Each virtual machine is allocated a user name and home directory for its cow file. The home directory for the virtual machines is a sub-directory of /home/uml. The names of the "virtual-machine-users" (and thus their home directories) are of the form: umlnn_hh where nn is the subnet they lie on and hh the host number on that subnet. For example, the virtual host with IP=x.y.z.17 would have the directory and user name of uml16_17 (the value 16 for the subnet comes from the relevant address table for a /28 subnetted network like this). The uml virtual firewall/router has the name/directory of umlfw224_225 (i.e. its IP=x.y.z.225).

3i. Three main scripts are run, one after the other in order to build the network. It is important that all scripts are run from the directory /home/uml (i.e. ~uml). The scripts are called: umlcreatenet1, umlcreatenet2, and umlcreatenet3. The way it is done presently, umlcreatenet1 must be run by user root (it insmods ethertap and runs the many uml_router occurrences etc).
3ii. For security reasons user root does not run the second script umlcreatenet2. It is run instead by user "uml". This second script boots up the virtual machines themselves. After running this second script all machines should be running in their own xterm ready for final network configuration.
3iii. The third script "umlcreatenet3" (which must be run by user root) sets up the route on the real host towards the virtual network.
3iv. At this stage the main components of the network are already in place (ethertap and the uml_router daemons etc). All that remains is to arrange the ifconfig up and route commands on the virtual hosts themselves. That is not yet fully automatic. Instead I have created two special scripts (one for the virtual router, and one for the other virtual hosts). These scripts have been copied into the /root directory of the small debian root_fs (by entering: mount root_fs [host_mount_point] -o loop (followed by cp'ing the scripts into /root). The two virtual host network configuration scripts are called umlvfw.conf and umlvhost.conf. Running any one of these scripts, without supplying any parameters, results in a brief, but hopefully helpful, usage message.

In practice their are several more scripts than those outlined in the simple startup steps above. The umlcreatenet(1,2,3) scripts are actually only "call-up" scripts - they call up the underlying scripts that do the real work of configuration. The underlying scripts are called (and they are run in the following order by the umlcreatenet scripts): umlkillall, umlkillnet (these first two are simply there to brutally "clean up" any previous uml occurrencies), umlhostsetup1, umlvfs, umlvhost, umlhostsetup2.

The best way of understanding the whole thing is simply to read the scripts through in the correct order. They are individually quite simple really!!

Summary:
a. Create the user uml (home=/home/uml), and (with home subdirectories in /home/uml) users: umlfw224_225, uml16_17, uml16,18, uml32_33, uml32_34 etc...
b. Put every script and the root_fs in /home/uml (and check all the permissions are okay).
c. Then run the following scripts (and always from pwd of /home/uml) in this order: umlcreatenet1 (with the parameters required indicated as usage when run) umlcreatenet2 umlcreatenet3
d. Login to the uml virtual machines (as root) and immediately run the network script: ./umlfw.conf (for the virtual router) or ./umlvhost.conf (for any of the other virtual machines).
Here then are the scripts themselves, and an appendix showing the permissions that were assigned to each of them and their relevant directories. Hopefully this stuff will save somebody the many many tens of hours it took me to put it all together :-).

I. The umlcreatenet1 script:

    #!/bin/sh
    #Program: umlcreatenet1
    #Licence: GPL
    #Author: William McEwan
    #Date: 6 Sep 2001

    # 1. This is the main script (part 1 of 3) for building the Virtual
    #Network Laboratory semi-automatically.
    # "umlcreatenet1 (as user root) creates a clean slate and sets up the
    #host ethertap and uml_router daemons.
    # 2. This script should be followed by running script
    # ~uml/umlcreatenet2 (as user uml).
    # 3. Finally the script ~uml/umlcreatenet3 should be run (as user root).

    # 4. The only thing left to do after that it to run the conf scripts
    # on the uml machines themselves to complete networking.  Assuming a
    # telnetd or sshd is present on the virtual machines it should then be
    # possible to remotely log in to them.

    # READ this script first to help you understand how the whole scheme works.
    # It runs all the other scripts for you except for umlvfw.conf and for
    # umlvhost.conf (which you run once the virtual machines have booted -
    # refer to the related umlvfw and the umlvhost script for usage comments).
    # I intend automating that last part later.
    # If you have difficulty getting it to work smoothly, start by giving
    # more access permissions  to all relevant files and directories (and
    # re-organise that later).

    # IMPORTANT NOTES:

    # NOTE 1: Run "./umlcreatenet1 subnet (e.g. 192.168.5)" as user root.
    #	  All these scripts assume you want the (sub)subnet mask
    # 255.255.255.240

    # NOTE 2: root_fs MUST be placed in ~uml (i.e. uml home directory) for the
    #	  scripts to find it and its modes must be -rw-rw----  root  uml
    #	  All the scripts (e.g. umlkillall, umlkillnet, umlhostsetup1,
    #	  umlvfw, umlvhost, umlhostsetup2 MUST also be kept in ~uml
    #	  for this script to find them etc) and all permissions must
    #	be carefully set up to allow user uml to access them.

    # NOTE 3: Make sure you have previously created the uml user(s) along
    # with their associated home directories.
    # And that you have setup the the main text described permissions and
    # groups etc.
    # Each virtual machine must have its own directory created in
    # ~uml. For example, vhost 192.165.5.17 in my set up has home
    # directory /home/uml/uml16_17
    # (You can use the -G and -b options of useradd for doing this kind of
    # stuff) - in practice it is best to write an automating script for
    # adding the uml users.
    # The 16_17 stands for sub(subnet) 16 and host id 17.  i.e. the number
    # 16 usefully tells you which sub(subnet) this particular host is on
    # (i.e. subnet 192.168.5.16/28).

    cpitsubnet="$1"
    case "$cpitsubnet" in
    	"")	echo
    		echo 'usage: ./umlcreatenet1 subnet(e.g. 192.168.5)'
    		exit 1
    		;;
    	*)	;;
    esac

    #MAKE SURE you are root user before running this script for the following to work...

    # Have a look at the internals of all the following scripts to see
    # what they actually do...

    cd ~uml

    # Get rid off any old uml linux processes and network daemons.
    #  i.e. clean start:

    ./umlkillall
    ./umlkillnet

    # Set up ethertap and the uml_router daemons on the host computer:

    ./umlhostsetup1 238 "$cpitsubnet"

II. The umlcreatenet2 script:

    # Program: umlcreatenet2

    #This is the second part of the startup script.
    #NOTE WELL: It should be run as user uml.

    #Boots up all the virtual machines starting with the firewall router

    cd ~uml

    cpitsubnet="$1"
    case "$cpitsubnet" in
    	"")	echo
    		echo 'usage: ./umlcreatenet2 subnet(e.g. 192.168.5)'
    		exit 1
    		;;
    	*)	;;
    esac

    ./umlvfw 225 238 0 "$cpitsubnet"
    ./umlvhost 17
    ./umlvhost 18
    ./umlvhost 33
    ./umlvhost 34
    ./umlvhost 49
    ./umlvhost 50
    ./umlvhost 65
    ./umlvhost 66
    ./umlvhost 81
    ./umlvhost 82
    ./umlvhost 97
    ./umlvhost 98
    ./umlvhost 113
    ./umlvhost 114
    ./umlvhost 129
    ./umlvhost 130
    ./umlvhost 145
    ./umlvhost 146
    ./umlvhost 161
    ./umlvhost 162

III. The umlcreatenet3 script:

    # Program: umlcreatenet3

    #This is the third and final part of the startup script.
    #NOTE WELL: It MUST be run as user root.

    # Set up the final route from the host computer to the virtual network.
    # Make sure you are in directory ~uml (where all these uml scripts are
    # located):

    cd ~uml

    cpitsubnet="$1"
    case "$cpitsubnet" in
    	"")	echo
    		echo 'usage: ./umlcreatenet3 subnet(e.g. 192.168.5)'
    		exit 1
    		;;
    	*)	;;
    esac

    ./umlhostsetup2 "$cpitsubnet"

    # Should all be up now.  Now you just need to run "umlvhost.conf on each
    # booted uml host (and umlvfw.conf on the virtual firewall router).

IV. The rough and brutal umlkillall script:

    # This is just an inelegant quick fix for killing off all the virtual machines
    # It assumes "linux" is name of the uml process.
    # I generally run this script as the first thing before building the
    # virtual net (as user root).
    # It, followed by running "umlkillnet", (as user root) cleans
    # everything up before  beginning the main virtual hosts build.
    # I also tend to rm all the cow files before rebuilding the vnet.

    # usage: ~uml/umlkillall
    # NOTE: Instead of running this script individually it can be called
    # by the script "~uml/umlcreatenet1"
    # whose purpose is to call up all the other scripts as well.  View
    # umlcreatenet1 (2 and 3) for details.

    kill -9 `ps aux | grep linux | cut -c10-14`
    rm -rf /tmp/uml/*

V. The equally rough umlkillnet script:

    # Just an inelegant quick fix for killing off all uml_router daemons
    # and ethertaps ready for a clean start

    # usage: ~uml/umlkillnet
    # NOTE: Instead of running this script individually it can be called
    # by the script "~uml/umlcreatenet1"
    # whose purpose is to call up all the other scripts as well.  View
    # umlcreatenet1 (2 and 3) for details.

    kill -9 `ps aux | grep uml_router | cut -c10-14`
    rm -f 14*
    ifconfig tap0 down
    rmmod ethertap
    rmmod ethertap0

VI. The similarly awful umlkillxterm script:

    #Just an inelegant quick way to kill all xterms/vconsoles if you ever
    #want to...
    #usage: ~uml/umlkillxterm

    kill -9 `ps aux | grep xterm | cut -c10-14`

VII. The umlhostsetup1 script:

    #!/bin/sh
    #Program: umlhostsetup1
    #Licence: GPL
    #Author: William McEwan
    #Date: 6 Sep 2001

    # This script sets up the host computer.
    # Run it (as user root) just after the "clean up scripts" (i.e
    # umlkillall followed by umlkillnet).
    # NOTE: Instead of running this script individually it can be called
    # by the script ~uml/umlcreatenet1
    # whose purpose is to call up all the other scripts as well.  View
    # umlcreatenet1 (2 and 3) for details.

    tap0ip="$1" # or in this example case could simply use: tap0ip="238"
                # (since that is what it is here!)
    case "$1" in
    	238)    ;; # Could modify script to increase acceptable tap
                       # values: e.g. 23[1-8])
    	*)	echo
    		echo 'usage: ./umlhostsetup1 tapip(e.g. 238) \
    subnet(e.g. 192.168.5)'
    		exit 1
    		;;
    esac

    cpitsubnet="$2" # or could use: cpitsubnet="x.y.z"
    tap0mac="10:0:0:0:0:2" # or could use: tap0mac=$3
                           # (or whatever MAC address you want for tap0)

    #Just in case they need done:
    mknod /dev/tap0 c 36 16
    insmod ethertap #making tap0
    #Bring tap0 up on host:
    ifconfig tap0 hw ether "$tap0mac" arp mtu 1484 ${cpitsubnet}.${tap0ip} \
    netmask 255.255.255.240 broadcast ${cpitsubnet}.239
    #Create all the subnet "switches" (daemons):
    uml_router -unix 14003 14004 &
    uml_router -unix 14005 14006 &
    uml_router -unix 14007 14008 &
    uml_router -unix 14009 14010 &
    uml_router -unix 14011 14012 &
    uml_router -unix 14013 14014 &
    uml_router -unix 14015 14016 &
    uml_router -unix 14017 14018 &
    uml_router -unix 14019 14020 &
    uml_router -unix 14021 14022 &
    uml_router -unix 14023 14024 &
    uml_router -unix 14025 14026 &
    uml_router -unix 14027 14028 &
    uml_router -unix 14029 14030 &
    #Give a wee bit time to assure uml_router daemon sockets are ready:
    sleep 1
    #Make sure the uml virtual hosts can access the uml_router daemon(s) sockets
    chgrp uml 14*
    chmod 770 14*

VIII. The umlvfw (virtual router/firewall machine) script:

    #!/bin/sh
    #Program: umlvfw
    #Licence: GPL
    #Author: William McEwan
    #Date: 6 Sep 2001

    # This script sets up the virtual machine being used as a router (firewall)
    # between the host computer and the rest of the virtual machines.
    # In this Case Study this one virtual router connects via ethertap
    # (its eth0 IP=225) to the host computer (IP=238).
    # The other nine interfaces on this virtual router connect to the other
    # virtual machines - two such on each network segment.
    # It is planned to set up a filtering firewall on this virtual router in
    # order to help sandbox remote users inside the virtual network laboratory.
    # "umlvfw" should be run as user uml (not as user root).
    # Run it after running umlkillall, umlkillnet and umlhostsetup1 or as part
    # of the general startup scripts (~uml/umlcreatenet1,2,3)
    # that comes after these.
    # NOTE: Instead of running this script individually it can be called
    # by the script "~uml/umlcreatenet2" whose purpose is to call up all
    # the other scripts as well.  View umlcreatenet2 for details.

    # (This virtual router is later connected to the uml_router daemon segments
    # using the associated script: "umlvfw.conf".
    # Note: I previously copy umlvhost.conf onto the root_fs (debian small),
    # into the directory /root using:
    # mount root_fs [host_dir_mountpoint] -o loop   and then using cp.
    # "umlvfw.conf is set up to connect to the uml_router daemons using:
    # IP addresses 30,46,62,78,94,110,126,142,158,174.
    # These are the highest host numbers for each of the segments on
    # a 255.255.255.240 subnetted IP address).

    # Also, once (and only once) the virtual machine has booted up,
    # login as root and run the associated virtual machine configuration
    # script "umlvfw.conf" by
    # entering: ./umlvfw.conf 225 238 0

    umask 006 #So that the cow files are created with the correct permissions
    case "$1" in
    	22[5-9]|23[0-7]) subsubnet=224;;
    	*)	echo
    		echo 'usage: ./umlvfw ip_address_last_octet(e.g. 225)
    \
    tapip(e.g. 238)'
    		echo '               tapnum(e.g. 0) subnet(e.g. 192.168.5)'
    		exit 1
    		;;
    esac

    mainip="$1" # or could use: mainip=225 (= other end of tap)
    tapip="$2" # or could use: tapip=238
    tapnum="$3" # e.g. tapnum=0 (makes it tap0 below)
    cpitsubnet="$4" # or could use: cpitsubnet="x.y.z"

    umlswitch1="14003,14004"
    umlswitch2="14005,14006"
    umlswitch3="14007,14008"
    umlswitch4="14009,14010"
    umlswitch5="14011,14012"
    umlswitch6="14013,14014"
    umlswitch7="14015,14016"
    umlswitch8="14017,14018"
    umlswitch9="14019,14020"
    umlswitch10="14021,14022"
    umlswitch11="14023,14024"
    umlswitch12="14025,14026"
    umlswitch13="14027,14028"
    umlswitch14="14029,14030"

    # Start up uml linux as a daemon (nohup) with one xterm to do the final
    # network configuration; using umlvfw.conf (as described in that script):
    cow_locat=~uml/umlfw${subsubnet}_${mainip}/cowfw${subsubnet}_${mainip}
    nohup linux umid=${mainip} ubd0=${cow_locat},root_fs \
    eth0=ethertap,"tap${tapnum}",,${cpitsubnet}.${tapip} \
    eth1=daemon,,unix,${umlswitch1} eth2=daemon,,unix,${umlswitch2} \
    eth3=daemon,,unix,${umlswitch3} eth4=daemon,,unix,${umlswitch4} \
    eth5=daemon,,unix,${umlswitch5} eth6=daemon,,unix,${umlswitch6} \
    eth7=daemon,,unix,${umlswitch7} eth8=daemon,,unix,${umlswitch8} \
    eth9=daemon,,unix,${umlswitch9} eth10=daemon,,unix,${umlswitch10} \
    eth11=daemon,,unix,${umlswitch11} eth12=daemon,,unix,${umlswitch12} \
    eth13=daemon,,unix,${umlswitch13} eth14=daemon,,unix,${umlswitch14} \
    ssl=pty con=pty con0=xterm &

    umask 022 #returning umask to original values on my host

IX. The umlvhost (every other virtual machine) script:

    #!/bin/sh
    #Program: umlvhost
    #Licence: GPL
    #Author: William McEwan
    #Date: 6 Sep 2001

    # This script sets up a single virtual machine on
    # the network segment relevant to its ip address (e.g ip 17,18...33,34...etc).
    # It should be run as user uml (not as user root).
    # Run it after running umlkillall, umlkillnet and umlhostsetup1 or
    # as part of a general script (umlcreatenet1,2,3)that comes after these.
    # NOTE: Instead of running this script individually it can be called by
    # the script "~uml/umlcreatenet2" whose purpose is to call up all
    # the other scripts as well.  View umlcreatenet2 for details.

    # (It is later connected to the uml_router daemon segments using
    # the associated script: "umlvhost.conf".
    # Note: I previously copy umlvhost.conf onto the root_fs (debian small),
    # into the directory /root using:
    # mount root_fs [host_dir_mountpoint] -o loop   and then using cp).

    # Also, once (and only once) the virtual machine has booted up,
    # login as root and run the script "umlhost.conf" by entering,
    # for example: ./umlvhost.conf 17
    # Repeat the above for the other (non-firewall) virtual machines
    # (using different IPs!).
    # (Later I hope to make this networking more automatic..:-).

    umask 006 #So that the cow files are created with the correct permissions
    mainip="$1"

    #Arrange for the host IP to end up on the correct uml_router daemon subnet:
    case "$mainip" in
    	[1-9]|1[0-4])			subsubnet=0 ; umlswitch="14001,14002"  ;;
    	1[7-9]|2[0-9]|30)		subsubnet=16 ; umlswitch="14003,14004"  ;;
    	3[3-9]|4[0-6])			subsubnet=32 ; umlswitch="14005,14006"  ;;
    	49|5[0-9]|6[0-2])		subsubnet=48 ; umlswitch="14007,14008"  ;;
    	6[5-9]|7[0-8])			subsubnet=64 ; umlswitch="14009,14010"  ;;
    	8[1-9]|9[1-4])			subsubnet=80 ; umlswitch="14011,14012"  ;;
    	9[7-9]|10[0-9]|110)		subsubnet=96 ; umlswitch="14013,14014"  ;;
    	11[3-9]|12[0-6])		subsubnet=112 ; umlswitch="14015,14016"  ;;
    	129|13[0-9]|14[1-2])	subsubnet=128 ; umlswitch="14017,14018"  ;;
    	14[5-9]|15[0-8])		subsubnet=144 ; umlswitch="14019,14020"  ;;
    	16[1-9]|17[0-4])		subsubnet=160 ; umlswitch="14021,14022"  ;;
    	17[7-9]|18[0-9]|190)	subsubnet=176 ; umlswitch="14023,14024"  ;;
    	19[3-9]|20[0-6])		subsubnet=192 ; umlswitch="14025,14026"  ;;
    	209|21[0-9]|22[0-2])	subsubnet=208 ; umlswitch="14027,14028"  ;;
    #	22[5-9]|23[0-8])		subsubnet=224 ; umlswitch="14029,14030"  ;;
    	24[1-9]|25[0-4])		subsubnet=240 ; umlswitch="14031,14032"  ;;
    	*)	echo
    		echo 'invalid ip_octet'
    		echo 'usage: ./umlvhost dotted_dec_ip_address_last_octet(e.g. 17)'
    		exit 1
    		;;
    esac

    # Start up uml linux as a daemon (nohup) with one xterm to do the
    # final network configuration; using umlvhost.conf (as described in
    # that script):
    cow_locat=~uml/uml${subsubnet}_${mainip}/cow${subsubnet}_${mainip}
    nohup linux umid=uml${mainip} ubd0=${cow_locat},root_fs \
    eth0=daemon,,unix,${umlswitch} ssl=pty con=pty con0=xterm &

    umask 022 #returning umask to original values on my host

X. The virtual router/firewall network configuration script (umlvfw.conf):

    #!/bin/sh
    #Program: umlvfw.conf
    #Licence: GPL
    #Author: William McEwan
    #Date: 6 Sep 2001

    # This script is used to finally connect the virtual router (firewall)
    # to the virtual network.
    # It is run from the virtual machine itself after it is first booted
    # as root user.
    # I plan to automate this better later.
    # I store this script in the /root directory of the debian small
    # root_fs used in the experiment.
    # I similarly store one copy of the script umlvhost.conf in the same place.
    # I get them there using the command:
    # mount root_fs /some_host_mount_point -o loop
    # followed by cp them from the host computer.

    # In the current setup $1 should be entered on the
    # commandline as 225 (= the virtual machine end of tap0):
    case "$1" in
    	22[5-9]|23[0-7]) ;;
    	*)	echo
    		echo 'usage: umlhost ip_address_last_octet(e.g. 225) \
    tapip(e.g. 238) subnet(e.g. 192.168.5'
    		exit 1
    		;;
    esac

    mainip="$1" # e.g. mainip=225 (= other end of tap).
    tapip="$2" # or could use: tapip=238 (= host computer tap0 IP address).
    cpitsubnet="$3"  # or could make: cpitsubnet="x.y.z"

    # Configure the ethertap connection from eth0 to tap:
    ifconfig eth0 ${cpitsubnet}.${mainip} netmask 255.255.255.240
    broadcast ${cpitsubnet}.239 up

    # Configure the virtual router connections to the uml_router daemon sockets:
    ifconfig eth1 ${cpitsubnet}.30 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.31 up
    ifconfig eth2 ${cpitsubnet}.46 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.47 up
    ifconfig eth3 ${cpitsubnet}.62 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.63 up
    ifconfig eth4 ${cpitsubnet}.78 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.79 up
    ifconfig eth5 ${cpitsubnet}.94 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.95 up
    ifconfig eth6 ${cpitsubnet}.110 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.111 up
    ifconfig eth7 ${cpitsubnet}.126 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.127 up
    ifconfig eth8 ${cpitsubnet}.142 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.143 up
    ifconfig eth9 ${cpitsubnet}.158 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.159 up
    ifconfig eth10 ${cpitsubnet}.174 netmask 255.255.255.240 broadcast \
    ${cpitsubnet}.175 up

    # On the virtual router machine: add default route (gw = host tap0)
    and turn on forwarding:
    route add default gw ${cpitsubnet}.${tapip}
    echo 1 > /proc/sys/net/ipv4/ip_forward

XI. The network configuration script for all the other virtual hosts (umlvhost.conf):

    #!/bin/sh
    #Program: umlvhost.conf
    #Licence: GPL
    #Author: William McEwan
    #Date: 6 Sep 2001

    # This script is used to finally connect the virtual machines to the
    # virtual network.
    # It is run from the virtual machine itself after it is first booted
    # as root user.
    # I plan to automate this better later.
    # I store this script in the /root directory of the debian small
    # root_fs used in the experiment.
    # I similarly store one copy of the script umlvfw.conf in the same place.
    # I get them there using the command:
    # mount root_fs /some_host_mount_point -o loop
    # followed by cp them from the host computer.

    cpitsubnet="$2" # or could use: cpitsubnet="x.y.z"
    mainip="$1"

    #Arrange for the host IP to end up on the correct uml_router daemon subnet:
    case "$mainip" in
    	[1-9]|1[0-4])			gwip=14  ; bcastip=15 ;;
    	1[7-9]|2[0-9]|30)		gwip=30  ; bcastip=31 ;;
    	3[3-9]|4[0-6])			gwip=46  ; bcastip=47 ;;
    	49|5[0-9]|6[0-2])		gwip=62  ; bcastip=63 ;;
    	6[5-9]|7[0-8])			gwip=78  ; bcastip=79 ;;
    	8[1-9]|9[1-4])			gwip=94  ; bcastip=95 ;;
    	9[7-9]|10[0-9]|110)		gwip=110 ; bcastip=111 ;;
    	11[3-9]|12[0-6])		gwip=126 ; bcastip=127 ;;
    	129|13[0-9]|14[1-2])	gwip=142 ; bcastip=143 ;;
    	14[5-9]|15[0-8])		gwip=158 ; bcastip=159 ;;
    	16[1-9]|17[0-4])		gwip=174 ; bcastip=175 ;;
    	17[7-9]|18[0-9]|190)	gwip=190 ; bcastip=191 ;;
    	19[3-9]|20[0-6])		gwip=206 ; bcastip=207 ;;
    	209|21[0-9]|22[0-2])	gwip=222 ; bcastip=223 ;;
    	22[5-9]|23[0-8])		gwip=238 ; bcastip=239 ;;
    	24[1-9]|25[0-4])		gwip=254 ; bcastip=255 ;;
    	*)	echo
    		echo 'invalid ip_octet'
    		echo 'usage: ./umlvhost.conf ip_octet(e.g. 17)  \
    subnet(e.g.192.168.5)'
    		exit 1
    		;;
    esac

    # Configure the virtual machine eth0:
    ifconfig eth0 ${cpitsubnet}.${mainip} netmask 255.255.255.240
    broadcast \
    ${cpitsubnet}.${bcastip} up

    # Add a route on the virtual machine back towards the host computer
    # via the uml virtual firewall:
    route add default gw ${cpitsubnet}.${gwip}

XII. Appendix A: The permissions on the files and directories etc.:

    drwxr-xr-x    4 root     root         4096 Sep  8 20:36 home

    Inside /home:

    drwxr-x---   31 uml      uml          4096 Sep  8 20:35 uml

    Inside /home/uml:
    #the uml_router unix sockets
    srwxrwx---    1 root     uml             0 Sep  8 20:25 14003
    srwxrwx---    1 root     uml             0 Sep  8 20:25 14004
    srwxrwx---    1 root     uml             0 Sep  8 20:25 14005
    srwxrwx---    1 root     uml             0 Sep  8 20:25 14006
    ...etc...
    #the debian root filesystem
    -rw-rw----    1 root     uml      104857600 Sep  8 19:05 root_fs
    # uml virt. mach. IP=17
    drwxrwx---   10 uml16_17 uml          4096 Sep  8 20:00 uml16_17
    drwxrwx---    5 uml16_18 uml          4096 Sep  7 02:57 uml16_18
    drwxrwx---    5 uml32_33 uml          4096 Sep  8 20:00 uml32_33
    drwxrwx---    4 uml32_34 uml          4096 Sep  7 02:57 uml32_34
    drwxrwx---    4 uml48_49 uml          4096 Sep  8 18:17 uml48_49
    drwxrwx---    4 uml48_50 uml          4096 Sep  8 18:17 uml48_50
    # uml virt. router
    drwxrwx---   10 umlfw224 uml          4096 Sep  8 20:00 umlfw224_225
    ...etc...
    #first run script
    -r-x------    1 root     root         2993 Sep  8 18:25 umlcreatenet1
    -r-xr-x---    1 root     uml           666 Sep  8 17:52 umlcreatenet2
    -r-x------    1 root     root          591 Sep  8 18:27 umlcreatenet3
    #sets up real host
    -rwx------    1 root     root         1781 Sep  8 18:33 umlhostsetup1
    -rwx------    1 root     root          643 Sep  8 15:45 umlhostsetup2
    #wipes all uml processes
    -rwx------    1 root     root          716 Sep  8 20:09 umlkillall
    #wipes the uml_routers etc
    -rwx------    1 root     root          455 Sep  8 18:33 umlkillnet
    -rwx------    1 root     root          153 Sep  8 18:33 umlkillxterm
    #sets up the virtual router
    -r-xr-x---    1 root     uml          3484 Sep  8 20:33 umlvfw
    #and its networking
    -r-x------    1 root     root         2320 Sep  8 18:50 umlvfw.conf
    #sets up other virt. machines
    -r-xr-x---    1 root     uml          2921 Sep  8 20:34 umlvhost
    #and their networking
    -r-x------    1 root     root         1893 Sep  8 15:37 umlvhost.conf

    Inside /home/uml/uml16_17:
    #the cows are stored separately - gives better access control.
    #This works though it isn't what I intended...:-\
    -rw-r-----    1 uml      uml      100731392 Sep  8 20:32 cow16_17

    Inside: /home/uml/umlfw224_225:

    -rw-r-----    1 uml      uml      100704768 Sep  8 20:32 cowfw224_225
    ...etc...

XIII. For a 192.168.5.0 network with a subnet mask: 255.255.255.240

    Network         Host range                   Broadcast
                    From          To             address

    192.168.5.0    192.168.5.1    192.168.5.14   192.168.5.15
    192.168.5.16   192.168.5.17   192.168.5.30   192.168.5.31
    192.168.5.32   192.168.5.33   192.168.5.46   192.168.5.47
    192.168.5.48   192.168.5.49   192.168.5.62   192.168.5.63
    192.168.5.64   192.168.5.65   192.168.5.78   192.168.5.79
    192.168.5.80   192.168.5.81   192.168.5.94   192.168.5.95
    192.168.5.96   192.168.5.97   192.168.5.110  192.168.5.111
    192.168.5.112  192.168.5.113  192.168.5.126  192.168.5.127
    192.168.5.128  192.168.5.129  192.168.5.142  192.168.5.143
    192.168.5.144  192.168.5.145  192.168.5.158  192.168.5.159
    192.168.5.160  192.168.5.161  192.168.5.174  192.168.5.175
    192.168.5.176  192.168.5.177  192.168.5.190  192.168.5.207
    192.168.5.208  192.168.5.209  192.168.5.222  192.168.5.223
    192.168.5.224  192.168.5.225  192.168.5.238  192.168.5.239
    192.168.5.240  192.168.5.241  192.168.5.254  192.168.5.255

Hosted at