149 lines
3.6 KiB
Perl
149 lines
3.6 KiB
Perl
#!/usr/bin/perl
|
|
# (c) Ártica ST 2016 <info@artica.es>
|
|
# Utility functions for the network topology discovery modules.
|
|
|
|
package PandoraFMS::Recon::Util;
|
|
use strict;
|
|
use warnings;
|
|
|
|
# Default lib dir for RPM and DEB packages.
|
|
use lib '/usr/lib/perl5';
|
|
|
|
use Socket qw/inet_aton/;
|
|
|
|
our @ISA = ("Exporter");
|
|
our %EXPORT_TAGS = ( 'all' => [qw( )] );
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
|
our @EXPORT = qw(
|
|
enterprise_new
|
|
ip_to_long
|
|
mac_matches
|
|
mac_to_dec
|
|
parse_mac
|
|
subnet_matches
|
|
);
|
|
|
|
################################################################################
|
|
# Return an Enterprise Recon object.
|
|
################################################################################
|
|
sub enterprise_new($$) {
|
|
my ($class, $arguments) = @_;
|
|
|
|
my @args;
|
|
if (ref($arguments) eq "HASH") {
|
|
@args = %{$arguments};
|
|
}
|
|
if (ref($arguments) eq "ARRAY") {
|
|
@args = @{$arguments};
|
|
}
|
|
|
|
# Try to load the module
|
|
if ($^O eq 'MSWin32') {
|
|
# If the Windows service dies the service is stopped, even inside an eval ($RUN is set to 0)!
|
|
eval 'local $SIG{__DIE__}; require '.$class.';';
|
|
}else {
|
|
eval 'require '.$class.';';
|
|
}
|
|
if ($@) {
|
|
# Not loaded.
|
|
return undef;
|
|
}
|
|
|
|
return new $class(@args);
|
|
}
|
|
|
|
|
|
################################################################################
|
|
# Return the numeric representation of the given IP address.
|
|
################################################################################
|
|
sub ip_to_long($) {
|
|
my $ip_address = shift;
|
|
|
|
return unpack('N', inet_aton($ip_address));
|
|
}
|
|
|
|
################################################################################
|
|
# Returns 1 if the two given MAC addresses are the same.
|
|
################################################################################
|
|
sub mac_matches($$) {
|
|
my ($mac_1, $mac_2) = @_;
|
|
|
|
if (parse_mac($mac_1) eq parse_mac($mac_2)) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
################################################################################
|
|
# Convert a MAC address to decimal dotted notation.
|
|
################################################################################
|
|
sub mac_to_dec($) {
|
|
my $mac = shift;
|
|
|
|
my $dec_mac = '';
|
|
my @elements = split(/:/, $mac);
|
|
foreach my $element (@elements) {
|
|
$dec_mac .= unpack('s', pack 's', hex($element)) . '.';
|
|
}
|
|
chop($dec_mac);
|
|
|
|
return $dec_mac;
|
|
}
|
|
|
|
################################################################################
|
|
# Make sure all MAC addresses are in the same format (00 11 22 33 44 55 66).
|
|
################################################################################
|
|
sub parse_mac($) {
|
|
my ($mac) = @_;
|
|
|
|
# Remove leading and trailing whitespaces.
|
|
$mac =~ s/(^\s+)|(\s+$)//g;
|
|
|
|
# Replace whitespaces and dots with colons.
|
|
$mac =~ s/\s+|\./:/g;
|
|
|
|
# Convert hex digits to uppercase.
|
|
$mac =~ s/([a-f])/\U$1/g;
|
|
|
|
# Add a leading 0 to single digits.
|
|
$mac =~ s/^([0-9A-F]):/0$1:/g;
|
|
$mac =~ s/:([0-9A-F]):/:0$1:/g;
|
|
$mac =~ s/:([0-9A-F])$/:0$1/g;
|
|
|
|
return $mac;
|
|
}
|
|
|
|
################################################################################
|
|
# Returns 1 if the given IP address belongs to the given subnet.
|
|
################################################################################
|
|
sub subnet_matches($$;$) {
|
|
my ($ipaddr, $subnet, $mask) = @_;
|
|
my ($netaddr, $netmask);
|
|
|
|
# Decimal dot notation mask.
|
|
if (defined($mask)) {
|
|
$netaddr = $subnet;
|
|
$netmask = ip_to_long($mask);
|
|
}
|
|
|
|
# CIDR notation.
|
|
else {
|
|
($netaddr, $netmask) = split('/', $subnet);
|
|
return 0 unless defined($netmask);
|
|
|
|
# Convert the netmask to a numeric format.
|
|
$netmask = -1 << (32 - $netmask);
|
|
}
|
|
|
|
if ((ip_to_long($ipaddr) & $netmask) == (ip_to_long($netaddr) & $netmask)) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
1;
|
|
__END__
|
|
|