#!/bin/sh
#
# VirtualBox lab script for BSD Router Project
# https://bsdrp.net
#
# Copyright (c) 2009-2018, The BSDRP Development Team
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

set -eu

# Global variable
VM_TPL_NAME="BSDRP_lab_template"
LOG_FILE="${HOME}/BSDRP_lab.log"
DEFAULT_RAM="512"

# A usefull function (from: http://code.google.com/p/sh-die/)
die() { echo -n "EXIT: " >&2; echo "$@" >&2; exit 1; }

check_system_common () {
	echo "Checking if VirtualBox installed..." >> ${LOG_FILE}

	`VBoxManage -v > /dev/null 2>&1` || die "[ERROR] Is VirtualBox installed ?"
	VBVERSION=`VBoxManage -v`
	VBVERSION_MAJ=`echo $VBVERSION|cut -d . -f 1`
	VBVERSION_MIN=`echo $VBVERSION|cut -d . -f 2`

	[ $VBVERSION_MAJ -lt 4 ] && die "[ERROR] Need Virtualbox 4.1 minimum"

	[ $VBVERSION_MAJ -eq 4 -a $VBVERSION_MIN -lt 1 ] &&
		die "[ERROR] Need Virtualbox 4.1 minimum"

	if ! `VBoxHeadless | grep -q vnc`; then
		if ! `VBoxHeadless | grep -q vrde`; then
			echo "No Virtualbox VRD/VNC support detected:"
			echo "BSDRP vga images will not be supported (only serial)"
			echo "VRDE: Supported by Virtualbox closed source release"
			echo "VNC:  Supported by FreeBSD VirtualBox-OSE (if enabled during make config)"
			VBOX_VGA=false
		else
			VBOX_OUTPUT="vrde"
			VBOX_VGA=true
		fi
	else
		VBOX_OUTPUT="vnc"
		VBOX_VGA=true
	fi

}

# Check filename given, and unzip it
check_image () {
	[ -f $1 ] || die "[ERROR] Can't found the file $1"

	if echo $1 | grep -q bz2  >> ${LOG_FILE} 2>&1; then
		echo "Bzip2 compressed image detected, unzip it..."
		which bunzip2 > /dev/null 2>&1 || \
			die "[ERROR] Need bunzip2 for bunzip the compressed image!"
		bunzip2 -fk $1 || die "[ERROR] Can't bunzip2 image file!"

		# change FILENAME by removing the last.bz2"
		FILENAME=`echo $1 | sed -e 's/.bz2//g'`
	elif echo $1 | grep -q xz  >> ${LOG_FILE} 2>&1; then
		echo "xz compressed image detected, unzip it..."
		which xz > /dev/null 2>&1 || \
			die "[ERROR] Need xz for unxz the compressed image!"
		xz -dkf ${FILENAME} || die "[ERROR] Can't unxz image file!"

		# change FILENAME by removing the last.lzma"
		FILENAME=`echo ${FILENAME} | sed -e 's/.xz//g'`
	fi

	file -b ${FILENAME} | grep -q "boot sector"  >> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Not a BSDRP image??"

}

