I have a lldp2dot script by sergiusk
I need to add functionality, but I cannot contact the author.
Currently the script can only process 1 subnet.
For example, 192.168.212.1-192.168.212.50
You need to be able to scan at least 2 subnets: 192.168.212.1-192.168.212.50 and 10.111.1.1-10.111.1.100 .

The script itself:

 #!/usr/bin/perl # Topology Discovery, lldp2dot for FTTB by SERGIUS, v2.6.1 beta use lib "./libs"; # use strict; # use warnings; use Net::SNMP; use SNMP_Session; use SNMP_util; use Net::Ping; use iptools; use threads; use threads::shared; use DateTime; my $ping=Net::Ping->new(); my %hosts:shared=(); my $maxThreads=100; my %lldpmapout = (); my $mgmtvlans; my $snmpcommunity = "xxxxxxxxxxx"; my %edges = (); my %edges2 = (); my %database = (); my %snmplldpnei_hash = (); my $i; my $edgesid = 0; my $edgesid2 = 0; # Объявляем переменные my $today = DateTime->now; # Определяем текущую дату my @scanRange=( "10.111.1.4-10.111.1.40" ); foreach my $rangeS (@scanRange) { my @range=split /-/,$rangeS; my $startIP=iptools::IPtodec($range[0]); my $endIP=iptools::IPtodec($range[1]); for (my $i=$startIP;$i<=$endIP;$i++) { $_->join() foreach (threads->list(threads::joinable)); if (threads->list(threads::all)>$maxThreads) { print "thread count > limit, joining\n"; while(threads->list(threads::all)>$maxThreads) { $_->join() foreach (threads->list(threads::joinable)); } } threads->create(\&pingDec,$i); } while(threads->list(threads::all)) { $_->join() foreach (threads->list(threads::joinable)); } foreach $iphost (keys %hosts) { print "get sysObjct.0 from $iphost... \n"; } foreach $iphost (keys %hosts) { my $snmpsession; my $snmperror; my $snmptemp; my $snmpsysobject; my $snmplocalmac; my $snmplocation; my $snmpsysname; my $snmpvid; my %snmptemp = (); my $request; my $id; my $sysobject; my $localmac; my $syslocation; my $sysname; my %snmpvlans = (); my $vlanid; my $snmploopback; my $fw; $syslocation = ""; $localmac = ""; $uptime = ""; $sysname = ""; my $firmware = ""; $sysobject = ""; $network = ""; $vlanid = ""; my $serial = ""; print "get sysObjct.0 from $iphost... "; my ($snmpsession, $snmperror) = Net::SNMP -> session( -timeout => 1, -retries => 1, -hostname => $iphost, -community => $snmpcommunity, -translate => [-timeticks => 0x0] ); #sysObject.0 my $snmptemp = $snmpsession->get_request('.1.3.6.1.2.1.1.2.0'); if (ref($snmptemp)) { my %snmpsysobjectid = %{$snmptemp}; foreach my $values (values %snmpsysobjectid) {$sysobjectid = $values;} #default $id = 0; # 1-99 tkd if($sysobjectid eq ".1.3.6.1.4.1.6486.800.1.1.2.2.4.1.1") {$id = 1;$sysobject = "Alcatel-Lucent OmniStack LS 6224";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.1.5") {$id = 2;$sysobject = "D-Link DES-3200-26";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.63.6") {$id = 3;$sysobject = "D-Link DES-3028";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.64.1") {$id = 4;$sysobject = "D-Link DES-3526";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.1.1") {$id = 5;$sysobject = "D-Link DES-3200-10";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.64.2") {$id = 6;$sysobject = "D-Link DES-3550";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.105.3") {$id = 7;$sysobject = "D-Link DES-3552";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.1.3") {$id = 8;$sysobject = "D-Link DES-3200-28";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.5.1") {$id = 9;$sysobject = "D-Link DES-3200-28-C1";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.1.2") {$id = 10;$sysobject = "D-Link DES-3200-18";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.1.4") {$id = 11;$sysobject = "D-Link DES-3200-28F";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.113.9.1") {$id = 12;$sysobject = "D-Link DES-3200-52";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.116.2") {$id = 13;$sysobject = "D-Link DES-1228/ME";} # 100-999 agg if($sysobjectid eq ".1.3.6.1.4.1.6486.800.1.1.2.1.7.1.10") {$id = 100;$sysobject = "Alcatel-Lucent OmniSwitch 6850-U24X";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.70.8") {$id = 101;$sysobject = "D-Link DGS-3627G";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.120.1") {$id = 101;$sysobject = "D-Link DGS-6604";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.101.1") {$id = 102;$sysobject = "D-Link DGS-3200-10";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.70.9") {$id = 103;$sysobject = "D-Link DGS-3612g";} if($sysobjectid eq ".1.3.6.1.4.1.207.1.4.149") {$id = 104;$sysobject = "Allied Telesis AT-9000/28SP";} if($sysobjectid eq ".1.3.6.1.4.1.171.10.117.1.3") {$id = 105;$sysobject = "D-Link DGS-3120-24SC";} # 1000-9999 ups if($sysobjectid eq ".1.3.6.1.4.1.2254.2.4") {$id = 1000;$sysobject = "Delta GES102R202035";} if($sysobjectid eq ".1.3.6.1.4.1.935") {$id = 1001;$sysobject = "EngPower EP901RH";} # 10000-99999 core if($sysobjectid eq ".1.3.6.1.4.1.9.1.402") {$id = 10000;$sysobject = "Cisco 7606 Chassis";} } else { $id = "-1"; print "fault, reason: wrong SNMP community or forbitten SNMP protocol "; } if($id eq 0){print "unknow net device ";} undef $snmptemp; if ($id >= 0) { #get MAC-adress $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.17.1.1.0"); $localmac = $snmptemp -> {".1.3.6.1.2.1.17.1.1.0"}; #get sysLocation.0 $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.1.6.0"); $syslocation = $snmptemp -> {".1.3.6.1.2.1.1.6.0"}; #get sysName.0 $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.1.5.0"); $sysname = $snmptemp -> {".1.3.6.1.2.1.1.5.0"}; #get VLAN $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.17.7.1.4.3.1.1"); $vlanid = $snmptemp -> {".1.3.6.1.2.1.17.7.1.4.3.1.1"}; # Take Loopback0 for aggregator if($id >= 100 && $id <= 999) { $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.14.1.1.0"); $snmploopback = $snmptemp -> {".1.3.6.1.2.1.14.1.1.0"}; $iphost = $snmploopback; } #LLDP nei %snmplldpnei_hash = %{$snmpsession -> get_table(".1.0.8802.1.1.2.1.4.1.1.5")}; my $snmpport; foreach $lldpneioid (keys %snmplldpnei_hash) { $lldpneioid =~ m/(\d{1,})(?=\.(\d{1,})$)/; if($id >=0 && $id <= 999) { $getport = ".1.3.6.1.2.1.31.1.1.1.1."."$&"; $snmptemp = $snmpsession -> get_request("$getport"); $portname = $snmptemp -> {"$getport"}; $edges{$edgesid} = { 'edgefrom'=>$localmac, 'edgeto'=>$snmplldpnei_hash{$lldpneioid}, 'port'=>$portname, }; $edgesid = $edgesid + 1; $lldpnei.= $portname."->".$snmplldpnei_hash{$lldpneioid}.","; } } if(defined($lldpnei)) { chop $lldpnei; } # take firmware for D-Link DES-3200-26 ... if ($id == 2 || $id == 5 || $id == 9 || $id == 10 || $id == 11 ) { $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.47.1.1.1.1.9.1"); $fw = $snmptemp -> {".1.3.6.1.2.1.47.1.1.1.1.9.1"}; } # take firmware for D-Link DES-3526 ... if ($id == 4) { $snmptemp = $snmpsession -> get_request(".1.3.6.1.2.1.16.19.2.0"); $fw = $snmptemp -> {".1.3.6.1.2.1.16.19.2.0"}; } } if(!defined($fw)) { $fw = ""; } if($id >=0 ) { print "$iphost;"; print "$localmac;"; print "$syslocation;"; print "$vlanid;"; print "$sysname;"; print "$id;"; print "$sysobject;"; print "$fw;"; if(!defined($lldpnei)) { $lldpnei = ""; } print "$lldpnei\n\n"; $database{$iphost}={ 'localmac'=>$localmac, 'syslocation'=>$syslocation, 'vlanid'=>$vlanid, 'sysname'=>$sysname, 'id'=>$id, 'sysobject'=>$sysobject, 'lldpnei'=>$lldpnei, 'fw'=>$fw, }; } undef $fw; undef $localmac; undef $syslocation; undef $vlanid; undef $sysname; undef $id; undef $sysobject; undef $lldpnei; } %hosts = (); } my $edgefrom; my $edgefrom2; my $edgeto; my $edgeto2; my $edge; my $edge2; my $port; my $port2; foreach $edge6(keys %edges) { $edgefrom6 = $edges{$edge6}{edgefrom}; $edgeto6 = $edges{$edge6}{edgeto}; $port6 = $edges{$edge6}{port}; print "$edge6 => $edgefrom6--$edgeto6;$port6\n"; } # delete full edges dublicate foreach $edge3(keys %edges) { $edgefrom3 = $edges{$edge3}{edgefrom}; $edgeto3 = $edges{$edge3}{edgeto}; $port3 = $edges{$edge3}{port}; if(defined($edgefrom3) & defined($edgeto3) & defined($port3)) { foreach $edge4(keys %edges) { $edgefrom4 = $edges{$edge4}{edgefrom}; $edgeto4 = $edges{$edge4}{edgeto}; $port4 = $edges{$edge4}{port}; if(defined($edgefrom4) & defined($edgeto4) & defined($port4)) { if($edgefrom3 eq $edgefrom4 & $edgeto3 eq $edgeto4 & $port3 eq $port4 & $edge3 ne $edge4) { delete $edges{$edge4}; } } } } } # combine edges and ports and delete dublicate foreach $edge(keys %edges) { my $port2; $edgefrom = $edges{$edge}{edgefrom}; $edgeto = $edges{$edge}{edgeto}; $port = $edges{$edge}{port}; foreach $edge2(keys %edges) { $edgefrom2 = $edges{$edge2}{edgefrom}; $edgeto2 = $edges{$edge2}{edgeto}; if(defined($edgefrom)) { if(defined($edgeto2)) { if($edgefrom eq $edgeto2) { if($edgeto eq $edgefrom2) { $port2 = $edges{$edge2}{port}; delete $edges{$edge2}; } } } } } if (defined($edgefrom) & defined($edgeto)) { if(defined($edge) & defined($edgefrom) & defined($edgeto) & defined($port) & defined($port2)) { print "$edge => $edgefrom--$edgeto;$port;$port2\n"; } if(!defined($port2)) { $port2 = ""; } $lldpmap.= "\"$edgefrom\" -- \"$edgeto\" [taillabel=\"$port\", headlabel=\"$port2\", labeldistance=\"8\", len=\"15\" ]\;\n"; } } foreach $iphost(keys %database) { $fw = $database{$iphost}{fw}; $syslocation = $database{$iphost}{syslocation}; $vlanid = $database{$iphost}{vlanid}; $sysname = $database{$iphost}{sysname}; $sysobject = $database{$iphost}{sysobject}; $id = $database{$iphost}{id}; $localmac = $database{$iphost}{localmac}; my @portmac = (); if($id >= 0 && $id <= 9999) { $label.="\"$database{$iphost}{localmac}\" [ label=\"$iphost\\n$syslocation\\n$sysobject\\n$sysname\\n$vlanid\", fillcolor=\"white\", shape=\"$shape\", ranksep=\"15\" ]\;\n"; } } open(lldp2dot,">mapdot.gv"); print lldp2dot "graph lldp2dot {\n\toverlap=scale;\n\tsplines=true;\n"; print lldp2dot "node [ shape=\"box\", fixedsize=\"false\", style=\"filled\", fillcolor=\"black\" ];\n"; print lldp2dot "graph [ fontname=\"Helvetica-Oblique\", fontsize=\"150\", label=\"Metro\", size=\"12\" ];\n"; print lldp2dot "edge [color=red];\n"; print lldp2dot $label; print lldp2dot $lldpmap; print lldp2dot "}"; close(lldp2dot); sub pingDec { my $iphost=iptools::dectoIP(shift); print "ping $iphost..."; if($ping->ping($iphost,0.500)) { $hosts{$iphost}=undef; print " success, save result, go to next host...\n"; } else { print " fault, save result, go to next host...\n"; } return 0; } # pdf #print "dot ==> generation PDF...\n"; #`dot -Tpdf -Gratio=auto -Ecolor=black -Ncolor=black -Goverlap=false -Gsize=20 mapdot.gv -o mapdot_06.08.13.pdf`; print "neato ==> generation PDF...\n"; `neato -Tpdf -Gratio=auto -Ecolor=black -Ncolor=black -Goverlap=false -Gsize=20 mapdot.gv -o mapneato_$today.pdf`; #print "fdp ==> generation PDF...\n"; #`fdp -Tpdf -Gratio=auto -Ecolor=black -Ncolor=black -Goverlap=false -Gsize=20 mapdot.gv -o mapfdp.pdf`; # svg # print "dot ==> generation SVG...\n"; # `dot -Tsvg -Gratio=auto -Ecolor=black -Ncolor=black -Goverlap=false -Gsize=10 mapdot.gv -o mapdot.svg`; print "neato ==> generation PS2...\n"; `neato -Tsvg -Gratio=auto -Ecolor=black -Ncolor=black -Goverlap=false -Gsize=20 mapdot.gv -o mapneato_$today.svg`; # print "fdp ==> generation SVG...\n"; # `fdp -Tsvg -Gratio=auto -Ecolor=black -Ncolor=black -Goverlap=false -Gsize=50 mapdot.gv -o mapfdp.svg`; 

