#!/usr/bin/perl 

use strict;
use IO::File;
use IO::Pipe;
use Getopt::Long;

# Commands to use below.  These all seem to be in the same place on FreeBSD and
# Lunix
my $TMCC = "/usr/local/etc/emulab/tmcc";
my $FINDIF = "/usr/local/etc/emulab/findif";
my $IFCONFIG = "/sbin/ifconfig";
my $ROUTE = "/sbin/route";

my $tmcc = new IO::Pipe || die "Can't create tmcc pipe: $!\n";	# To parse tmcc
my $interface;			# Interface with external address
my $ip;				# IP address of external interface
my $mac;			# MAC address
my $netmask;			# Netmask
my $router;			# Router for the internet
my $routedest;			# Add host route to this address (if given)
my $recordfile;			# Record interfaces
my $forceip;			# User overriddedn IP
my $forcemask;			# User overriddedn netmask

# Linux and FreeBSD use slightly different route syntax, so get the OS
my $os = `uname`;
chomp $os;

# Option parsing, --destination sets $routedest
GetOptions('destination=s' => \$routedest, "record=s" => \$recordfile,
    'forceip=s' => \$forceip, 'forcemask=s' => \$forcemask);

# Parse out the info about tunnelips
$tmcc->reader("$TMCC tunnelip");
while (<$tmcc>) {
    chomp;
    /TUNNELIP=([\d\.]*)/ && do { $ip = $1; };
    /TUNNELMASK=([\d\.]*)/ && do { $netmask = $1; };
    /TUNNELMAC=([[:xdigit:]]*)/ && do { $mac = $1; };
    /TUNNELROUTER=([\d\.]*)/ && do { $router = $1; };
}
$tmcc->close();

die "No MAC information for tunnel.\n" unless $mac;

# Let the user override the IP and mask if they know what they are doing.
$ip = $forceip if $forceip;
$netmask = $forcemask if $forcemask;

# Use the emulab findif command to get the right interface to configure
$interface = `$FINDIF $mac`;
chomp $interface;
die "Can't get interface for mac address $mac: $?" if $? || !$interface;

# Do the ifconfig
my @ifconfig = ($IFCONFIG, $interface, $ip);
push(@ifconfig, 'netmask', $netmask) if $netmask;

system(@ifconfig);
die join(" ", @ifconfig) . " failed: $!\n" if $?;

# Add the host route, if needed
if ($router) {
    if ($routedest ) {
	my @cmd;

	if ( $os =~ /^Linux/ ) { 
	    @cmd = ($ROUTE, 'add', $routedest, 'gw', $router);
	}
	elsif ( $os =~ /^FreeBSD/ ) {
	    @cmd = ($ROUTE, 'add', $routedest, $router);
	}
	else {
	    die "Unknown OS: $os\n";
	}
	system(@cmd);
	die join(" ", @cmd) . " failed: $?\n" if $?;
    }
}
else { warn "Destination but no router\n" if $routedest; }
if ($recordfile) {
    $netmask = "255.255.255.0" unless $netmask;
    my $rf = new IO::File(">>$recordfile") || 
	die "Can't open $recordfile:$!\n";
    print $rf "$ip:$interface:$mac:$netmask\n";
    $rf->close();
}
exit(0);
