#!/usr/bin/perl

# File: createscenario.pl
#
# This Script takes a file with the form
#
# ----------------------------------
# > net1,net2,net3,...
#
# > r1 net1,net2
# > r2 net2,net3
# ----------------------------------
# 
# Comments are whole lines that begin with #
# To change VNUML Settings just edit the variables $global, $net and $router
# 
# Input file must have suffix .zvf
#
# Call this script with
# ./createscenario.pl inputfile.zvf
# It creates a scenario inputfile in file inputfile.xml
# 
# Attention: No error-handling implemented

use strict;
use warnings;

my $filename = shift;
my $scenario = $filename;
$scenario =~ s/(.*?)\.zvf/$1/;

my $global="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE vnuml SYSTEM \"/usr/share/xml/vnuml/vnuml.dtd\">

<vnuml>
  <global>
    <version>1.8</version>
    <simulation_name>$scenario</simulation_name>
    <ssh_version>2</ssh_version>
	<ssh_key>/root/.ssh/id_rsa.pub</ssh_key>
    <automac/>
    <vm_mgmt type=\"private\" network=\"192.168.0.0\" mask=\"24\" offset=\"100\" >
       <host_mapping/>
    </vm_mgmt>
    <vm_defaults>
       <filesystem type=\"cow\">/usr/share/vnuml/filesystems/mini_fs</filesystem>
       <kernel>/usr/share/vnuml/kernels/linux</kernel>
    </vm_defaults>
  </global>\n";  

# the prefix 
# <net name="nameofnet"
# is added later
my $net=" mode=\"virtual_bridge\"/>";

# the start tag 
# <vm name="routername">
# and the nets are added later
my $router="\n<forwarding type=\"ipv4\" />

    <filetree root=\"/etc/quagga\" seq=\"start\">conf</filetree>
	  <exec seq=\"start\" type=\"verbatim\">sysctl -w net.ipv4.conf.all.rp_filter=0</exec>
      <exec seq=\"start\" type=\"verbatim\">hostname</exec>
      <exec seq=\"start\" type=\"verbatim\">/usr/lib/quagga/zebra -f /etc/quagga/zebra.conf -d</exec>
      <exec seq=\"rip\" type=\"verbatim\">/usr/lib/quagga/ripd -f /etc/quagga/ripd.conf -d</exec>
      <exec seq=\"ospf\" type=\"verbatim\">/usr/lib/quagga/ospfd -f /etc/quagga/ospfd.conf -d -P 2604</exec>
      <exec seq=\"stop\" type=\"verbatim\">hostname</exec>
      <exec seq=\"stop\" type=\"verbatim\">killall zebra</exec>
      <exec seq=\"stop\" type=\"verbatim\">killall ripd</exec>
      <exec seq=\"stop\" type=\"verbatim\">killall ospfd</exec>

  	  <exec seq=\"rpfilter\" type= \"verbatim\">
      for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > \$f; done
      </exec>
    </vm>\n\n";


# --------- program start -------------- #

open(FILE,"<$filename");
	my @lines=<FILE>;
close(FILE);

my $netline = "";
do {
	$netline = shift @lines;
} while ($netline =~ /^#/ || $netline =~ /^$/);

my @nets = split(",",$netline);

my $outfile = $global;
my %netuses = ();
foreach my $netname (@nets)
{
	chomp $netname;
	$outfile .= "<net name=\"$netname\"$net\n";
	$netuses{$netname} = 1;
}
$outfile .= "\n";

foreach my $line (@lines)
{
	next if(not($line =~ /r[0-9]+ .*/));
	next if($line =~ /^#/);

	my @actrouter = split(" ",$line);
	$outfile .= "<vm name=\"$actrouter[0]\">\n";
	my @netlist = split(",",$actrouter[1]);
	my $id=1;
	foreach my $rnet (@netlist)
	{
		$outfile .= "  <if id=\"$id\" net=\"$rnet\">\n";
		my $netnum = $rnet;
		$netnum =~ s/net([0-9]+)/$1/;
		$outfile .= "    <ipv4 mask=\"255.255.255.0\">10.0.$netnum.$netuses{$rnet}</ipv4>\n</if>\n";
		$netuses{$rnet}++;
		$id++;
	}
	$outfile .= $router;
}
$outfile .= "\n</vnuml>";

open(OUTFILE,">$scenario.xml");
print OUTFILE "$outfile\n\n";
close(OUTFILE);

