if2port.in 6.02 KB
Newer Older
1
#!/usr/bin/perl -w
Leigh Stoller's avatar
Leigh Stoller committed
2 3

#
4
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Leigh Stoller's avatar
Leigh Stoller committed
24
#
25
use Getopt::Std;
26 27
use strict;

28 29 30 31 32 33 34 35 36 37 38
use lib "@prefix@/lib";
use libdb;

#
# if2port - Given an interface (specified as node[:card]), find the
# port on the switches that it's connected to. With the -v switch, gives
# some human-readable information to help in following wires and diagnosing
# problems.
#

#
39 40
# IMPORTANT: This file contains some information specific to the Utah
# Network Testbed! If you want to use it in another enviroment, change
41
# the information below (%switches, %cards, %wires)
42

43
#
44 45
# Describes the location of each of the switches that nodes may be
# connected to.
46
#
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
my %switches = ( cisco1 => 'pc850 cluster top right',
		 cisco2 => 'pc840 cluster bottom right',
		 cisco3 => 'pc850 cluster top middle',
		 cisco4 => 'pc850 cluster top left',
		 cisco5 => 'pc3000 cluster top left',
		 cisco6 => 'pc3000 cluster bottom left',
		 cisco8 => 'pc3000 cluster top right',
		 procurve1 => 'd710 cluster middle right',
		 procurve2 => 'd710 cluster bottom right',
		 procurve3 => 'd710 cluster top right',
		 procurve4 => 'd710 cluster top left',
		 procurve5 => 'd710 cluster middle left',
		 apcon1 =>    'd710 cluster bottom left',
		 arista1 =>   'd820 cluster top right'
);
62

63
#
64 65
# Description of the location of each chard on the back of a machine.
# A hash, indexed by node type. Each value is an array reference, ordered
66
# by the card order in the database.
67
#
68 69 70 71
my %cards = ( 'pc600' => [ 'second from left','third from left',
                          'second from right','rightmost','leftmost' ],
	      'pc850' => [ 'left port of dual card', 'right port of dual card',
	      		   'bottom builtin port', 'top builtin port',
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
			   'single port card' ],
	      'pc2000' =>[ 'bottom single', 'top right', 'top left',
			   'middle right', 'middle left' ],
	      'pc3000' =>[ 'builtin right', 'builtin left',
			   'top left', 'top right',
			   'bottom left', 'bottom right' ],
	      'd710'  => [ 'builtin leftmost', 'builtin second from left',
			   'builtin second from right', 'builtin rightmost',
			   'dual card left port', 'dual card right port' ],
	      'd820'  => [ 'builtin leftmost', 'builtin second from left',
			   'builtin second from right', 'builtin rightmost',
			   'left port of top 10G dual card',
			   'right port of top 10G dual card',
			   'left port of bottom 10G dual card',
			   'right port of bottom 10G dual card' ]
 );
88 89 90 91 92

# Colors of wires, indexed by wire type
my %wires = ( Node => 'yellow', Control => 'red', Power => 'green',
	Serial => 'white' );

93
# Options: v = verbose, d = debug, m = show mac
94
my %opt = ( v => 0, d => 0, m => 0, I => 0);
95

96
getopts('vdmI',\%opt);
97
$opt{m} = 0 if ($opt{v});
98 99


100 101
if (@ARGV < 1) {
	exit &usage;
102 103
}

104
while (my $arg = shift @ARGV) {
105
	my ($node,$iface) = split /:/,$arg;
106
	&debug("Node is $node");
107
	&debug("iface is $iface") if (defined $iface);
108

109 110
	printf("\n%9s %9s %5s%s%s %9s %9s %5s %5s %5s %3s %7s %7s\n",
	       "nodeid1", "iface1", "card1",
111 112
	       $opt{I} ? "              IP" : "",
	       $opt{m} ? "          MAC" : "",
113 114
	       "nodeid2", "iface2", "card2", "port2", "cable", "len", "wtype",
	       "ntype");
115

116
	my $query;
117
	my $ix = 0;
118 119
	if ($opt{m} || $opt{I}) {
	    $query = "SELECT w.node_id1,w.card1,";
120 121 122 123 124 125 126 127
	    if ($opt{I}) {
		$query .= "i.IP,";
		$ix++;
	    }
	    if ($opt{m}) {
		$query .= "i.mac,";
		$ix++;
	    }
128 129
	    $query .= "w.node_id2,w.card2,w.port2,w.cable,w.len,w.type,".
		"  n.type,w.iface1,w.iface2 ".
130
		" FROM wires AS w,nodes AS n,interfaces AS i".
131 132
		" WHERE w.node_id1=n.node_id AND ".
		"       w.node_id1=i.node_id AND w.iface1=i.iface";
133 134
	} else {
	    $query = "SELECT w.node_id1,w.card1,w.node_id2,w.card2,w.port2,".
135
		"w.cable,w.len,w.type,n.type,w.iface1,w.iface2 ".
136
		"FROM wires AS w,nodes AS n WHERE w.node_id1=n.node_id";
137 138
	}
	$query .= " AND node_id1='$node'";
139 140
	if (defined $iface) {
	    $query .= " AND iface1='$iface'";
141
	}
142

143
	&debug("Sending query $query\n");
144 145

	my $result = DBQueryFatal($query);
146 147

	if ($opt{v}) {
148 149 150 151 152 153
	    while (my @row = $result->fetchrow) {
		my $cardinfo;
		if (exists($cards{$row[8+$ix]})) {
		    $cardinfo = ${$cards{$row[8+$ix]}}[$row[1]];
		} else {
		    $cardinfo = "";
154
		}
155 156 157 158 159 160
		my $switchinfo = $switches{$row[2+$ix]};
		$switchinfo = "" if (!$switchinfo);
		my $wireinfo = $wires{$row[7+$ix]};
		$wireinfo = "black"
		    if ($row[2+$ix] eq "arista1" && $wireinfo eq "yellow");
		$row[5] = "0" if (!defined($row[5+$ix]));
161
		print "$row[0] $row[9+$ix] port $row[1] ($cardinfo) ".
162 163 164 165
		    "connects to $row[2+$ix] ($switchinfo), ".
		    "module $row[3+$ix], port $row[4+$ix] via ".
		    "wire #$row[5+$ix] (length $row[6+$ix], color $wireinfo)\n";
	    }
166
	} else {
167 168
	    while (my @row = $result->fetchrow) {
		my $i = 0;
169
		$row[5+$ix] = "0" if (!defined($row[5+$ix]));
170
		printf("%9s %9s %5d", $row[$i++], $row[9+$ix], $row[$i++]);
171 172 173 174
		printf("%16s", $row[$i++])
		    if ($opt{I});
		printf(" %12s", $row[$i++])
		    if ($opt{m});
175 176
		printf(" %9s %9s %5d %5d %5d %3d %7s %7s\n",
		       $row[$i++], $row[10+$ix], $row[$i++], $row[$i++], $row[$i++],
177 178
		       $row[$i++],$row[$i++],$row[$i++]);
	    }
179 180
	}
}
181

182
sub debug { warn @_,"\n" if $opt{d}; }
183 184

sub usage {
185
	print "Usage: $0 [-vdm] <node | node:ethNNN> ... \n";
186 187
	print "-v: Verbose, prose, output\n";
	print "-d: Enable debugging output\n";
188
	print "-m: Show MAC addresses\n";
189
	print "-I: Show any assigned IP addresses\n";
190 191
	return -1;
}