#!/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);