# Create BSDRP template VM by converting BSDRP image disk file (given in parameter) into Virtualbox format and compress it
# This template is used only for the image disk
create_template () {
	# Generate $VM_ARCH and $CONSOLE from the filename

	[ -z "$VM_ARCH" ] && parse_filename $1

	echo "Create BSDRP template VM..." >> ${LOG_FILE}
	VBoxManage createvm --name ${VM_TPL_NAME} --ostype $VM_ARCH \
		--register >> ${LOG_FILE} 2>&1 || die "[ERROR] Can't create template VM!"

	[ -z "$RAM" ] && RAM=${DEFAULT_RAM}

	# Enabling ICH9 chipset (support 36 NIC)
	VBoxManage modifyvm ${VM_TPL_NAME} --chipset ich9 --audio none \
		--memory $RAM --vram 9 --boot1 disk --floppy disabled \
		>> ${LOG_FILE} 2>&1 || die "[ERROR] Can't customize ${VM_TPL_NAME}"

	VBoxManage modifyvm ${VM_TPL_NAME} --biosbootmenu disabled \
		>> ${LOG_FILE} 2>&1 || die "[ERROR] Can't disable bootmenu for $1"

	echo "Add ATA controller to the VM..." >> ${LOG_FILE}
	VBoxManage storagectl ${VM_TPL_NAME} --name "ATA Controller" \
		--add ide --controller PIIX4 >> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Can't add ATA controller to the VM!"

	echo "Convert BSDRP image disk to VDI..." >> ${LOG_FILE}
	VBoxManage convertfromraw "$1" \
		"${WORKING_DIR}/${VM_TPL_NAME}/${VM_TPL_NAME}.vdi" \
		>> ${LOG_FILE} 2>&1 || die "[ERROR] Can't convert BSDRP image disk!"

	echo "Add the VDI to the VM..." >> ${LOG_FILE}
	VBoxManage storageattach ${VM_TPL_NAME} --storagectl "ATA Controller" \
		--port 0 --device 0 --type hdd \
		--medium "${WORKING_DIR}/${VM_TPL_NAME}/${VM_TPL_NAME}.vdi" \
		>> ${LOG_FILE} 2>&1 || die "[ERROR] Can't add VDI to the VM!"

	VBoxManage modifyvm ${VM_TPL_NAME} --uart1 0x3F8 4 \
		--uartmode1 server /tmp/${VM_TPL_NAME}.serial \
		>> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Can't configure serial port for ${VM_TPL_NAME}"

	echo "Compress the VDI..." >> ${LOG_FILE}
	VBoxManage modifyvdi "${WORKING_DIR}/${VM_TPL_NAME}/${VM_TPL_NAME}.vdi" \
		--compact >> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Can't compres the VDI!"

	# Enable pagefusion (avoid duplicate RAM use between all routers)
	# pagefusion works only on 64bit host & guest with VT-X/AMD-V
	if [ "$VM_ARCH" = "FreeBSD_64" ]; then
		if [ "$MACHINE_TYPE" = "amd64" -o "$MACHINE_TYPE" = "x86_64" ]; then
			VBoxManage modifyvm ${VM_TPL_NAME} --pagefusion on \
				>> ${LOG_FILE} 2>&1 || \
				echo "[WARNING] Can't enable pagefusion"
		fi
	fi

	#Save CONSOLE type to extradata
	($SERIAL) && VBoxManage setextradata ${VM_TPL_NAME} Console Serial || \
		 VBoxManage setextradata ${VM_TPL_NAME} Console VGA

	echo "Take a snapshot (will be the base for linked-vm)..."  >> ${LOG_FILE} 2>&1
	VBoxManage snapshot ${VM_TPL_NAME} take SNAPSHOT \
		--description  "Snapshot used for linked clone" \
		>> ${LOG_FILE} 2>&1 || die "[ERROR] Can't take a snapshot"
}

# Check if VM allready exist
# Return 0 (true) if exist
# Returen 1 (false) if doesn't exist
check_vm () {
	echo "Check if $1 exist..." >> ${LOG_FILE}
   if `VBoxManage showvminfo $1 > /dev/null 2>&1`; then
	   echo "Found it..." >> ${LOG_FILE}
	   return 0 # true
   else
	   echo "Didn't found it..." >> ${LOG_FILE}
	   return 1 # false
   fi
}

# Clone VM
# $1 : Name of the VM
clone_vm () {
	[ "$1" = "" ] && die "[BUG] In function clone_vm() that need a vm name"

# Check if the vm allready exist
if ! check_vm $1; then
	echo "Clone VM $1..." >> ${LOG_FILE}
	VBoxManage clonevm ${VM_TPL_NAME} --name $1 --snapshot SNAPSHOT \
		--options link --register >> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Can't clone $1"
	VBoxManage modifyvm $1 --uartmode1 server /tmp/$1.serial \
		>> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Can't configure serial port for $1"
	echo "VM $1 cloned" >> ${LOG_FILE}
else
	# if existing: Is running ?
	if `VBoxManage showvminfo $1 | grep -q "running"`; then
		VBoxManage controlvm $1 poweroff ||
			echo "[ERROR] Can't poweroff running $1"
	fi
	delete_all_nic $1
fi
}

delete_all_nic () {
	#Delete all NIC
	local NIC_LIST=""
	NIC_lIST=`VBoxManage showvminfo $1 | grep MAC | cut -d ' ' -f 2 | cut -d ':' -f 1`
	for i in ${NIC_LIST}; do
		VBoxManage modifyvm $1 --nic$i none >> ${LOG_FILE} 2>&1 || \
			echo "[WARNING] Can't unconfigure NIC $i"
	done
}

