You could get ARP info via Telnet or Web, but my preference is to get it via SNMP. Here is some code you can plagerize - lot of stuf you probably won't use, and you will need to remove database references, but it should get you a lot more than you wanted.

Sorry - Not the cleanest code -- I was still learning SNMP.

Concentrate on "sub ARPtable".

####################################################### ## Bridgemac.pl ## Queries the main routers for the ARP table ## Queries E7 and Vertical horizon switches for ## their Forwarding database (All Mac addresses). ## Stores info collected into the ARP table of the ## Hardware Database. ## The router ARP entries are queried for MAC <=> IP ## The Switch table gives Mac <=> Port/Switch info. ## All Equipment queries use SNMP. ## ## This is intended to run periodically as a scheduled ## job that updates the database. ## Database queries are done externally (Via web app) ## By Vijay Anand , March 2003 -Overhauled Sept2003 ########################################################### use strict; use Net::SNMP qw(:snmp); use DBInterface; # Vijay's homegrown DB module for Hardware Db my $session; my %SysInfo; # Contains {MaxPorts, manufacturer etc..}; my @FrontPorts; # Index by Maxports, gives last front-panel port numbe +r my @hosts=qw( ### Enter a list of Switch IP addresses here ......<<<<< ); ######################################### ### Program Starts ############# my $DB = DBInterface->new(); Query_Router_ARP_And_Update_DB('**IP address of ROUTER***'); foreach (@hosts){ Query_Switch_And_Update_DB($_); } # ARP tables may have changed or be incomplete # So run them again Query_Router_ARP_And_Update_DB('**IP address of ROUTER**'); print "--Closing DB--\n"; $DB = undef; # Close print "--end--\n"; ########################################### sub Query_Router_ARP_And_Update_DB{ &connect( host => shift, comm => shift || 'public'); my $ARPTable = ARPtable(); print "Got " . %{$ARPTable} . " arp entries from $session->{Hostname +}\n"; my %myrec; $DB->{REC} = \%myrec; ##$DB->verbose(1); foreach (sort keys %$ARPTable){ #print " $ARPTable->{$_} : $_\n"; $myrec{Mac} =$ARPTable->{$_}; $myrec{IP} = $_; $DB->Write_Rec(); } } ########################################### sub Query_Switch_And_Update_DB{ $session = undef; %SysInfo = {}; &connect( host => shift, comm => shift || 'public'); &Initial_Params; print "Front panel ports = $FrontPorts[$SysInfo{MaxPorts}]\n"; my ($fdb, $PortName) = &queryfdb(); # First, save this switch's Primary address my %myrec = ( Mac => $SysInfo{Mac} , IP => $SysInfo{Host} , User => '' , HostName =>$SysInfo{Host} , SwitchName => $SysInfo{Model} , SwitchPortIdx => 0, SwitchPortName => 'Internal', HostType => 'Switch' , Notes => $SysInfo{Manufacturer} , UpstreamID =>'' ); $DB->{REC} = \%myrec; my $SwitchRecId= $DB->Write_Rec(); for (my $port = 1;$port < @{$fdb}; $port++){ my $macs = $fdb->[$port] or next; $port > $FrontPorts[$SysInfo{MaxPorts}] and next; # Dont sho +w uplinks print "PORT $port $PortName->[$port] Macs= @$macs\n"; # $PortName->[$port] =~s/\s/_/g; # Db does not like spaces ? foreach (@$macs){ %myrec =( Mac=> $_, IP=> '' , User=> '' , HostName =>'' , SwitchName => $SysInfo{Host} , SwitchPortIdx => $port, ## SwitchPortName => $PortName->[$port], HostType => '' , Notes => '' , UpstreamID =>$SwitchRecId ); $DB->Write_Rec(); }#End For Each }#End For } # End Main Loop ################################################################# sub connect { my %cla = @_; $cla{comm} = "public" unless exists $cla{comm}; $session = Net::SNMP->session(Hostname => $cla{host}, Community => $cla{comm}); if (!defined($session)) { die "**SNMP Connect ERROR for %s: %s.\n",$_; } } ################################################################# sub Initial_Params{ my $sysUpTime ='1.3.6.1.2.1.1.3.0'; my $sysDescr =qq(1.3.6.1.2.1.1.1.0); #sy +stem.sysDescr.0 my $ifNumber = qq(1.3.6.1.2.1.2.1.0); my $dot1dStpTopChanges =qq(1.3.6.1.2.1.17.2.4.0); my $dot1dStpDesignatedRoot =qq(1.3.6.1.2.1.17.2.5.0); my $dot1dStpPortTable =qq(1.3.6.1.2.1.17.2.15); my $dot1dBaseNumPorts =qq(1.3.6.1.2.1.17.1.2.0); my $dot1dStpTimeSinceTopologyChange =qq(1.3.6.1.2.1.17.2.3.0); my $dot1dBaseBridgeAddress =qq(1.3.6.1.2.1.17.1.1.0); # Initialize Frontports to be the same as that reported for (my $i = 0; $i < 1024; $i++){ $FrontPorts[$i] = 999999; # View ALL ports, by default } # Now do the special cases .. $FrontPorts[26] = 24; # Vh2402 $FrontPorts[61] = 48; # 6h302-48 $FrontPorts[19] = 06; # 6G306-06 my $result = $session->get_request( -varbindlist => [$sysUpTime, $dot1dStpTopChanges, $sysD +escr, $dot1dStpDesignatedRoot, $dot1dBaseNumPo +rts, $dot1dStpTimeSinceTopologyChange, $dot1dBaseBridgeAddress,$ifNumber ]); if (!defined($result)) { die ("ERROR in initial request: %s.\n", $session->error); } #print( $session->hostname . " " . # &showinfo($session,"TC_count",$dot1dStpTopChanges) . # &showinfo($session,"rootBridge",$dot1dStpDesignatedRoot) +. # &showinfo($session,"ports",$dot1dBaseNumPorts) . # &showinfo($session,"TC_Time",$dot1dStpTimeSinceTopologyCh +ange) . # &showinfo($session,"This-BridgeMac", $dot1dBaseBridgeAddr +ess) . # &showinfo($session,"This-Bridge", $sysDescr) . # "\n" # ); $SysInfo{TCCount}= $session->var_bind_list()->{$dot1dStpTop +Changes}; $SysInfo{TCTime}= $session->var_bind_list()->{$dot1dStpTime +SinceTopologyChange}; $SysInfo{RootBridge} = $session->var_bind_list()->{$dot1dStpDes +ignatedRoot}; $SysInfo{RootBridge} =~ s/^0x//; # Zap the leading "0x" $SysInfo{MaxPorts}= $session->var_bind_list()->{$dot1dBaseNu +mPorts}; if ($session->var_bind_list()->{$ifNumber} != $SysInfo{MaxPorts +}){ print "**Problem: Number of Interfaces reported(" . $session->var_bind_list()->{$ifNumber} . ") Disagrees with number of Bridge ports($SysInfo{Ma +xPorts})\n" ; } $SysInfo{Mac}= $session->var_bind_list()->{$dot1dBaseBr +idgeAddress}; $SysInfo{Mac} =~ s/^0x//; # Zap the leading "0x" $SysInfo{Descr}=$session->var_bind_list()->{$sysDescr}; $SysInfo{Descr}=~ /([a-zA-Z ]+)\s.*\s([\w\-]*\d+[\w\-]*).*\s[V|R]E[V|R]\w*?\s +([\w\.\(\)]+)/iso; $SysInfo{Manufacturer} = $1; $SysInfo{Model} = $2; $SysInfo{Version} = $3; if (! $SysInfo{Manufacturer}){ # We did NOT get a Manufacturer - try to Re-parse for SSR, w +hich is like # 6SSRM/6C107 - Enterasys Networks Firmware Version: E9.0.7 +.0 PROM Version: prom- $SysInfo{Descr}=~m/(\S+)[\s-]+(\S+).*?\s[V|R]E[V|R][\w:]*?\s +([\w\.\(\)-]+)/iso; $SysInfo{Manufacturer} = $2; $SysInfo{Model} = $1; $SysInfo{Version} = $3; } $SysInfo{Host} = $session->hostname; # Vertical Horizon's dont report Manufacturer etc .. if ($SysInfo{Mac} =~m/^0001f4/ && $SysInfo{MaxPorts}== 26){ $SysInfo{Manufacturer} = "Enterasys (Guess based on Mac)"; $SysInfo{Model} = "VH2402"; $SysInfo{Version} = "No way of knowing"; } #SSR's report themselves differently if ($SysInfo{Descr} =~m/^6SSRM.*Version: (\w+)/){ $SysInfo{Manufacturer} = "Enterasys"; $SysInfo{Model} = "6SSRM/6C107"; $SysInfo{Version} = $1; } while (my ($k, $v) = each %SysInfo){ print " SYSTEM $k=$v;\n"; } } ################################################################# sub queryfdb { my ($key, $newkey); my @PortMacs; # An array of Array ref's my @PortDesc; # Description of each port my $dot1dBaseBridgeAddress = qq(1.3.6.1.2.1.17.1.1); my $dot1dBaseNumPorts = qq(1.3.6.1.2.1.17.1.2); my $dot1dTpFdbAddress = qq(1.3.6.1.2.1.17.4.3.1.1); my $dot1dTpFdbPort = qq(1.3.6.1.2.1.17.4.3.1.2); my $dot1dBasePortIfIndex = qq(1.3.6.1.2.1.17.1.4.1.2); my $ifName = qq(1.3.6.1.2.1.31.1.1.1.1); my $macref = $session->get_table($dot1dTpFdbAddress); $session->error and return {error => $session->error}; #foreach my $oid (oid_lex_sort(keys(%{$macref}))){ # print "OID $oid Mac " . $macref->{$oid} . "\n"; #} my $portref = $session->get_table($dot1dTpFdbPort); $session->error and return {error => $session->error}; my $portIfIndex = $session->get_table($dot1dBasePortIfIndex); $session->error and return {error => $session->error}; #foreach my $p (oid_lex_sort(keys(%{$portIfIndex}))){ # print " PORTIDX $p IFIDx " . $portIfIndex->{$p} . "\n"; #} my $PortNameRef = $session->get_table($ifName); $session->error and return {error => $session->error}; #foreach my $p (oid_lex_sort(keys(%{$PortNameRef}))){ # print " PORTNAME for Index $p Name=" . $PortNameRef->{$p} + . ";\n"; #} while (my($portkey,$port) = each %$portref) { ($newkey = $portkey) =~ s/$dot1dTpFdbPort\.//; # print "Pkey Port " . $portref->{$portkey} # #. " macKey $dot1dTpFdbAddress\.$newkey; Mac=" # . " mac " . $macref->{"$dot1dTpFdbAddress\.$newkey"} # . "\n"; $port > $FrontPorts[$SysInfo{MaxPorts}] and next; # Dont save +uplinks my $mac = $macref->{"$dot1dTpFdbAddress\.$newkey"}; length($mac) < 14 and next ; $mac =~ s/0x//; my $ifIndex = $portIfIndex->{$dot1dBasePortIfIndex . "\." . $p +ort}; ##$ifIndex == $port or print " IfIndex $ifIndex = Port $port + \n"; push @{$PortMacs[$ifIndex]}, $mac; $PortDesc[$ifIndex] =$PortNameRef->{$ifName . "\." . $ifIndex} +; } #print "**Port Count = " . scalar(%{$portref}) # . " Mac count = " . scalar(%{$macref}) # . " Portmac size=" . scalar(@PortMacs) # . "\n"; #for (my $i = 0; $i < @PortMacs; $i++) { # $PortMacs[$i] or next; # print "--Port $i MACS: @{$PortMacs[$i]} \n"; #} return (\@PortMacs, \@PortDesc); } ################################################################# sub showinfo(){ my ($session,$varname,$oid) = @_; my $format="%5d"; # Default format, if numeric my $val = $session->var_bind_list()->{$oid}; if (length($val)> 5 or $val > 9999){ return $varname . "=" . $val . "; "; } return $varname . "=" . sprintf("%6d", $val) . "; "; } ################################################################# ################################################################# sub ARPtable { my %MacbyIP; my $ifName = qq(1.3.6.1.2.1.31.1.1.1.1); my $ipNetToMediaNetAddress = qq(1.3.6.1.2.1.4.22.1.3); #Idx=Instanc +e, returns IP my $ipNetToMediaPhysAddress= qq(1.3.6.1.2.1.4.22.1.2); #Idx=Instanc +, Returns Mac my $ipNetToMediaIfIndex = qq(1.3.6.1.2.1.4.22.1.1); #Idx=Instanc +e, returns IFIdx my $ipNetToMediaEntry = qq(1.3.6.1.2.1.4.22.1); # Entire ARP t +able (Unused) my $ifIndex = qq(1.3.6.1.2.1.2.2.1.1); my $ifDescr = qq(1.3.6.1.2.1.2.2.1.2); my $ifPhysAddress = qq(1.3.6.1.2.1.2.2.1.6); my $IPref = &GetCleanTableRef($ipNetToMediaNetAddress); my $Macref= &GetCleanTableRef($ipNetToMediaPhysAddress, "^0x",""); # my $Portref=&GetCleanTableRef($ipNetToMediaIfIndex); # my $IfIdxref=&GetCleanTableRef($ifIndex); # my $IfDescref=&GetCleanTableRef($ifDescr); # my $IfEthAddrref=&GetCleanTableRef($ifPhysAddress); foreach my $idx (sort keys(%{$IPref})){ # my $desc = $IfDescref->{$IfIdxref->{$Portref->{$idx}}}; # $desc=~s/^IP interface: //; # print " Mac=" . $Macref->{$idx} . " len=" . length($Macref +->{$idx}) ##. " Eth=" . $IfEthAddrref->{$idx} # . " IP=" . $IPref->{$idx} # # . " Port=" . $Portref->{$idx} # # . " Desc=" . $desc # . "\n"; ##. " Idx=$idx\n"; if (length($Macref->{$idx}) > 11){ $MacbyIP{$IPref->{$idx}} = $Macref->{$idx}; } } return (\%MacbyIP); } ################################################################# sub GetCleanTableRef{ my $oid = shift; my ($subst_find, $subst_replacetext)=@_; my ($Tab, $NewTab, $newkey); $Tab = $session->get_table($oid); $session->error and die "Error getting $oid : " . $session->error; foreach my $idx (keys(%{$Tab})){ ($newkey = $idx) =~ s/$oid\.//; # print "OIDKey=$idx Info=" . $Tab->{$idx} . " New=$newkey\ +n"; $NewTab->{$newkey} = $Tab->{$idx}; $subst_find and $NewTab->{$newkey} =~s/$subst_find/$subst_r +eplacetext/; } return $NewTab; } #################################################################

    Earth first! (We'll rob the other planets later)


In reply to Re: using perl for arp collection by NetWallah
in thread using perl for arp collection by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.