[Tech] hostfind per tool php

mao.trash mao.trash@katamail.com
Mar 24 Lug 2007 10:53:45 CEST


 > ciao a tutti,

 > ho trovato questo interessante tool per la gestione degli apparati di 
 > rete:
 > http://www.cs.princeton.edu/patchmaker/

 > è fatto abbastanza bene anche se vecchio ormai di 2 anni, il problema
 > è che utilizza un comando (hostfind) che non riesco a reperire da
 > nessuna parte... non ho trovato nemmeno un esempio di output per
 > poterlo ricreare.

Ciao, anch'io sto cercando di far funzionare patchmaker e ho trovato su 
internet questo:
[ancora non sono riuscito a farlo funzionare, se ci riesco ri-posto]
Ciaooo
MaoX


#!/usr/local/bin/perl

require "getopts.pl" || die "\n\nrequire failed for getopts.pl: $!\n\n";

use Env;
use Socket;
use SNMP_util;
use strict;

$ENV{'PATH'} =~ s?^?/usr/local/bin:?;

$SNMP_Session::suppress_warnings = 2;

undef $ENV{MIBFILE};

####################
# Global Vars
####################

$main::debug = 0;
$main::defaultDomain = 'defaultdomain.edu';
$main::linkFile = '/usr/local/etc/switch.links';
%main::links;
$main::mrtgHost = 'mrtg.somehost.com';
$main::mrtgOutput = 0;
$main::mrtgBrowser = 0;
$main::numericOuptut = 0;
$main::PatchMakerOuptut = 0;
$main::opSys = '';
$main::rootSwitch = 'main';

my(@VLANS) = (1, 2, 3, 4);

my(%OID,%systemVendor,%systemProduct,%macAddr,%macSNMP);

####################
# Functions
####################