# Parse filename for detecting ARCH and console
parse_filename () {
	if echo "$1" | grep -q "amd64"; then
		VM_ARCH="FreeBSD_64"
		echo "x86-64 image"
	fi

	if echo "$1" | grep -q "i386"; then
		VM_ARCH="FreeBSD"
		echo "i386 image"
	fi
	[ "$VM_ARCH" = "0" ] && die "[ERROR] Can't deduce arch type from filename"

	# SERIAL can be allready set from CLI options
	if [ -z ${SERIAL} ]; then
		if echo "$1" | grep -q "serial"; then
			SERIAL=true
			echo "serial image"
		fi
		if echo "$1" | grep -q "vga"; then
			SERIAL=false
			echo "vga image"
			if ! $VBOX_VGA; then
				die "[ERROR] You can't use BSDRP vga release with a Virtualbox that didn't support RDP or VNC"
			fi
		fi
	fi

}

# This function generate the clones
build_lab () {
	echo "Setting-up a lab with $NUMBER_VM router(s):"
	echo "- $LAN LAN between all routers"
	echo "- Full mesh Ethernet links between each routers"
	if ($HOSTONLY_NIC); then
		echo "- One NIC connected to the shared LAN with the host"
	fi
	if ($VIRTIO); then
		echo "- Virtio interfaces enabled"
		NIC_TYPE="virtio"
		DRIVER_TYPE="vtnet"
	else
		NIC_TYPE="82540EM"
		DRIVER_TYPE="em"
	fi
	[ -n "$RAM" ] && echo "- RAM: $RAM MB each"

	echo ""
	local i=1
	#Enter the main loop for each VM
	while [ $i -le $NUMBER_VM ]; do
		clone_vm BSDRP_lab_R$i

		if [ -n "$RAM" ]; then
			#Configure RAM
			VBoxManage modifyvm BSDRP_lab_R$i --memory $RAM \
				>> ${LOG_FILE} 2>&1 || \
				die "[ERROR] Can't change RAM for BSDRP_lab_R$i"
		fi

		NIC_NUMBER=0
		echo "Router$i have the following NIC:"
		#Enter in the Cross-over (Point-to-Point) NIC loop
		#Now generate X x (X-1)/2 full meshed link
		local j=1
		while [ $j -le $NUMBER_VM ]; do
			if [ $i -ne $j ]; then
				echo "${DRIVER_TYPE}${NIC_NUMBER} connected to Router${j}."
				NIC_NUMBER=$(( ${NIC_NUMBER} + 1 ))
				if [ $i -le $j ]; then
					#Need to manage correct mac address
					[ $i -le 9 ] && MAC_I="0$i" || MAC_I="$i"
					[ $j -le 9 ] && MAC_J="0$i" || MAC_J="$i"
					VBoxManage modifyvm BSDRP_lab_R$i \
						--nic${NIC_NUMBER} intnet \
						--nictype${NIC_NUMBER} ${NIC_TYPE} \
						--intnet${NIC_NUMBER} LAN${i}${j} \
						--macaddress${NIC_NUMBER} AAAA00${MAC_I}${MAC_I}${MAC_J} \
						--nicpromisc${NIC_NUMBER} allow-vms \
						>> ${LOG_FILE} 2>&1 || \
						die "[ERROR] Can't add NIC ${NIC_NUMBER} (full mesh) to VM $i"
				else
					VBoxManage modifyvm BSDRP_lab_R$i \
						--nic${NIC_NUMBER} intnet \
						--nictype${NIC_NUMBER} ${NIC_TYPE} \
						--intnet${NIC_NUMBER} LAN${j}${i} \
						--macaddress${NIC_NUMBER} AAAA00000${i}${j}${i} \
						--nicpromisc${NIC_NUMBER} allow-vms \
						>> ${LOG_FILE} 2>&1 || \
						die "[ERROR] Can't add NIC ${NIC_NUMBER} (full mesh) to VM $i"
				fi
			fi
			j=$(( $j + 1 ))
		done
		#Enter in the LAN NIC loop
		local j=1
		while [ $j -le $LAN ]; do
			#Need to manage correct mac address
			[ $i -le 9 ] && MAC_I="0$i" || MAC_I="$i"
			[ $j -le 9 ] && MAC_J="0$i" || MAC_J="$i"

			echo "${DRIVER_TYPE}${NIC_NUMBER} connected to LAN number ${j}."
			NIC_NUMBER=$(( ${NIC_NUMBER} + 1 ))
			VBoxManage modifyvm BSDRP_lab_R$i --nic${NIC_NUMBER} intnet \
				--nictype${NIC_NUMBER} ${NIC_TYPE} \
				--intnet${NIC_NUMBER} LAN10${j} \
				--macaddress${NIC_NUMBER} CCCC0000${MAC_J}${MAC_I} \
				--nicpromisc${NIC_NUMBER} allow-vms \
				>> ${LOG_FILE} 2>&1 || \
				die "[ERROR] Can't add NIC ${NIC_NUMBER} (LAN) to VM $i"
			j=$(( $j + 1 ))
		done
		if ($HOSTONLY_NIC); then
			#Need to manage correct mac address
			[ $i -le 9 ] && MAC_I="0$i" || MAC_I="$i"

			echo "${DRIVER_TYPE}${NIC_NUMBER} connected to shared-with-host LAN."
			NIC_NUMBER=$(( ${NIC_NUMBER} + 1 ))
			VBoxManage modifyvm BSDRP_lab_R$i --nic${NIC_NUMBER} hostonly \
				--hostonlyadapter${NIC_NUMBER} ${HOSTONLY_NIC_NAME} \
				--nictype${NIC_NUMBER} ${NIC_TYPE} \
				--macaddress${NIC_NUMBER} 00bbbb0000${MAC_I} \
				--nicpromisc${NIC_NUMBER} allow-vms >> ${LOG_FILE} 2>&1 || \
				die "[ERROR] Can't add NIC ${NIC_NUMBER} (Host only) to VM $i"
		fi
		i=$(( $i + 1 ))
	done
}