I assume that the problem is in this piece:

 my @scanRange = ( "10.111.1.4-10.111.1.4, 10.101.1.6-10.101.1.6" ); foreach my $rangeS (@scanRange) { my @range = split /-/, $rangeS; my $startIP = iptools::IPtodec($range[0]); my $endIP = iptools::IPtodec($range[1]); for (my $i = $startIP; $i <= $endIP; $i++) { $_->join() foreach (threads->list(threads::joinable)); if (threads->list(threads::all) > $maxThreads) { print "thread count > limit, joining\n"; while (threads->list(threads::all) > $maxThreads) { $_->join() foreach (threads->list(threads::joinable)); } } threads->create(\&pingDec, $i); } while (threads->list(threads::all)) { $_->join() foreach (threads->list(threads::joinable)); } foreach $iphost (keys %hosts) { print "get sysObjct.0 from $iphost... \n"; } 
  • I'm not sure that here you can rewrite some particular piece - Izya12
  • Try replacing "10.199.1.4-10.199.1.4, 10.199.1.6-10.199.1.6" with "10.199.1.4-10.199.1.4", "10.199.1.6-10.199.1.6" . - Regent
  • I tried, does not help - Izya12
  • 1. You provided a link to the site, and registration is required there even for reading. this is probably not entirely correct. 2. at the very beginning, some ./libs , and you did not provide the source of this file (s) or the links to download them. this is probably not entirely correct. - aleksandr barakin
  • It helped !!! Thank! - Izya12

1 answer 1

 my @scanRange = ("10.111.1.4-10.111.1.4, 10.101.1.6-10.101.1.6"); 

is an array consisting of a single element (string). As a result, in foreach my $rangeS (@scanRange) will be only one iteration in which the lines "10.111.1.4" , "10.111.1.4, 10.101.1.6" and "10.101.1.6" .

While

 my @scanRange = ("10.111.1.4-10.111.1.4", "10.101.1.6-10.101.1.6"); 

will give an array of two elements, in each of which - one range.

  • It will be more convenient to write my @scanRange = qw/10.111.1.4-10.111.1.4 10.101.1.6-10.101.1.6/ . If there are a lot of subnets, you get tired of putting quotes, well, and something more perl-like or something. - andy.37
  • @ andy.37 I, by the way, have recently replaced many "pearl-barley" in the code with more familiar ones for Java and C # (without considering newfangled things like lambda expressions and LINQ). I think if there are many subnets, the author will get tired of writing them anyway). - Regent