Leeon has asked for the wisdom of the Perl Monks concerning the following question:

hi everyone i have configured snmp on my cisco switch. i get the message :
iso.3.6.1.2.1.17.7.1.2.2.1.2.4091.100.49.80.27.64. 126 = INTEGER: 49
where : 4091 is a vlan 100.49.80.27.64.126 is mac address in decimical format INTEGER: 49 is physical port number. i want to output this information in following format: vlan = 4091 mac-address = 64:31:50:1b:40:7e port number = 9 i found net::mac for converting mac address dec to hex in perl and it worked. but i can not do others . anybody can help me ?

Replies are listed 'Best First'.
Re: SNMP Trap
by williams554 (Sexton) on Oct 25, 2011 at 11:10 UTC

    I'm not sure you are hitting the correct OID.
    I think what you want to do is snmpwalk.
    snmp trap is something the device sends you.

    <snip sorry>
    In my environment the access layer devices are just layer 2 devices.
    So I can't get from ip -> port number.

    I keep a history of ip -> mac addresses

    I run an old tool called arpwatch.
    ftp://ftp.ee.lbl.gov/arpwatch.tar.gz

    It it builds three files:
    first.txt ## this keeps track when it first saw a mac address.
    current.txt ##this shows the ip/mac it saw on the last run
    history.txt ##this show the hist of a mac address over time.

    head history.txt
    20091210/08:27 10.3.2.4 00:04:4E:60:C0:54
    20111025/00:30 10.3.2.3 00:0F:CB:A1:80:ED
    20100913/16:30 10.3.2.3 00:0F:CB:A1:80:ED
    20110623/12:30 10.3.2.5 00:14:22:F3:EC:45
    20091210/08:27 10.3.2.3 00:14:7C:4B:0C:00
    >>>snip...

    I then have to harvest cam tables from the switches and map to this data.

    I need the port they are on really fast. (rouge DHCP, dup address, etc)

    #!/usr/bin/perl -w use strict; ## sweep.pl ## program havest ethernet cam tables from a list switches contained ## in files in $switch_file_dir ## rev 1.1 ## 1.1 changes the ouput file, and fixes it to append, adds grep examp +le ## this line left blank #### # modules use Parallel::ForkManager; ### # global varibles my $rev = "1.1"; my $count=0; my $debug = 1; my $answer = "n"; my $switch_num_input =""; my @switchfiles_array = (); my $directory = "Data"; # directory for output my $max =50; # number of concurrent processes my %port_count_hash; my @bridgetable; ## switchfile is just a list of switches ## each building has a file in the dir Switchfiles/ ## building14 building 15... # witch the snmp read string ## switchfile example ## 192.168.1.10 public ## 192.168.1.15 public #get the list of switchfiles while ($answer =~ /^n/i ) { $count=0; @switchfiles_array =<Switchfiles/*>; &draw_line; &print_switchfiles (@switchfiles_array); &draw_line; print "(ver$rev)"; print "\t enter number?: "; chomp($switch_num_input = <STDIN>); print "\n\n"; die "please enter a number\n\n\n" unless $switch_num_input =~/\d+$ +/; die "number doesn't exist\n\n\n" unless $switchfiles_array[$switch +_num_input]; my $file_check = &remove_dir($switchfiles_array[$switch_num_input] +); print "\t\t-----> $file_check\n\n\n"; print "(y/n) ?: "; $answer = <STDIN>; } mkdir $directory, 0700 unless (-d "$directory"); &erase_directory ($directory); unlink "ether.txt"; my $switch_file = <$switchfiles_array[$switch_num_input]>; open FH , $switch_file; my @switch_file_lines = <FH>; close FH; print""; my $pm = new Parallel::ForkManager($max); $pm->run_on_finish( sub { my ($pid, $exit_code, $ident) = @_; } ); $pm->run_on_wait( sub { print "please hold....\n"; } ); foreach my $child(0..$#switch_file_lines) { my $pid=$pm->start($switch_file_lines[$child]) and next; #this co +de is the child process my $switches_line = $switch_file_lines[$child]; my @lines_array = split /\s+/, $switches_line; my $ip = $lines_array[0]; my $community = $lines_array[1]; my @bridgetable = `snmpwalk -Cc -c $community -v 1 $ip .1.3.6.1.2. +1.17.4.3.1.2`; # number of macs on each port foreach (@bridgetable) { chomp; my @bt_array = split /[\. ]/,$_; $port_count_hash{$bt_array[14]}++; } open(SWEEP_OUT,">>$directory/$ip"); foreach (@bridgetable) { my @bt_array = split /[\. ]/,$_; my $port_number = $bt_array[14]; printf SWEEP_OUT "%02x%02x%02x%02x%02x%02x",$bt_array[6],$bt_a +rray[7],$bt_array[8],$bt_array[9],$bt_array[10],$bt_array[11]; print SWEEP_OUT " $ip/$port_number" , " $port_count_hash{$port +_number} \n"; } $pm->finish($child) } print "child leaving pool\n"; $pm->wait_all_children; print "all child proccesses done.\n"; my @files = <$directory/*>; open SWEEP_OUT, ">>ether.txt"; foreach (@files){ open SWITCH_FH,"<$_"; my @all_lines = <SWITCH_FH>; foreach (@all_lines) { print SWEEP_OUT $_; } } &draw_line; print " \t You can search the file \"ether.txt\" with the command \"gr +ep\" \n"; print " \t Ethernet addresses are formatted like c42c032225a9\n"; print " \t example: grep 2225a9 ether.txt"; &draw_line; ######################## # subs sub remove_dir { $_ = shift @_; $_=~/^\S*\/(.*)/; # set after dir to $1 $_=$1; # remove leading dir without looking anything up :) + } sub draw_line { print "\n"; print "=" x60; print "\n"; } sub print_switchfiles { my @switchfiles_array = @_; foreach (@switchfiles_array) { $_ = &remove_dir ($_); print"$count. $_\n"; $count++; } } sub erase_directory { my $directory = shift @_; my @files = <$directory/*>; foreach (@files){ unlink "$_"; } }

    This is all based on the standard mib tree so depending on what you were after, this could work for you too.

    Good luck, Rob

      You may also want to have a look at the switchmap perl scripts.
Re: SNMP Trap
by JavaFan (Canon) on Oct 25, 2011 at 09:02 UTC
    i found net::mac for converting mac address dec to hex in perl and it worked. but i can not do others
    Call me confused, but since you only want to convert a single mac address from decimal to hex, and that already works according to the statement above, which "others" do you have a problem with?
Re: SNMP Trap
by Sewi (Friar) on Oct 25, 2011 at 10:31 UTC

    Try to cut down the message key in parts:

  • Cut off the prefix: s/^\Qiso.3.6.1.2.1.17.7.1.2.2.1.2.\E$//
  • Get the vlan: s/^(\d+)\.//
  • Get the MAC and convert it: join("-",map { unpack("H*",chr($_)) } split(/\./))
  • Remember: TIMTOWTDT

      thanks Sewi i try this code
      s/^\Qiso.3.6.1.2.1.17.7.1.2.2.1.2.\E$//
      but cannot get work . maybe i make wrong something. can you write an example in "foreach" ?