#! /usr/bin/perl # **** License **** # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program 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 # General Public License for more details. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. # All Rights Reserved. # # Author: Stephen Hemminger # Date: Novemember 2010 # Description: Script for show snmp ifmib # # **** End License **** use strict; use warnings; use Getopt::Long; use POSIX qw(strtol); # This is used to show values corresponding to to results IF-MIB. my %interfaces; sub show_ifindex { foreach my $ifname (@_) { my $info = $interfaces{$ifname}; my $ifindex = $info->{'ifIndex'}; printf "%s: ifIndex = %d\n", $ifname, $ifindex; } } sub show_ifalias { foreach my $ifname (@_) { my $info = $interfaces{$ifname}; my $ifalias = $info->{'ifAlias'}; printf "%s: ifAlias = %s\n", $ifname, defined($ifalias) ? $ifalias : $ifname; } } sub read_sysfs { my $filename = shift; open( my $f, '<', $filename ) or return; # not a PCI device my $val = <$f>; close $f; return strtol($val); } # Imitate code in net-snmp to lookup PC # TODO - move to common code extension (and handle USB?) sub pci_info { my $ifname = shift; my $vendor_id = read_sysfs("/sys/class/net/$ifname/device/vendor"); my $device_id = read_sysfs("/sys/class/net/$ifname/device/device"); return unless ( defined($vendor_id) && defined($device_id) ); my $cmd = sprintf("lspci -m -d %04x:%04x", $vendor_id, $device_id); open( my $pci, '-|', $cmd ) or die "Can't run $cmd"; my $info = <$pci>; close $pci; return unless $info; # extract vendor and device description from output $info =~ /^\S+ "[^"]*" "([^"]*)" "([^"]*)"/; return "$1 $2"; } sub show_ifdescr { foreach my $ifname (@_) { my $ifdescr = pci_info($ifname); printf "%s: ifDescr = %s\n", $ifname, defined($ifdescr) ? $ifdescr : $ifname; } } sub show_all { foreach my $ifname (@_) { my $info = $interfaces{$ifname}; my $ifindex = $info->{'ifIndex'}; my $ifalias = $info->{'ifAlias'}; my $ifdescr = pci_info($ifname); printf "%s: ifIndex = %d\n", $ifname, $ifindex; my $pad = sprintf( "%-*s", length($ifname) + 1, " " ); printf "%s ifAlias = %s\n", $pad, $ifalias if ($ifalias); printf "%s ifDescr = %s\n", $pad, $ifdescr if ($ifdescr); } } my $show = \&show_all; GetOptions( "ifindex" => sub { $show = \&show_ifindex }, "ifalias" => sub { $show = \&show_ifalias }, "ifdescr" => sub { $show = \&show_ifdescr }, ) or die "Unknown option\n"; # List of all interfaces that currently exist on system # includes interfaces that may be outside Vyatta CLI because # they still show up in SNMP open( my $ip, '-|', 'ip li' ) or die "Can't run ip command\n"; my $ifname; while (<$ip>) { if (/^(\d+): ([^:]*): /) { $ifname = $2; $interfaces{$ifname} = { 'ifIndex' => $1 }; } elsif (/^ +alias (.*)$/) { $interfaces{$ifname}->{'ifAlias'} = $1; } } close $ip; if (@ARGV) { $show->(@ARGV); } else { $show->( sort keys %interfaces ); }