# Start each vm
start_lab () {
	local i=1
	echo "Start the lab..."

	# if console mode is not forced: need to look in extrada for getting console type
	if [ -z ${SERIAL} ]; then
		VBoxManage getextradata ${VM_TPL_NAME} Console | grep -q Serial \
			&& SERIAL=true || SERIAL=false
	fi
	#Enter the main loop for each VM
	while [ $i -le $NUMBER_VM ]; do
		if ! ($SERIAL); then
			[ $i -le 9 ] && VNC_PORT="0$i" || VNC_PORT="$i"
			if [ "${VBOX_OUTPUT}" = "vnc" ]; then
				nohup VBoxHeadless --vnc --${VBOX_OUTPUT}port 59${VNC_PORT} --startvm BSDRP_lab_R$i >> ${LOG_FILE} 2>&1 &
			else
				# --vrdeport seems to have disappeared from VBoxHeadless (at least on 4.3.36)
				# use VBoxManage modifyvm instead and start with config
				VBoxManage modifyvm BSDRP_lab_R$i --${VBOX_OUTPUT}port 59${VNC_PORT} || \
					die "[ERROR] Can't set ${VBOX_OUTPUT}port to 59${VNC_PORT} for VM $i"
				nohup VBoxHeadless --${VBOX_OUTPUT} on --startvm BSDRP_lab_R$i >> ${LOG_FILE} 2>&1 &
			fi
		else
			nohup VBoxHeadless --startvm BSDRP_lab_R$i >> ${LOG_FILE} 2>&1 &
		fi
		sleep 2

		if ($SERIAL); then
			echo "Connect to router ${i}: socat unix-connect:/tmp/BSDRP_lab_R${i}.serial stdio,raw,echo=0,icanon=0"
		else
			echo "Connect to router ${i}: connect a ${VBOX_OUTPUT} client on port 590${i}"
		fi
		i=$(( $i + 1 ))
	done

	if ($HOSTONLY_NIC); then
		echo "You need to configure an IP address in these range for communicating with the host:"
		/sbin/ifconfig ${HOSTONLY_NIC_NAME} | grep "inet"
	fi
}