sub read_link_file {

  # Read in data from switch link file, so we know which
  # switch to query next.

  my($line,$srcPort,$destPort);
  open(LINKS,$main::linkFile) || die "cannot open link file: $!\n";
  while (<LINKS>) {
      chomp;
      next if (/^#/);
      next if (/^$/);
      $line = $_;
      $line =~ s/^[ \t]+//;
      ($srcPort,$destPort)=split(/[ \t]+/,$line);
      if (! $main::links{$srcPort}) {
          $main::links{$srcPort} = $destPort;
      } else {
          die "$srcPort listed twice in $main::linkFile\n";
      }
      if (! $main::links{$destPort}) {
          $main::links{$destPort} = $srcPort;
      } else {
          die "$destPort listed twice in $main::linkFile\n";
      }
  }
  close(LINKS);
}

#####

sub find_host {
  my($switch,$community,$host) = @_;

  # Walk the switch links looking for the switch that has
  # the target host on a non-link port.

  my($macAddr,$macSNMP) = &host2mac($host);

  print STDERR "checking $switch " if $main::debug;
  my($srcPort) = &enetport($switch,$community,$host);
  if (! $srcPort) {
      die("$host not found on $switch\n");
  }
  print STDERR "($srcPort)\n" if $main::debug;
  if ($main::links{"$switch:$srcPort"}) {
      my($nextSwitch,$nextPort) =
split(/:/,$main::links{"$switch:$srcPort"});
      if ($nextSwitch eq $host) {
          &enetportPrint($switch,$community,$host);
      } else {
          &find_host($nextSwitch,$community,$host);
      }
  } else {
      &enetportPrint($switch,$community,$host);
  }
}

#####

sub is_unreachable {
  my($targetHost) = @_;

  # Ping the host to prime the switch macAddress tables.

  if ($main::opSys eq "SunOS") {
      `/usr/sbin/ping $targetHost 1 > /dev/null 2>&1`;
  } elsif ($main::opSys eq 'Linux') {
      `/bin/ping -c 1 $targetHost > /dev/null 2>&1`;
  } else {
      `ping $targetHost 1 > /dev/null 2>&1`;
  }
  return($?);
}

#####

sub host2mac {
  my($host) = @_;

  my($MACADDRESS,$MACSNMP,@hexBytes,@snmpBytes,$byte);

  # Convert a (possible) host name to both a colon-hex
  # and dotted-decimal MAC address.

  $MACADDRESS = $host;
  if ($macAddr{$host} && $macSNMP{$host}) {
      return($macAddr{$host},$macSNMP{$host});
  } else {

      `ypmatch $MACADDRESS ethers.byname > /dev/null 2>&1`;
      if (! $?) {
          $MACADDRESS = `ypmatch $MACADDRESS ethers.byname | cut -f1`;
          chomp($MACADDRESS);
      }

      @hexBytes = split(/:/,$MACADDRESS);
      foreach $byte (@hexBytes) {
          push(@snmpBytes,hex($byte));
      }
      $MACSNMP = join('.',@snmpBytes),"\n";

      chomp($MACSNMP);
      $macAddr{$host} = $MACADDRESS;
      $macSNMP{$host} = $MACSNMP;
      return($MACADDRESS,$MACSNMP);
  }
}

#####

sub enetport($$$) {
  my($switch,$baseCOMMID,$host) = @_;

  my(@COMMIDS,$COMMID,$dot1dTpFdbPort,$dot1dBasePortIfIndex);
  my($FOUND) = 0;

  my($macAddr,$macSNMP) = host2mac($host);

  push(@COMMIDS, $baseCOMMID);
  my($vendor,$product) = &systemType($switch,$baseCOMMID);
  if (($product eq 'pePR5200')
      || ($product eq 'Switch3300')) {
      foreach (@VLANS) {
          push(@COMMIDS, "$baseCOMMID\@$_");
      }
  }
  foreach $COMMID (@COMMIDS) {
      ($dot1dTpFdbPort) =
&snmpget("$COMMID\@$switch","$OID{'dot1dTpFdbPort'}.$macSNMP");
      next unless ($dot1dTpFdbPort);
      if ($product eq 'pePR5200') {
          $dot1dBasePortIfIndex = $dot1dTpFdbPort;
      } else {
          ($dot1dBasePortIfIndex) =
&snmpget("$COMMID\@$switch","$OID{'dot1dBasePortIfIndex'}.$dot1dTpFdbPort");

      }
      next unless ($dot1dBasePortIfIndex);
      return($dot1dBasePortIfIndex);
  }
  return(0);
}

#####

sub enetportPrint($$$) {
  my($switch,$baseCOMMID,$host) = @_;

  my($null,@ipAddrs,$ipAddr);

  my($macAddr,$macSNMP) = host2mac($host);
  my($srcPort) = &enetport($switch,$baseCOMMID,$host);
  if (! $srcPort) {
      die("$host not found on $switch\n");
  }
  if ($main::numericOutput) {
      print "${switch}:${srcPort}\n";
  } elsif ($main::PatchMakerOutput) {
      ($null,$null,$null,$null,@ipAddrs) = gethostbyname($host);
      if ($ipAddrs[0]) {
          $ipAddr = join('.',unpack('C4',$ipAddrs[0]));
      }
      print "${macAddr},${ipAddr},${switch},${srcPort}\n";
  } elsif ($main::mrtgOutput) {
      print
"http://${main::mrtgHost}/perl/14all.cgi\?log=${switch}.${main::defaultDomain}_${srcPort}\&cfg=mrtg.${switch}.cfg\n";

  } elsif ($main::mrtgBrowser) {
      if ($ENV{'WWWBROWSER'}) {
              my($URL);
              $URL =
"http://${main::mrtgHost}/perl/14all.cgi\?log=${switch}.${main::defaultDomain}_${srcPort}\&cfg=mrtg.${switch}.cfg";

              print STDERR "launching \"$ENV{'WWWBROWSER'} -remote
'openURL($URL,new-window)'\"\n" if $main::debug;
              system("$ENV{'WWWBROWSER'} -remote
'openURL($URL,new-window)'");
      } else {
              die "WWWBROWSER environment variable is not defined\n";
      }
  } else {              my($vendor,$product) =
&systemType($switch,$baseCOMMID);
      my($ifDescr,$ifName,$ifAlias) =
&portNames($switch,$baseCOMMID,$srcPort);
      my($portSlash) = &portSlash($srcPort,$product);

      if ( $ifAlias ) {
          print "$macAddr found on $switch port $ifAlias ($srcPort)
$portSlash\n";
      } elsif ( $ifName ) {
          print "$macAddr found on $switch port $ifName ($srcPort)
$portSlash\n";
      } elsif ( $ifDescr ) {
          print "$macAddr found on $switch port $ifDescr ($srcPort)
$portSlash\n";
      } else {
          print "$macAddr found on $switch port $srcPort $portSlash\n";
      }
  }
}

#####

sub portSlash($$) {
  my($dot1dBasePortIfIndex) = shift;
  my($product) = shift;

  # Convert an interface number to slot/port or unit/port
  # notation, as needed.

  my($portSlash) = '';
  my($portPlusOffset,$unitPortNumber,$unitNumber);

  if ($product eq 'Switch') {
      $portPlusOffset = $dot1dBasePortIfIndex + 32;
      $unitPortNumber = $portPlusOffset % 32;
      $unitNumber = ( $portPlusOffset - $unitPortNumber ) / 32;
      $portSlash = "[$unitNumber/$unitPortNumber]";
  } elsif ($product eq 'Router') {
      $portPlusOffset = $dot1dBasePortIfIndex + 64;
      $unitPortNumber = $portPlusOffset % 64;
      $unitNumber = ( $portPlusOffset - $unitPortNumber ) / 64;
      $portSlash = "[$unitNumber/$unitPortNumber]";
  } else {
      if ( $dot1dBasePortIfIndex > 100 ) {
          $unitPortNumber = $dot1dBasePortIfIndex % 100;
          $unitNumber = ( $dot1dBasePortIfIndex - $unitPortNumber ) / 100;
          $portSlash = "[$unitNumber/$unitPortNumber]";
      }
  }
  return($portSlash);
}

#####

sub portNames($$$) {
  my($switch,$community,$ifNumber) = @_;

  # find any and all names for a given interface on a switch

  my($ifDescr) =
snmpget("$community\@$switch","$OID{'ifDescr'}.$ifNumber");
  my($ifName) = snmpget("$community\@$switch","$OID{'ifName'}.$ifNumber");
  my($ifAlias) =
snmpget("$community\@$switch","$OID{'ifAlias'}.$ifNumber");
  $ifName = '' if ($ifName eq 'XMIB2_NAME_STR'); # hack for Alcatel 6024
  return($ifDescr,$ifName,$ifAlias);
}

#####

sub systemType($$) {
  my($host) = shift;
  my($commID) = shift;

  # Use the sysObjectID to determine the Vendor and Product of
  # a device, and save the values in global hashes.  If we get
  # called again for a device we've already queried, return the
  # values from the hashes.

  my(@sysObjectID,$vendor,$product);

  if ($systemVendor{$host} && $systemProduct{$host}) {
      return($systemVendor{$host}, $systemProduct{$host});
  } else {

      @sysObjectID = &snmpget("$commID\@$host",'sysObjectID');
      for(@sysObjectID) {
          $vendor = '3com' if /^\Q1.3.6.1.4.1.43.\E/;
          $vendor = 'aironet' if /^\Q1.3.6.1.4.1.551.\E/;
          $vendor = 'apc' if /^\Q1.3.6.1.4.1.318.\E/;
          $vendor = 'alcatel' if /^\Q1.3.6.1.4.1.6486.\E/;
          $vendor = 'apple' if /^\Q1.3.6.1.4.1.762.\E/;
          $vendor = 'axis' if /^\Q1.3.6.1.4.1.368.\E/;
          $vendor = 'cisco' if /^\Q1.3.6.1.4.1.9.\E/;
          $vendor = 'foundry' if /^\Q1.3.6.1.4.1.1991.\E/;
          $vendor = 'hp' if /^\Q1.3.6.1.4.1.11.\E/;
          $vendor = 'intel' if /^\Q1.3.6.1.4.1.343.\E/;
          $vendor = 'netapp' if /^\Q1.3.6.1.4.1.789.\E/;
          $vendor = 'omnitronix' if /^\Q1.3.6.1.4.1.3052.\E/;
          $vendor = 'packetengines' if /^\Q1.3.6.1.4.1.3003.\E/;
          $vendor = 'pairgain' if /^\Q1.3.6.1.4.1.927.\E/;
          $vendor = 'portmaster' if /^\Q1.3.6.1.4.1.307.\E/;
          $vendor = 'sun' if /^\Q1.3.6.1.4.1.42.\E/;
          $vendor = 'tektronix' if /^\Q1.3.6.1.4.1.128.\E/;
          $vendor = 'xerox' if /^\Q1.3.6.1.4.1.253.\E/;
          $vendor = 'xylan' if /^\Q1.3.6.1.4.1.800.\E/;

          # Aironet
          $product = 'arlanAPE' if /^\Q1.3.6.1.4.1.551.2.1.76\E/;
          $product = 'arlanWGBE' if /^\Q1.3.6.1.4.1.551.2.1.123\E/;
          # Apple
          $product = 'airportBase' if /^\Q1.3.6.1.4.1.762.2\E/;
          # Alcatel/PE/Xylan
          $product = 'deviceOmniSwitch7800' if
/^\Q1.3.6.1.4.1.6486.800.1.1.2.1.1.1.2\E/;
          $product = 'omniStack6024' if /^\Q1.3.6.1.4.1.800.3.1.1.9\E/;
          $product = 'pePR5200' if /^\Q1.3.6.1.4.1.3003.2.2.2.1\E/;
          # Cisco
          $product = 'cisco7505' if /^\Q1.3.6.1.4.1.9.1.48\E/;
          # Foundry
          $product = 'snFES4802Router' if /^\Q1.3.6.1.4.1.1991.1.3.26.2\E/;
          # Intel
          $product = 'express510t' if /^\Q1.3.6.1.4.1.343.5.1.6\E/;
          # 3Com
          $product = 'linkSwitch1000' if /^\Q1.3.6.1.4.1.43.1.8.13\E/;
          # Xerox/Tektronix
          $product = 'xeroxN2125' if
/^\Q1.3.6.1.4.1.253.8.62.1.3.2.18.1\E/;

          # HP
          $product = 'hpJetDirect' if /^\Q1.3.6.1.4.1.11.2.3.9.1\E/;
      }
      $systemVendor{$host} = $vendor;
      $systemProduct{$host} = $product;
      return($vendor,$product);
  }
}

#####

sub map_my_OIDs {

# Bridge MIB OIDs
  snmpmapOID(
             'dot1dBasePort' ,                '1.3.6.1.2.1.17.1.4.1.1',
             'dot1dBasePortIfIndex',  '1.3.6.1.2.1.17.1.4.1.2',
             'dot1dTpFdbPort' ,               '1.3.6.1.2.1.17.4.3.1.2',
             'ifName' ,                       '1.3.6.1.2.1.31.1.1.1.1',
             'ifAlias' ,                      '1.3.6.1.2.1.31.1.1.1.18'
             );
  %OID = (
          'dot1dBasePort' ,           '1.3.6.1.2.1.17.1.4.1.1',
          'dot1dBasePortIfIndex',     '1.3.6.1.2.1.17.1.4.1.2',
          'dot1dTpFdbPort' ,          '1.3.6.1.2.1.17.4.3.1.2',
          'ifDescr' ,                 '1.3.6.1.2.1.2.2.1.2',
          'ifName' ,                  '1.3.6.1.2.1.31.1.1.1.1',
          'ifAlias' ,                 '1.3.6.1.2.1.31.1.1.1.18'
          );
}

####################
# MAIN PROGRAM
####################

$main::opt_r = "";                      # alternate root switch
$main::opt_d = 0;                       # debug mode
$main::opt_c = 'public';        # alternate SNMP Community ID
$main::opt_n = 0;                       # numeric (switch:port) output
$main::opt_p = 0;                       # PatchMaker output format
&Getopts("c:r:demMnp");

$main::debug = 1 if ($main::opt_d);
$main::numericOutput = 1 if ($main::opt_n);
$main::mrtgOutput = 1 if ($main::opt_m);
$main::mrtgBrowser = 1 if ($main::opt_M);
$main::PatchMakerOutput = 1 if ($main::opt_p);
$main::rootSwitch = $main::opt_r if ($main::opt_r);

if (! $ARGV[0]) {
  die "Usage: $0 [-denp] [-c community] [-r rootSwitch]  hostname |
enetAddr\n",
  "\t-d\tdebugging output\n",
  "\t-e\tuse hostname to lookup enetAddr (don't ping)\n",
  "\t-m\tmrtg URL output\n",
  "\t-M\tmrtg display in a browser window\n",
  "\t-n\t\"numeric\" output\n",
  "\t-p\tPatchMaker output\n";
}

$main::targetHost = $ARGV[0];

$main::opSys = `uname`;
chomp($main::opSys);

unless ($main::targetHost =~ /:/ || $main::opt_e) {
  if (is_unreachable($main::targetHost)) {
      die "$main::targetHost is unreachable\n";
  }
}
read_link_file;
map_my_OIDs;
find_host($main::rootSwitch,$main::opt_c,$main::targetHost);



Maggiori informazioni sulla lista flug-tech