2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-30 17:46:38 +00:00

Merge pull request #1307 from cxhong/1106

Add new subroutine and filter out disable networks for switchdiscover
This commit is contained in:
Xiaopeng Wang 2016-06-21 07:44:39 +08:00 committed by GitHub
commit afa26d2e86

View File

@ -14,6 +14,7 @@ use xCAT::NodeRange;
use xCAT::NetworkUtils;
use xCAT::Utils;
use xCAT::SvrUtils;
use xCAT::Table;
use XML::Simple;
no strict;
use Data::Dumper;
@ -33,12 +34,13 @@ my %global_switch_type = (
Juniper => "Juniper",
juniper => "Juniper",
Cisco => "Cisco",
cisco => "Cisco",
BNT => "BNT",
Blade => "BNT",
Mellanox => "Mellanox",
mellanox => "Mellanox",
MLNX => "Mellanox",
MELLAN => "Mellanox",
IBM => "BNT"
MELLAN => "Mellanox"
);
@ -683,6 +685,7 @@ sub nmap_scan {
my $switches;
my $found;
my $counter=0;
my $osguess_ips=[];
if ($result_ref) {
if (exists($result_ref->{host})) {
my $host_ref = $result_ref->{host};
@ -716,67 +719,8 @@ sub nmap_scan {
}
}
}
##########################################################
# If there is no vendor or other than %global_switch_type,
# issue the nmap again to do more aggresively discovery
# Choose best guess from osscan
# only search port 22 and 23 for fast performance
###########################################################
if ( ($found == 0) && ($type eq "mac") ) {
if (exists($globalopt{verbose})) {
send_msg($request, 0, "*********************************");
send_msg($request, 0, "Couldn't find vendor info, use nmap osscan command to choose best guess");
}
$ccmd = "/usr/bin/nmap -O --osscan-guess -A -p 22,23 -oX - $ip | grep osclass | grep -v embedded ";
if (exists($globalopt{verbose})) {
send_msg($request, 0, "Process command: $ccmd");
}
my $os_result = xCAT::Utils->runcmd($ccmd, 0);
if ($::RUNCMD_RC == 0)
{
if (exists($globalopt{verbose})) {
send_msg($request, 0, "$os_result\n");
}
my $os_vendor;
my @lines = split /\n/ => $os_result;
foreach my $line (@lines) {
# pick the first one if found osclass type = switch
if ($line =~ /switch/) {
if ($line =~ /vendor=\"(\S*)\"/) {
$os_vendor = $1;
last;
}
}
# if didn't find switch type, choose router as switch
if ($line =~ /router/) {
if ($line =~ /vendor=\"(\S*)\"/) {
if (!($os_vendor)) {
$os_vendor = $1;
}
}
}
}
if ($os_vendor) {
$switches->{$mac}->{ip} = $ip;
$switches->{$mac}->{vendor} = $os_vendor;
$switches->{$mac}->{name} = $host->{hostname};
$found = 1;
if (exists($globalopt{verbose})) {
send_msg($request, 0, "Choose best guess: ip=$ip, mac=$mac, vendor=$os_vendor");
send_msg($request, 0, "*********************************\n");
}
} else {
if (exists($globalopt{verbose})) {
send_msg($request, 0, "ip=$ip, mac=$mac is not switch");
send_msg($request, 0, "*********************************\n");
}
}
} else {
if (exists($globalopt{verbose})) {
send_msg($request, 0, "ip=$ip, mac=$mac is not switch");
send_msg($request, 0, "*********************************\n");
}
}
push(@$osguess_ips, $ip);
} # end nmap osscan command
} #end for each address
}
@ -784,9 +728,106 @@ sub nmap_scan {
}
}
return $switches
my $guess_switches = nmap_osguess($request, $osguess_ips);
foreach my $guess_mac ( keys %$guess_switches ) {
$switches->{$guess_mac}->{ip} = $guess_switches->{$guess_mac}->{ip};;
$switches->{$guess_mac}->{vendor} = $guess_switches->{$guess_mac}->{vendor};
}
return $switches;
}
##########################################################
# If there is no vendor or other than %global_switch_type,
# issue the nmap again to do more aggresively discovery
# Choose best guess from osscan
# only search port 22 and 23 for fast performance
###########################################################
sub nmap_osguess {
my $request = shift;
my $ranges = shift;
my $switches;
my $cmd;
if (exists($globalopt{verbose})) {
send_msg($request, 0, "Couldn't find vendor info, use nmap osscan command to choose best guess");
}
my $nmap_version = xCAT::Utils->get_nmapversion();
if (xCAT::Utils->version_cmp($nmap_version,"5.10") < 0) {
$cmd = "/usr/bin/nmap -O --osscan-guess -A -p 22,23 @$ranges | grep -E 'Interesting ports on|MAC Addres|Device|Running|Aggressive OS guesses' ";
} else {
$cmd = "/usr/bin/nmap -O --osscan-guess -A -p 22,23 @$ranges | grep -E 'Nmap scan report|MAC Addres|Device|Running|Aggressive OS guesses' ";
}
if (exists($globalopt{verbose})) {
send_msg($request, 0, "Process command: $cmd");
}
my $result = xCAT::Utils->runcmd($cmd, 0);
if (defined($globalopt{r}) || defined($globalopt{verbose})) {
send_msg($request, 0, "$result\n" );
}
if ($::RUNCMD_RC == 0)
{
my @lines;
if (xCAT::Utils->version_cmp($nmap_version,"5.10") < 0) {
@lines = split /Interesting ports /, $result;
} else {
@lines = split /Nmap scan /, $result;
}
foreach my $lines_per_ip (@lines) {
my @lines2 = split /\n/, $lines_per_ip;
my $isswitch=0;
my $ip;
my $mac;
my $vendor;
foreach my $line (@lines2) {
if ($line =~ /\b(\d{1,3}(?:\.\d{1,3}){3})\b/)
{
$ip = $1;
}
if ($line =~ /MAC Address/) {
my @array = split / /, $line;
$mac = $array[2];
}
if ( $line =~ /Device type/ ) {
if ( ( $line =~ /switch/) || ( $line =~ /router/) ) {
$isswitch=1;
} else {
last;
}
}
my $search_string = join '|', keys(%global_switch_type);
if ($line =~ /Running/) {
if ($line =~ /($search_string)/){
$vendor = $1;
last;
}
}
if ($line =~ /Aggressive OS/) {
if ($line =~ /($search_string)/){
$vendor = $1;
$isswitch=1;
}
}
}
if ($isswitch == 1) {
$switches->{$mac}->{ip} = $ip;
$switches->{$mac}->{vendor} = $vendor;
if (exists($globalopt{verbose})) {
send_msg($request, 0, "FOUND switch from osscan-guess: $ip, $mac, $vendor");
}
}
}
}
return $switches;
}
#--------------------------------------------------------------------------------
@ -811,14 +852,6 @@ sub snmp_scan {
my $switches;
my $counter = 0;
# snmpwalk command has to be available for snmp_scan
if (-x "/usr/bin/snmpwalk" ){
send_msg($request, 0, "Discovering switches using snmpwalk.....");
} else {
send_msg($request, 0, "snmpwalk is not available, please install snmpwalk command first");
return 1;
}
#################################################
# If --range options, take iprange, if noderange is defined
# us the ip addresses of the nodes. If none is define, use the
@ -826,14 +859,29 @@ sub snmp_scan {
##################################################
my $ranges = get_ip_ranges($request);
# snmpwalk command has to be available for snmp_scan
if (-x "/usr/bin/snmpwalk" ){
send_msg($request, 0, "Discovering switches using snmpwalk for @$ranges .....");
} else {
send_msg($request, 0, "snmpwalk is not available, please install snmpwalk command first");
return 1;
}
# handle ctrl-c
$SIG{TERM} = $SIG{INT} = sub {
#clean up the nmap processes
my $nmap_pid = `ps -ef | grep /usr/bin/nmap | grep -v grep | grep -v "sh -c" |awk '{print \$2}'`;
if ($nmap_pid) {
system("kill -9 $nmap_pid >/dev/null 2>&1");
exit 0;
}
};
##########################################################
#use nmap to parse the ip range and possible output from the command:
# Nmap scan report for switch-10-5-22-1 (10.5.22.1) 161/udp open snmp
# Nmap scan report for 10.5.23.1 161/udp open snmp
# Nmap scan report for 10.5.24.1 161/udp closed snmp
# Host 10.5.23.1 appears to be up ... good. 161/udp open|filtered snmp
# Host 10.5.24.1 appears to be up ... good. 161/udp closed snmp
##########################################################
my $nmap_version = xCAT::Utils->get_nmapversion();
if (xCAT::Utils->version_cmp($nmap_version,"5.10") < 0) {
@ -1163,14 +1211,26 @@ sub get_ip_ranges {
return \@ipranges;
}
# for default, use the subnets for all the live nics on the mn
my $nets = xCAT::NetworkUtils->my_nets();
# for default, use the subnets for all the enabled networks
# defined in the networks table.
my $ranges=[];
foreach my $net (keys %$nets) {
if ($net !~ /127\.0\.0\.0/) {
my $nettab = xCAT::Table->new('networks');
if ($nettab) {
my $netents = $nettab->getAllEntries();
foreach (@$netents) {
my $net = $_->{'net'};
my $nm = $_->{'mask'};
my $fnm = xCAT::NetworkUtils::formatNetmask($nm, 0 , 1);
$net .="/$fnm";
push(@$ranges, $net);
}
}
if (!@$ranges) {
send_msg($request, 1, "ip range is empty, nothing to discover" );
exit 0;
}
return $ranges;