# Delete VM
# $1: name of the VM
delete_vm () {
	[ "$1" = "" ] && die "BUG: In delete_vm (), no argument given"

	echo "Delete VM $1" >> ${LOG_FILE} 2>&1
   	echo "Delete VM $1"
	VBoxManage unregistervm $1 --delete >> ${LOG_FILE} 2>&1 || \
		die "[ERROR] Can't delete VM $1, Check ${LOG_FILE}."

	#Some times, templates is deletet, but there is some file that was not deletet
	if ! check_vm $1; then
		if [ -d "${WORKING_DIR}/$1" ]; then
			echo "[WARNING] Force deleting directory for $1"
			rm -rf "${WORKING_DIR}/$1"
		fi
	fi

}
delete_all_vm () {
	stop_all_vm
	local LIST_VM=""
	LIST_VM=`VBoxManage list vms | grep BSDRP_lab_R | cut -d "\"" -f 2`
	#Enter the main loop for each cloned VM
	for i in ${LIST_VM}; do
		check_vm $i && delete_vm $i
	done
	#And, at last, delete the template
	check_vm ${VM_TPL_NAME} && delete_vm ${VM_TPL_NAME}
	echo "All VMs deleted"
}

# Stop All VM
stop_all_vm () {
	local LIST_RUNNING_VM=""
	LIST_RUNNING_VM=`VBoxManage list runningvms | grep BSDRP_lab | cut -d "\"" -f 2`
	#Enter the main loop for each VM
	for i in ${LIST_RUNNING_VM}; do
		echo "Stopping $i..."
		VBoxManage controlvm $i poweroff >> ${LOG_FILE} 2>&1 || \
			echo "[WARNING] Can't poweroff $i"
	done
}

# Get Virtualbox hostonly adapter informatiom
vbox_hostonly () {
	if ! `VBoxManage list hostonlyifs | grep "^Name:"  >> ${LOG_FILE} 2>&1`; then
		echo "ERROR: Not VBox hostonly NIC, you need to create one:"
		echo "VBoxManage hostonlyif create"
		echo "VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.56.1 --netmask 255.255.255.0"
		echo "VBoxManage dhcpserver remove --ifname vboxnet0"
		exit 1
	fi

	HOSTONLY_NIC_NAME=`VBoxManage list hostonlyifs | grep "^Name:" | cut -d ':' -f 2 | sed 's/^[ \t]*//;s/[ \t]*$//' | head -n 1`
}

usage () {
	(
	echo "Usage: $0 [-hdsv] [-a i386|amd64] [-i BSDRP_image_file.img] [-n router-number] [-l LAN-number] [-o serial|vga]"
	echo "  -a ARCH    Force architecture: i386 or amd"
	echo "             This disable automatic arch/console detection from the filename"
	echo "             You should use -o with -a"
	echo "  -c         Enable internal NIC shared with host for each routers (default: Disable)"
	echo "  -d         Delete all BSDRP VM and disks"
	echo "  -i filename BSDRP image file name (to be used the first time only)"
	echo "  -h         Display this help"
	echo "  -l Y       Number of LAN between 0 and 9 (default: 0)"
	echo "  -m         RAM (in MB) for each VM (default: ${DEFAULT_RAM})"
	echo "  -n X       Number of router (between 1 and 9) full meshed (default: 1)"
	echo "  -o CONS    Force console:vga (default if -a) or serial"
	echo "  -s         Stop all VM"
	echo "  -v         Enable virtio drivers"
	echo ""
	) 1>&2
	exit 2
}

###############
# Main script #
###############

### Parse argument

args=`getopt a:i:dhcl:m:n:o:sv $*`
[ $? -ne 0 ] && usage

NUMBER_VM=""
HOSTONLY_NIC=false
VIRTIO=false
LAN=""
FILENAME=""
RAM=""
SERIAL=""
VM_ARCH=""

echo "BSD Router Project (https://bsdrp.net) - VirtualBox lab script"

echo "BSD Router Project (https://bsdrp.net) - Virtualbox lab script, log file" > ${LOG_FILE}

OS_DETECTED=`uname -s`
MACHINE_TYPE=`uname -m`

check_system_common

