#!/bin/bash # Generate interface files for a common topology # # Default values topname="lan" topnum="100" numhosts=1 numrouters=0 outdir="./" # Read input parameters while [ "$1" != "" ]; do case $1 in -l | --lefthosts ) shift; lefthosts=$1; ;; -r | --righthosts ) shift; righthosts=$1; ;; -R | --routers ) shift; routers=$1; ;; -n | --number ) shift; topnum=$1; ;; -o | --out ) shift; outdir=$1; ;; * ) usage exit 1 esac shift done # Topology parameters numnetworks=$(( ${routers} + 1)); totalnodes=$(( ${lefthosts} + ${routers} + ${righthosts} )); firstrouter=$(( ${lefthosts} + 1 )); lastrouter=$(( ${lefthosts} + ${routers} )); netnumber=1 # Address structure # Ip addresses are split into parts: # commonnetwork - subnet - hostbase - hostspecific # where # commonnetwork is the same for all networks, e.g. 192.168. commonnetwork="192.168." # subnet is an integer, incremented for each subnet subnet=1 # hostbase is 1 for left hosts lefthostbase=1 # and 2 or higher for right hosts righthostbase=2 # hostspecific is an integer, increment for each host in the subnet hostspecific=1 # # The result is address such as: # lefthosts: 192.168.1.11, 192.168.1.12, 192.168.1.13, ... , 192.168.1.20, ... # righthosts: 192.168.x.21, 192.168.x.22, 192.168.x.23, ..., 192.168.x.30, ... # router1: 192.168.1.1, 192.168.2.1 # router2: 192.168.2.2, 192.168.3.2 # router3: 192.168.3.3, 192.168.4.3 # routerN: 192.168.N.N, 192.168.(N+1).N # Other addresses used: netmask="255.255.255.0" defaultnetwork="${commonnetwork}0.0" defaultnetmask="255.255.0.0" # Check the limits # Currently there is a limit on the number of networks/routers supported # since the router addressing scheme will overlap with host addressing # scheme in the right network. This is limited by righthostbase. # To lift this limit, increase righthostbase parameter above. limitrouters=$(( ${righthostbase} * 10 - 1 )); if [ ${routers} -gt ${limitrouters} ]; then echo "vn: The number of routers you selected (${routers}) creates" echo "vn: too many networks such that there will be a conflict" echo "vn: in addresses assigned to hosts and routers. The" echo "vn: current limit is ${limitrouters}. Either reduce the" echo "vn: number of routers, or modify this script and increase" echo "vn: righthostbase." echo "vn: Error. Address conflict due to too many routers. Exiting." exit 1 fi # Currently there is a limit on the number of networks/routers supported # since networks are named a, b, c, d, ... . # To lift this limit, need to modify the naming scheme, e.g. a, b, ... z, aa, ab, ... limitnetworks=26 if [ ${numnetworks} -gt ${limitnetworks} ]; then echo "vn: The number of routers you selected (${routers}) creates" echo "vn: more than the supported number of networks (${limitnetworks})." echo "vn: Please try again with less routers (or change this script" echo "vn: to support more networks)". echo "vn: Error. Too many routers. Exiting." exit 1 fi # Create the interfaces for each node for (( node=1; node<=${totalnodes}; node++ )); do # Node number in text format noden=${node} if [ ${noden} -lt 10 ]; then noden="0${noden}"; fi # Name of interface file nodeiffile="${outdir}/interfaces-topology-${topnum}-node-${noden}" # IP addresses # Left hosts if [ ${node} -lt ${firstrouter} ]; then nodetype="host" hostaddress=$(( ${lefthostbase} * 10 + ${node} )); ipaddress="${commonnetwork}${subnet}.${hostaddress}"; netaddress="${commonnetwork}${subnet}.0" bcaddress="${commonnetwork}${subnet}.255" defaultrouter="${commonnetwork}${subnet}.1" # Right hosts elif [ ${node} -gt ${lastrouter} ]; then nodetype="host" hostaddress=$(( ${righthostbase} * 10 + ${node} - ${lefthosts} - ${routers} )); ipaddress="${commonnetwork}${subnet}.${hostaddress}"; routerhostportion=$(( ${subnet} - 1 )); defaultrouter="${commonnetwork}${subnet}.${routerhostportion}" # Routers else nodetype="router" routernum=$(( ${node} - ${lefthosts} )); ipaddress="${commonnetwork}${subnet}.${routernum}" subnet2=$(( ${subnet} + 1 )); ipaddress2="${commonnetwork}${subnet2}.${routernum}" netaddress2="${commonnetwork}${subnet2}.0" bcaddress2="${commonnetwork}${subnet2}.255" fi netaddress="${commonnetwork}${subnet}.0" bcaddress="${commonnetwork}${subnet}.255" echo "${node} ${firstrouter} ${lastrouter} ${nodetype}" # Convert subnet number into name, e.g. "1" to "neta" subnetnum=$(( ${subnet} + 96 )); subnetletter=`printf "\x$(printf %x $subnetnum)"`; vboxnet="net${subnetletter}" if [ "${nodetype}" = "router" ]; then subnet2num=$(( ${subnet2} + 96 )); subnet2letter=`printf "\x$(printf %x $subnet2num)"`; vboxnet2="net${subnet2letter}" fi echo "# Interface file auto-generated by vn-generateinterfaces" > ${nodeiffile} echo "auto lo" >> ${nodeiffile} echo "iface lo inet loopback" >> ${nodeiffile} echo " " >> ${nodeiffile} echo "auto eth0" >> ${nodeiffile} echo "iface eth0 inet dhcp" >> ${nodeiffile} echo " " >> ${nodeiffile} echo "# VBoxNetwork: ${vboxnet}" >> ${nodeiffile} echo "auto eth1" >> ${nodeiffile} echo "iface eth1 inet static" >> ${nodeiffile} echo -e "\taddress ${ipaddress}" >> ${nodeiffile} echo -e "\tnetmask ${netmask}" >> ${nodeiffile} echo -e "\tnetwork ${netaddress}" >> ${nodeiffile} echo -e "\tbroadcast ${bcaddress}" >> ${nodeiffile} # Host node if [ "${nodetype}" = "host" ]; then echo -e "\tpost-up route add -net ${defaultnetwork} netmask ${defaultnetmask} gw ${defaultrouter} dev eth1" >> ${nodeiffile} echo -e "\tpre-down route del -net ${defaultnetwork} netmask ${defaultnetmask} gw ${defaultrouter} dev eth1" >> ${nodeiffile} # Router node else # In a chain such as: # H1 - R1 - R2 - R3 - R4 - R5 - H2 # we will treat R1, R2 and R3 as left side routers, and R4 and R5 as right side # Left side routers will have: # - default route to rest of network on eth2 (right side of router) # - specific routes to subnets on left of it on eth1 # Note that we don't need to add specific routes for directly attached networks # as they are automatically created when the interface is brought up. # For example R2 will have: # - default route to 192.168.0.0 to gw R3 on eth2 # - specific router to 192.168.1.0 (H1-R1) to gw R1 on eth1 # Similar applies for right side routers, but in the opposite direction: # - default route to rest of network on eth1 (left side of router) # - specific routes to subnets on right of it on eth2 firstrouternum=1 midrouternum=$(( (${routers} + 1) / 2 )); lastrouternum=${routers} # Left side routers if [ ${routernum} -le ${midrouternum} ]; then # Add 'numsr' specific routes on 1st interface numsr=$(( ${routernum} - ${firstrouternum} )); for (( sr=1; sr<=${numsr}; sr++ )); do destnetwork="${commonnetwork}${sr}.0" destmask=${netmask} destgw="${commonnetwork}${subnet}.$(( ${subnet} - 1 ))" destif="eth1" echo -e "\tpost-up route add -net ${destnetwork} netmask ${destmask} gw ${destgw} dev ${destif}" >> ${nodeiffile} echo -e "\tpre-down route add -net ${destnetwork} netmask ${destmask} gw ${destgw} dev ${destif}" >> ${nodeiffile} done # Create 2nd interface on router echo " " >> ${nodeiffile} echo "# VBoxNetwork: ${vboxnet2}" >> ${nodeiffile} echo "auto eth2" >> ${nodeiffile} echo "iface eth2 inet static" >> ${nodeiffile} echo -e "\taddress ${ipaddress2}" >> ${nodeiffile} echo -e "\tnetmask ${netmask}" >> ${nodeiffile} echo -e "\tnetwork ${netaddress2}" >> ${nodeiffile} echo -e "\tbroadcast ${bcaddress2}" >> ${nodeiffile} # Add default route on 2nd interface if [ ${routers} -gt 1 ]; then defaultgw="${commonnetwork}$(( ${subnet} + 1 )).$(( ${subnet} + 1 ))"; defaultif="eth2" echo -e "\tpost-up route add -net ${defaultnetwork} netmask ${defaultnetmask} gw ${defaultgw} dev ${defaultif}" >> ${nodeiffile} echo -e "\tpre-down route add -net ${defaultnetwork} netmask ${defaultnetmask} gw ${defaultgw} dev ${defaultif}" >> ${nodeiffile} fi # Right side routers else # Add default route on 1st interface defaultgw="${commonnetwork}${subnet}.$(( ${subnet} - 1 ))"; defaultif="eth1" echo -e "\tpost-up route add -net ${defaultnetwork} netmask ${defaultnetmask} gw ${defaultgw} dev ${defaultif}" >> ${nodeiffile} echo -e "\tpre-down route add -net ${defaultnetwork} netmask ${defaultnetmask} gw ${defaultgw} dev ${defaultif}" >> ${nodeiffile} # Create 2nd interface on router echo " " >> ${nodeiffile} echo "# VBoxNetwork: ${vboxnet2}" >> ${nodeiffile} echo "auto eth2" >> ${nodeiffile} echo "iface eth2 inet static" >> ${nodeiffile} echo -e "\taddress ${ipaddress2}" >> ${nodeiffile} echo -e "\tnetmask ${netmask}" >> ${nodeiffile} echo -e "\tnetwork ${netaddress2}" >> ${nodeiffile} echo -e "\tbroadcast ${bcaddress2}" >> ${nodeiffile} # Add 'numsr' specific routes on 2nd interface numsr=$(( ${lastrouternum} - ${routernum} )); for (( sr=${numsr}; sr>=1; sr-- )); do destnetwork="${commonnetwork}$(( ${subnet} + 1 + ${sr} )).0" destmask=${netmask} destgw="${commonnetwork}$(( ${subnet} + 1 )).$(( ${subnet} + 1 ))" destif="eth1" echo -e "\tpost-up route add -net ${destnetwork} netmask ${destmask} gw ${destgw} dev ${destif}" >> ${nodeiffile} echo -e "\tpre-down route add -net ${destnetwork} netmask ${destmask} gw ${destgw} dev ${destif}" >> ${nodeiffile} done fi fi # Increment subnet if necessary if [ "${nodetype}" = "router" ]; then subnet=$(( ${subnet} + 1 )); fi done