### Local Variables: ***
### mode:perl ***
### comment-column:0 ***
### comment-start: "### " ***
### comment-end: "***" ***
### End: ***
#
# ****************DO NOT MOVE OR CHANGE LINES ABOVE THIS*********************
#
# The first set of lines runs perl from any shell. The second set of lines
# identifies the rest of the file as PERL for EMACS autoformatting.
# See end of copyright for more information.
#
#
# -------------------------------------------------------------------
# X-BONE
#
# http://www.isi.edu/xbone
# USC Information Sciences Institute (USC/ISI)
# Marina del Rey, California 90292, USA
# Copyright (c) 1998-2005
#
# -------------------------------------------------------------------
#
# Copyright (c) 1998-2005 by the University of Southern California.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and
# its documentation in source and binary forms for non-commercial
# purposes and without fee is hereby granted, provided that the above
# copyright notice appear in all copies and that both the copyright
# notice and this permission notice appear in supporting
# documentation, and that any documentation, advertising materials,
# and other materials related to such distribution and use acknowledge
# that the software was developed by the University of Southern
# California, Information Sciences Institute. The name of the
# University may not be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THE UNIVERSITY OF SOUTHERN CALIFORNIA MAKES NO REPRESENTATIONS ABOUT
# THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS SOFTWARE IS
# PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# Other copyrights might apply to parts of this software and are so
# noted when applicable.
#
# -------------------------------------------------------------------
#
# Effort partly sponsored by the Defense Advanced Research Projects
# Agency (DARPA) and Air Force Research Laboratory, Air Force Materiel
# Command, USAF, under agreement numbers F30602-98-1-0200 (X-Bone) and
# F30602-01-2-0529 (DynaBone). The views and conclusions contained
# herein are those of the authors and should not be interpreted as
# necessarily representing the official policies or endorsements,
# either expressed or implied, of the Defense Advanced Research
# Projects Agency (DARPA), the Air Force Research Laboratory, or the
# U.S. Government.
#
# This work was partly supported by the NSF STI-XTEND (ANI-0230789)
# and NETFS (ANI-0129689) projects. Any opinions, findings, and
# conclusions or recommendations expressed in this material are those
# of the authors and do not necessarily reflect the views of the
# National Science Foundation.
#
# -------------------------------------------------------------------
# $RCSfile: XB_Route.pm,v $
#
# $Revision: 1.71 $
# $Author: pingali $
# $Date: 2005/03/31 07:03:56 $
# $State: Exp $
# ----------------------------------------------------------------------------
#
# Primary Author: Amy Hughes
# This script is used in place of the unix 'route' command.
# It takes the same input as 'route'.
#
# usage:
# XXX - This needs to be fixed.
# add_route( [-net|-host], destinationIP, [-netmask mask],
# (gateway | -interface name))
# delete_route ([-net|-host], destinationIP, [-netmask mask])
# get_route ([-net|-host], destinationIP, [-netmask mask])
# Supported OS:
# FreeBSD (Default OS)
# Linux (modifications are marked)
package XB_Route;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw(add_route delete_route get_route init);
use strict;
use sigtrap;
use Fcntl;
use POSIX qw(:errno_h);
use File::Copy;
use Socket;
use IPC::Open3;
use Net::Netmask;
use Net::IP;
use XB_Log;
use XB_Params;
use IO::Select;
use XB_CiscoSSH;
my $log = 0;
my $module = "XB_Route::";
###########################################################################
#
# GENERAL CODE
#
###########################################################################
# Function:
# verify_input
# Used by: ALL
# Description:
# verify the route command
# Arguments:
# \%hash
# ( command => (add|delete|get)
# ovlname => <name>
# routing_method => (static|dynamic)
# family => (-inet|-inet6)
# dstarg => (-net|-host)
# destination => <ip address>
# netmask_opt => (-netmask|-prefixlen)
# netmask => (<netmask>|<prefix length>)
# gateway => <ip address>
# );
# Returns:
# 1 on success
# Exceptions:
# "XB_Route::add_route" on error, nothing to clean up by caller
sub verify_input($){
my ($inputhash) = @_;
my $proc = "verify_input";
XB_Log::log "info" => "-> $module$proc $inputhash";
eval {
# overlay
if (not defined $inputhash->{ovlname}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined overlayname ";
die "arg";
}
# command
if (not defined $inputhash->{command}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{command} ";
die "arg";
}
if (($inputhash->{command} ne "get") and
($inputhash->{command} ne "add") and
($inputhash->{command} ne "delete")){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Wrong command $inputhash->{command}";
die "arg";
}
# routing method
if (not defined $inputhash->{routing_method}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{routing_method} ";
die "arg";
}
if (($inputhash->{routing_method} ne "static") and
($inputhash->{routing_method} ne "dynamic")){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Wrong routing method $inputhash->{routing_method}";
die "arg";
}
# family
if (not defined $inputhash->{family}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{family} ";
die "arg";
}
if (($inputhash->{family} ne "-inet6") and
($inputhash->{family} ne "-inet")){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Wrong family $inputhash->{family}";
die "arg";
}
# dstarg
if (not defined $inputhash->{dstarg}){
XB_Log::log "err","Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{dstarg} ";
die "arg";
}
if (($inputhash->{dstarg} ne "-host") and
($inputhash->{dstarg} ne "-net")){
XB_Log::log "err","Unable to execute route commands. Consistency check failed." . "Wrong arg $inputhash->{dstarg}";
die "arg";
}
# destination
if (not defined $inputhash->{destination}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{destination} ";
die "arg";
}
my $n = new Net::IP($inputhash->{destination});
if (not defined $n){
XB_Log::log "err","Unable to execute route commands. Consistency check failed." . "Wrong $inputhash->{destination}";
die "arg";
}
# netmask option
if (not defined $inputhash->{netmask_opt}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{netmask_opt} ";
die "arg";
}
unless ((($inputhash->{family} eq "-inet6") and
($inputhash->{netmask_opt} eq "-prefixlen")) or
(($inputhash->{family} eq "-inet") and
($inputhash->{netmask_opt} eq "-netmask"))){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Inappropriate network mask - $inputhash->{netmask_opt}";
die "arg";
}
# netmask
if (not defined $inputhash->{netmask}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{netmask} ";
die "arg";
}
# dev_opt
if (defined $inputhash->{dev_opt}) {
if (($inputhash->{dev_opt} ne "-interface") and
($inputhash->{dev_opt} ne "dev")){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Wrong arg $inputhash->{dev_opt}";
die "arg";
}
if (not defined $inputhash->{dev}){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Undefined $inputhash->{dev} ";
die "arg";
}
if ($inputhash->{dev} =~ m/^(([a-zA-Z]+\d+)(:\d+)?)$/){
$inputhash->{dev} = $1;
} else {
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Wrong arg $inputhash->{dev}";
die "arg";
}
} elsif (defined $inputhash->{gateway}){
my $n = new Net::IP($inputhash->{gateway});
if (not defined $n){
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "Incorrect gateway $inputhash->{gateway}";
die "arg";
}
} else {
XB_Log::log "err", "Unable to execute route commands. Consistency check failed." . "No gateway or interface";
}
}; #eval
XB_Log::log "info" => "<- $module$proc $inputhash";
return 1 unless ($@);
if ($@ !~ /(arg)/){
XB_Log::log "err" => "Error: $@";
}
die "$module$proc";
}
###########################################################
# Exported API
###########################################################
# Function:
# add_route
# Used by: ALL
# Description:
# Add the given route
# Arguments:
# hash
# ( ovlname => <name>
# routing_method => (static|dynamic)
# family => (-inet|-inet6)
# dstarg => (-net|-host)
# destination => <ip address>
# gateway => <ip address>
# );
# Returns:
# 1 on success
# Exceptions:
# "XB_Route::add_route" on error, nothing to clean up by caller
sub add_route($) {
my($params) = @_;
my $static = 0; # corresponding lines
my $line;
my $proc = "add_route";
XB_Log::log "info" => "-> $module$proc $params";
eval {
my $cpid;
die ("Incorrect argument") if (not defined $params);
# parse the destination and specify the command.
my $dip = new Net::IP::XB_IP ($params->{destination});
if (not defined $dip){
XB_Log::log "err", "Unable to create routes. ".
"Received incorrect format: " . $params->{destination};
die "arg";
}
if ($dip->version() == 4) {
$params->{netmask_opt} = "-netmask";
$params->{netmask} = $dip->mask;
$params->{destination} = $dip->addr;
$params->{family} = "-inet";
} else {
$params->{netmask_opt} = "-prefixlen";
$params->{netmask} = $dip->masklen;
$params->{destination} = $dip->addr;
$params->{family} = "-inet6";
}
$params->{command} = "add";
if (not verify_input($params)){
XB_Log::log "err" => "Unable to create routes. Input could not be parsed";
die "parse";
}
if ($XB_Params::node_opts{os} =~ /cisco/i) {
# Cisco IOS
if ((defined($params->{gateway})) && ($params->{gateway} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
my @cmd = "ip route $params->{destination} $params->{netmask} $params->{gateway} \n exit \n";
XB_Log::log "debug", "Route comand on Cisco: @cmd";
$cpid = XB_CiscoSSH::cmd @cmd
or XB_Log::log "err" => "$!: Route command failed" and die "route";
}
}
elsif ((defined($params->{dev_opt})) && ($params->{dev_opt} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
my @cmd = ("ip route $params->{destination} $params->{netmask} $params->{dev_opt} \n exit \n");
$cpid = XB_CiscoSSH::cmd @cmd
or XB_Log::log "err" => "$!: Route command failed" and die "route"; }
else {
# netmask not provided. using a dummy netmask : 255.255.255.255,
# since CISCO IOS IP route command requires a netmask
my @cmd = ("ip route $params->{destination} 255.255.255.255 $params->{gateway} \n exit \n");
$cpid = XB_CiscoSSH::cmd @cmd
or XB_Log::log "err" => "$!: Route command failed" and die "route"; }
}
else {
XB_Log::log "err" => "No destination specified for route command" and
die "route";
}
}
elsif ($XB_Params::node_opts{os} =~ /linux/i) {
# Linux OS
my @cmd = (\*WTR, \*RDR, \*ERR,
"route", "-n", "add",
$params->{dstarg},
$params->{destination});
my @remaining = ();
if ((defined($params->{gateway})) && ($params->{gateway} ne "")) {
if (($params->{dstarg} !~ /host/) && (defined($params->{netmask})) && ($params->{netmask} ne "")) {
@remaining = ( "netmask", $params->{netmask},
"gw", $params->{gateway});
} else {
@remaining = ( "gw", $params->{gateway} );
}
} elsif ((defined($params->{dev_opt})) && ($params->{dev_opt} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
@remaining = ($params->{netmask_opt}, $params->{netmask},
$params->{dev_opt}, $params->{dev});
} else {
@remaining = ($params->{dev_opt}, $params->{dev});
}
}else {
XB_Log::log "err" => "Unable to create routes. No destination specified for route command" and
die "route";
}
# collected all the parameters. now, execute it.
$cpid = open3(@cmd, @remaining) or
XB_Log::log "err" => "Unable to create routes. $!: Route command failed" and die "route";
} else {
# Default OS (FreeBSD)
my @remaining = ();
my @cmd = ( \*WTR, \*RDR, \*ERR,
"route", "-n", "-q", "add",
$params->{family}, $params->{dstarg},
$params->{destination});
if ((defined($params->{gateway})) && ($params->{gateway} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
@remaining = ($params->{netmask_opt}, $params->{netmask},
$params->{gateway});
}else {
@remaining = ($params->{gateway});
}
} elsif ((defined($params->{dev_opt})) && ($params->{dev_opt} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
@remaining = ($params->{netmask_opt}, $params->{netmask},
$params->{dev_opt}, $params->{dev});
} else {
@remaining = ($params->{netmask_opt}, $params->{netmask},
$params->{dev_opt}, $params->{dev});
}
} else {
XB_Log::log "err" => "Unable to create routes. No destination specified for route command" and die "route";
};
#XB_Log::log "info" => "executing route command @cmd @remaining \n";
# now execute the command.
$cpid = open3(@cmd, @remaining) or
XB_Log::log "err" => "Unable to create routes. $!: Route command failed" and die "route";
}; # else
if ($XB_Params::node_opts{os} !~ /cisco/i) {
# check output from route and warn if not successful
my @route = <ERR>;
close WTR or XB_Log::log "err" => "Unable to cleanup after creating routes. Could not close: $!" and die "close_route";
close RDR or XB_Log::log "err" => "Unable to cleanup after creating routes. Could not close: $!" and die "close_route";
close ERR or XB_Log::log "err" => "Unable to cleanup after creating routes. Could not close: $!" and die "close_route";
if (defined $cpid) {
waitpid $cpid, 0 == $cpid or
XB_Log::log "err" => "Operating system resource error. ".
"Could not create a child process $cpid" and die "wait"; }
if (scalar @route) {
# error
XB_Log::log "err" => "Unable to create routers. Route command returned an error: @route"
and die "route"; }
else { return; } # no error
}
}; # eval block
XB_Log::log "info" => "<- $module$proc $params";
return 1 unless $@;
if ($@ =~ /^(parse|close_route|route|wait|make_backup|route_exists|
XB_CiscoSSH::cmd)/) {
XB_Log::log "err" => "$module$proc: caught error: $@";
# no cleanup
} elsif ($@ =~ /^(gopen|gduplicate|gclose|checkconf)/) {
XB_Log::log "err" => "$module$proc: caught error: $@";
} elsif ($@ =~ /^(gmove|grestart)/) {
XB_Log::log "err" => "$module$proc: caught error: $@";
} else {
XB_Log::log "warning" => "$module$proc caught unexpected exception $@";
}
die "$proc";
} # sub add_route($)
# Function:
# delete_route
# Used by: ALL
# Description:
# Deletes given route
# Arguments:
# %hash
# ( ovlname => <name>
# routing_method => (static|dynamic)
# family => (-inet|-inet6)
# dstarg => (-net|-host)
# destination => <ip address>
# netmask_opt => (-netmask|-prefixlen)
# netmask => (<netmask>|<prefix length>)
# gateway => <ip address>
# );
# Returns:
# 1 on success
# Exceptions:
# "XB_Route::delete_route" on error, nothing to clean up by caller
#
sub delete_route(@) {
my $proc = "delete_route";
my ($params) = @_;
XB_Log::log "info" => "-> $module$proc $params";
eval {
#just a sanity check. have to check the type instead.
if (not defined $params){
XB_Log::log "err" => "Unable to delete routes. Incorrect arguments";
die "parse";
}
# parse the destination and specify the command.
my $dip = new Net::IP::XB_IP ($params->{destination});
if (not defined $dip){
XB_Log::log "err" => "Unable to delete routes. Incorrect format: " .
$params->{destination};
die "parse";
}
if ($dip->version() == 4) {
$params->{netmask_opt} = "-netmask";
$params->{netmask} = $dip->mask;
$params->{destination} = $dip->addr;
$params->{family} = "-inet";
} else {
$params->{netmask_opt} = "-prefixlen";
$params->{netmask} = $dip->masklen;
$params->{destination} = $dip->addr;
$params->{family} = "-inet6";
}
$params->{command} = "delete";
if (not verify_input($params) ){
XB_Log::log "err" => "Input could not be parsed";
die "parse";
}
# This is the ugly hack for the Linux problem!!!!
my $cpid;
if ($XB_Params::node_opts{ os} =~ /cisco/i) {
# Cisco IOS
if ((defined($params->{gateway})) && ($params->{gateway} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
my @cmd = "no ip route $params->{destination} $params->{netmask} $params->{gateway} \n exit \n";
$cpid = XB_CiscoSSH::cmd @cmd or XB_Log::log "err" =>
"$!: Route command failed" and die "route";
}
}
elsif ((defined($params->{dev_opt})) && ($params->{dev_opt} ne "")) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
my @cmd = ("no ip route $params->{destination} $params->{netmask} $params->{dev_opt} \n exit \n");
$cpid = XB_CiscoSSH::cmd @cmd or XB_Log::log "err"
=> "$!: Route command failed" and die "route";
}
else {
# netmask not provided. using a dummy netmask : 255.255.255.255, since CISCO IOS IP route command requires a netmask
my @cmd = ("no ip route $params->{destination} 255.255.255.255 $params->{gateway} \n exit \n");
$cpid = XB_CiscoSSH::cmd @cmd or XB_Log::log "err" =>
"$!: Route command failed" and die "route";
}
}
else {
XB_Log::log "err" => "No destination specified for route command" and
die "route";
}
}
elsif ($XB_Params::node_opts{os} =~ /linux/i) {
# Linux OS
my @cmd = (\*WTR, \*RDR, \*ERR, "route", "-n", "del",
$params->{dstarg},
$params->{destination});
my @remaining = ();
if (($params->{dstarg} !~ /host/) && (defined($params->{netmask})) && ($params->{netmask} ne "")) {
@remaining = ( "netmask", $params->{netmask} );
};
$cpid = open3(@cmd, @remaining) or
XB_Log::log "err" => "Unable to delete routes. ".
"$!: Route command failed" and die "route";
} else {
# Default OS (FreeBSD)
my @cmd = (\*WTR, \*RDR, \*ERR, "route", "-n", "delete",
$params->{family}, $params->{dstarg},
$params->{destination});
my @remaining = ();
if ((defined($params->{netmask})) && ($params->{netmask} ne "")){
@remaining = ( $params->{netmask_opt}, $params->{netmask} );
};
$cpid = open3(@cmd, @remaining) or
XB_Log::log "err" => "Unable to delete routes. ".
"$!: Route command failed" and die "route";
}
if ($XB_Params::node_opts{os} !~ /cisco/i){
# check output from route and warn if not successful
my @route = <ERR>;
close WTR or
XB_Log::log "err" =>
"Unable to cleanup after deleting routes. Close failed: $!"
and die "close_route";
close RDR or
XB_Log::log "err" =>
"Unable to cleanup after deleting routes. Close failed: $!"
and die "close_route";
close ERR or
XB_Log::log "err" =>
"Unable to cleanup after deleting routes. Close failed: $!"
and die "close_route";
if (defined $cpid) {
waitpid $cpid, 0 == $cpid or
XB_Log::log "err" => "Operating system resource error. ".
"No child $cpid" and die "wait";
}
# NOTE: NO ERROR WHEN DELETING A NON-EXISTING ROUTE. NEED REVIEW!
#if (defined(@route)) {
### This is an ugly hack to avoid giving an error if the route
### didn't exist.
if (scalar @route and ($route[0] !~ m/No such process/i)) {
# error
XB_Log::log "err" => "route command returned an error: @route"
and die "route"; }
else { return; } # no error
}
}; # eval block
XB_Log::log "info" => "<- $module$proc $params";
return 1 unless $@;
if ($@ =~ /^(parse|close_route|route|wait|make_backup|checkconf|
XB_Cisco::cmd)/) {
XB_Log::log "err" => "$module$proc: caught error: $@";
# no cleanup
} elsif ($@ =~ /^(open|close)/) {
XB_Log::log "err" => "$module$proc: caught error: $@";
} elsif ($@ =~ /^(move|restart|checkconf)/) {
XB_Log::log "err" => "$module$proc: caught error: $@";
} else {
XB_Log::log "warning" => "$module$proc caught unexpected exception $@";
}
die "$module$proc $@";
} # sub delete_route(@)
# Function:
# get_route
# Used by: ALL
# Description:
# Retrieve configuration for given route
# Arguments:
# %hash =
# ( ovlname => <name>
# routing_method => (static|dynamic)
# family => (-inet|-inet6)
# dstarg => (-net|-host)
# destination => <ip address>
# netmask_opt => (-netmask|-prefixlen)
# netmask => (<netmask>|<prefix length>)
# gateway => <ip address>
# );
# Returns:
# 1 if route is configured
# 0 otherwise
# Exceptions:
# "XB_Route::get_route" on error, nothing to clean up by caller
#
sub get_route(@) {
my $proc = "get_route";
my (@args) = @_;
my $params;
XB_Log::log "info" => "-> $module$proc @args";
$params->{command} = "get";
if (not verify_input($params)){
XB_Log::log "err" => "Unable to obtain routes. Input could not be parsed";
die "parse";
}
my $get_route = 0;
$get_route = eval {
if ($XB_Params::node_opts{os} =~ /cisco/i) {
# Cisco IOS
my @cpid = "";
my $line;
my @cmd;
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
@cmd = ("show running-config | include ip route $params->{destination} $params->{netmask}");
@cpid = XB_CiscoSSH::show_cmd @cmd or XB_Log::log "err"
=> "$!: Route command failed" and die "route";
}
else {
@cmd = ("show running-configuration | include ip route $params->{destination}");
@cpid = XB_CiscoSSH::show_cmd @cmd
or XB_Log::log "err" => "$!: Route command failed" and die "route";
}
@cpid = split "\n", $cpid[1];
@cpid = split(" ", $cpid[0]);
if ($cpid[0] ne "") {
if ($cpid[2] eq $params->{destination}) {
if ((defined($params->{netmask})) && ($params->{netmask} ne "") &&
($cpid[3] eq $params->{netmask}))
{ return 1; }
else
{ return 1; }
}
}
else { return 0; }
}
elsif ($XB_Params::NODEOS =~ /linux|nist/i) {
# Linux OS (No "route get")
my $pipe = "route -n |";
open ROUTE, $pipe or
XB_Log::log "err" => "Unable to obtain routes. $!: Could not open pipe $pipe"
and die "route";
my $line;
while (defined($line = <ROUTE>)) {
my @line = split(" ", $line);
if ($line[0] eq $params->{destination}){
if (defined $params->{netmask}){
if ($line[2] eq $params->{netmask}){
return 1;
} else {
return 0;
}
} else {
return 1;
}
}
}
close ROUTE;
return 0;
} else {
# Default OS (FreeBSD)
my $cpid;
my @cmd = (\*WTR, \*RDR, \*ERR, "route", "-n", "get",
$params->{dstarg}, $params->{destination});
my @remaining = ();
if ((defined($params->{netmask})) && ($params->{netmask} ne "")) {
@remaining = ($params->{netmask_opt}, $params->{netmask});
}
open3(@cmd, @remaining) or
XB_Log::log "err" => "Unable to obtain routes. ".
"$!: Route command failed" and die "route";
if (defined(my $line = <ERR>)) {
close WTR or
XB_Log::log "err" => "Unable to cleanup after obtaining routes. Close failed: $!"
and die "close";
close RDR or
XB_Log::log "err" => "Unable to cleanup after obtaining routes. Close failed: $!"
and die "close";
close ERR or
XB_Log::log "err" => "Unable to cleanup after obtaining routes. Close failed: $!"
and die "close";
if (defined $cpid) {
waitpid $cpid, 0 == $cpid or
XB_Log::log "err" => "Operating system resource error. No child $cpid" and die "wait";
}
return 0;
} else {
while (defined(my $line = <RDR>)) {
if ($line =~ m/route to:/) {
# get "route to:" line and extract IP
$line =~ s/\s$//g;
my @line = split(':', $line);
my $goal = $line[1];
$goal =~ s/^\s*//;
# get "destination:" line and extract IP
$line = <RDR>;
$line =~ s/\s$//g;
@line = split(':', $line);
my $dest = $line[1];
$dest =~ s/^\s*//;
close WTR;
close RDR;
close ERR;
if (defined $cpid) {
waitpid $cpid, 0 == $cpid or
XB_Log::log "err" => "Operating system resource error. No child $cpid" and die "wait";
}
if ($goal eq $dest) { return 1; } # explicit route defined
else { return 0; } # uses default route
last;
}
} #while (defined(my $line = <ROUTE>))
}
} # else
}; # eval
XB_Log::log "info" => "<- $module$proc @args";
return $get_route unless $@;
if ($@ =~ /^(open|route|wait|close|XB_CiscoSSH::show_cmd)/){
XB_Log::log "err" => "$module$proc: caught error: $@";
} else {
XB_Log::log "warning" => "$module$proc caught unexpected exception $@";
}
die "$module$proc";
} # sub get_route(@)
# Description:
# Initialize the routing module. Call this *once* before using
# any function in here.
# Arguments:
# -
# Returns:
# -
# Exceptions:
# "XB_Route::init" on error, nothing to clean up by caller
sub init () {
}
1;
syntax highlighted by Code2HTML, v. 0.9.1