case "$OS_DETECTED" in
	"FreeBSD")
		kldstat -m vboxdrv > /dev/null 2>&1 || \
			echo "[WARNING] vboxdrv module not loaded ?"
		break
		;;
	"Linux")
		grep -q vboxdrv /proc/modules || \
			echo "[WARNING] VirtualBox module not loaded ?"
		break
		;;
	"Darwin")
                kextstat -bundle-id org.virtualbox.kext.VBoxDrv > /dev/null 2>&1 || \
                        echo "[WARNING] VirtualBox module not loaded ?"
                break
                ;;
	*)
		echo "ERROR: This script doesn't support $OS_DETECTED"
		exit 1
		;;
esac

WORKING_DIR=`VBoxManage list systemproperties | grep "Default machine folder" | cut -d ":" -f 2 | tr -s " " | sed '1s/^.//'`
MAX_NIC=`VBoxManage list systemproperties | grep "Maximum ICH9 Network Adapter count" | cut -d ":" -f 2 | tr -s " " | sed '1s/^.//'`
# A full mesh network consume, on each machine, N-1 VNIC
MAX_VM=$(( $MAX_NIC + 1 ))

set -- $args
for i do
	case "$i" in
		-a)
			if [ "$2" = "i386" ]; then
				VM_ARCH="FreeBSD"
			elif [ "$2" = "amd64" ]; then
				VM_ARCH="FreeBSD_64"
			else
				echo "INPUT ERROR: Bad ARCH name"
				usage
			fi
			shift
			shift
			;;
		-n)
			NUMBER_VM=$2
			shift
			shift
			;;
		-c)
			HOSTONLY_NIC=true
			shift
			;;
		-d)
			delete_all_vm
			exit 0
			;;
		-l)
			LAN=$2
			shift
			shift
			;;
		-h)
			usage
			;;
		-i)
			FILENAME="$2"
			echo "Filename given, delete existing lab"
			delete_all_vm
			shift
			shift
			;;
		-m)
			RAM="$2"
			shift
			shift
			;;
		-o)
			if [ "$2" = "vga" ]; then
				SERIAL=false
			elif [ "$2" = "serial" ]; then
				SERIAL=true
			else
				echo "INPUT ERROR: Bad OUTPUT name"
				usage
			fi
			shift
			shift
			;;
		-s)
			stop_all_vm
			exit 0
			;;
		-v)
			VIRTIO=true
			shift
			;;
		--)
			shift
			break
	esac
done

if [ "$OS_DETECTED" = "Darwin" ]; then
	id ${USER} | grep -q staff || \
		die "[WARNING] Your user is not in the staff group"
else
	id ${USER} | grep -q vboxusers || \
                die "[WARNING] Your user is not in the vboxusers group"
fi

if [ "$NUMBER_VM" != "" ]; then
	[ $NUMBER_VM -lt 1 ] && die "[ERROR] Use a minimal of 1 router in your lab."
	[ $NUMBER_VM -gt $MAX_VM ] && \
		die "[ERROR] Use a maximum of $MAX_VM routers in your lab (Vbox don't support more than $MAX_NIC VNIC to a VM."
else
	NUMBER_VM=1
fi

if [ $NUMBER_VM -eq 1 ]; then
	# Impose shared-with-host NIC if only one router started
	HOSTONLY_NIC=true
fi

if [ "$LAN" != "" ]; then
	[ $LAN -gt $MAX_NIC ] && \
		die "[ERROR] Use a maximum of $MAX_VM routers in your lab (Vbox don't support more than $MAX_NIC VNIC to a VM."
else
	LAN=0
fi

if [ $# -gt 0 ] ; then
	echo "$0: Extraneous arguments supplied"
	usage
fi

($HOSTONLY_NIC) && vbox_hostonly

#Count the number of available NIC

($HOSTONLY_NIC) && TOTAL_NIC=1 || TOTAL_NIC=0
TOTAL_NIC=$(( $TOTAL_NIC + $LAN )) || true
TOTAL_NIC=$(( $TOTAL_NIC + $NUMBER_VM - 1 )) || true
[ $TOTAL_NIC -gt $MAX_NIC ] && die "[ERROR] you can't have more than $MAX_NIC VNIC by VM"

if ! check_vm ${VM_TPL_NAME}; then
	if [ "$FILENAME" != "" ]; then
		check_image ${FILENAME}
		#Note: check_image will change the $FILENAME variable...
		create_template ${FILENAME}
	else
		die "[ERROR] You need to enter an image filename for creating the VM."
	fi
fi

build_lab
start_lab
