The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

#!/usr/bin/perl
use strict;
use lib './lib';
use setup;
use English qw(-no_match_vars);
my %types = (
1 => 'COMPUTER',
2 => 'NETWORKING',
3 => 'PRINTER',
4 => 'STORAGE',
5 => 'POWER',
6 => 'PHONE',
7 => 'VIDEO',
);
my $options = {
debug => 0,
threads => 1
};
GetOptions(
$options,
'model=s',
'type=s',
'host=s@',
'file=s@',
'community=s',
'credentials=s',
'port=s@',
'protocol=s@',
'threads=i',
'timeout=i',
'control',
'debug+',
'help',
'version',
) or pod2usage(-verbose => 0);
if ($options->{version}) {
my $PROVIDER = $FusionInventory::Agent::Version::PROVIDER;
map { print $_."\n" }
"NetInventory task $FusionInventory::Agent::Task::NetInventory::VERSION",
"based on $PROVIDER Agent v$FusionInventory::Agent::Version::VERSION",
@{$FusionInventory::Agent::Version::COMMENTS}
;
exit 0;
}
pod2usage(-verbose => 0, -exitval => 0) if $options->{help};
pod2usage(
-message => "no host nor file given, aborting\n", -verbose => 0
) unless $options->{host} or $options->{file};
warn "deprecated option model, ignoring\n" if $options->{model};
# Split host, port and protocol options on comma
foreach my $opt (qw(host port protocol)) {
$options->{$opt} = [ map { split(/\s*,\s*/, $_) } @{$options->{$opt} || []} ];
}
# Add hosts if --host option is not listing as much host as --file option is providing snmpwalk files
while ($options->{file} && @{$options->{file}} > @{$options->{host}}) {
push @{$options->{host}}, $options->{host}[0] || '127.0.0.1';
}
# Add as ports as set hosts, setting 0 will force to select the default SNMP port
while ($options->{host} && @{$options->{host}} > @{$options->{port}}) {
push @{$options->{port}}, $options->{port}[0] || 0;
}
# Add as protocols as set hosts, setting '' will force to select the default SNMP protocol
while ($options->{host} && @{$options->{host}} > @{$options->{protocol}}) {
push @{$options->{protocol}}, $options->{protocol}[0] || '';
}
my $id = 0;
my @devices;
if ($options->{file}) {
push @devices, {
ID => $id++,
FILE => $_,
IP => shift @{$options->{host}},
AUTHSNMP_ID => 1,
MODELSNMP_ID => 1
} foreach @{$options->{file}};
} else {
push @devices, {
ID => $id++,
IP => $_,
PORT => shift @{$options->{port}},
PROTOCOL => shift @{$options->{protocol}},
AUTHSNMP_ID => 1,
MODELSNMP_ID => 1
} foreach @{$options->{host}};
}
my $credentials = { ID => 1 };
if ($options->{type}) {
pod2usage(
-message => "invalid type '$options->{type}', aborting\n",
-verbose => 0
) unless any { $options->{type} eq $_ } values %types;
map { $_->{TYPE} = $options->{type} } @devices;
}
if ($options->{community}) {
$credentials->{COMMUNITY} = $options->{community};
} elsif (defined $options->{credentials}) {
foreach my $parameter (split(',', $options->{credentials})) {
my ($key, $value) = split(':', $parameter);
my $newkey =
$key eq 'authpassword' ? 'AUTHPASSPHRASE' :
$key eq 'privpassword' ? 'PRIVPASSPHRASE' :
uc($key);
$credentials->{$newkey} = $value;
}
} else {
$credentials->{COMMUNITY} = 'public';
}
my $inventory = FusionInventory::Agent::Task::NetInventory->new(
%setup,
target => FusionInventory::Agent::Task::NetInventory::Target->new(),
logger => FusionInventory::Agent::Logger->new(config => $options)
);
$inventory->{jobs} = [
FusionInventory::Agent::Task::NetInventory::Job->new(
params => {
PID => 1,
THREADS_QUERY => $options->{threads},
TIMEOUT => $options->{timeout},
},
devices => \@devices,
credentials => [ $credentials ]
)
];
$inventory->{client} =
FusionInventory::Agent::Task::NetInventory::Client->new(
control => $options->{control}
);
$inventory->run();
sub new {
my ($class, %params) = @_;
return bless {
control => $params{control}
}, $class;
}
sub send {
my ($self, %params) = @_;
# don't display control message by default
return unless $self->{control}
or $params{message}->{h}->{CONTENT}->{DEVICE};
print $params{message}->getContent();
}
## no critic (ProhibitMultiplePackages)
sub new {
my ($class) = @_;
return bless {}, $class;
}
sub getUrl {
my ($self, %params) = @_;
## no critic (ExplicitReturnUndef)
return undef;
}
__END__
=head1 NAME
fusioninventory-netinventory - Standalone network inventory
=head1 SYNOPSIS
fusioninventory-netinventory [options] [--host <host>|--file <file>]
Options:
--host <HOST> target host
--port <PORT[,PORT2]> SNMP port (161)
--protocol <PROT[,P2]> SNMP protocol/domain (udp/ipv4)
--file <FILE> snmpwalk output file
--community <STRING> community string (public)
--credentials <STRING> SNMP credentials (version:1,community:public)
--timeout <TIME> SNMP timeout, in seconds (15)
--type <TYPE> force device type
--threads <COUNT> number of inventory threads (1)
--control output control messages
--debug debug output
-h --help print this message and exit
--version print the task version and exit
=head1 DESCRIPTION
F<fusioninventory-netinventory> can be used to run a network inventory task without
a GLPI server.
=head1 OPTIONS
=over
=item B<--host> I<HOST>
Run an online inventory against given host. Multiple usage allowed, for
multiple hosts.
=item B<--port> I<PORT[,PORT2]>
List of ports to try, defaults to: 161
Set it to 161,16100 to first try on default port and then on 16100.
=item B<--protocol> I<PROTOCOL[,PROTOCOL2]>
List of protocols to try, defaults to: udp/ipv4
Possible values are: udp/ipv4,udp/ipv6,tcp/ipv4,tcp/ipv6
=item B<--file> I<FILE>
Run an offline inventory against snmpwalk output, stored in given file.
Multiple usage allowed, for multiple files.
=item B<--communty> I<STRING>
Use given string as SNMP community (assume SNMPv1)
=item B<--credentials> I<STRING>
Use given string as SNMP credentials specification. This specification is a
comma-separated list of key:value authentication parameters, such as:
=over
=item * version:2c,community:public
=item * version:3,username:admin,authprotocol:sha,authpassword:s3cr3t
=item * etc.
=back
=item B<--timeout> I<TIME>
Set SNMP timeout, in seconds.
=item B<--type> I<TYPE>
Force device type, instead of relying on automatic identification. Currently
allowed types:
=over
=item * COMPUTER
=item * NETWORKING
=item * PRINTER
=item * STORAGE
=item * POWER
=item * PHONE
=back
=item B<--threads> I<count>
Use given number of inventory threads.
=item B<--control>
Output server-agent control messages, in addition to inventory result itself.
=item B<--debug>
Turn the debug mode on. Multiple usage allowed, for additional verbosity.
=back
=head1 EXAMPLES
Run an inventory against a network device, using SNMP version 2c authentication:
$> fusioninventory-netinventory --host 192.168.0.1 \
--credentials version:2c,community:public
Run an inventory against a network device, using SNMP version 3 authentication
and forcing its type:
$> fusioninventory-netinventory --host my.device --type NETWORKING \
--credentials version:3,username:admin,authprotocol:sha,authpassword:s3cr3t