1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
|
###############################################################################
## Copyright 2005-2016 OCSInventory-NG/OCSInventory-Server contributors.
## See the Contributors file for more details about them.
##
## This file is part of OCSInventory-NG/OCSInventory-ocsreports.
##
## OCSInventory-NG/OCSInventory-Server is free software: you can redistribute
## it and/or modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation, either version 2 of the License,
## or (at your option) any later version.
##
## OCSInventory-NG/OCSInventory-Server is distributed in the hope that it
## will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with OCSInventory-NG/OCSInventory-ocsreports. if not, write to the
## Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
## MA 02110-1301, USA.
################################################################################
# This core module is used to guide you through the module creation
# All modules using modperl api functions must use the wrappers defined in MODPERL1 or 2 .pm
# or create a new one in these 2 files if you need to use something that is not wrapped yet
package Apache::Ocsinventory::Server::Capacities::Snmp;
use XML::Simple;
use strict;
# This block specify which wrapper will be used ( your module will be compliant with all mod_perl versions )
BEGIN{
if($ENV{'OCS_MODPERL_VERSION'} == 1){
require Apache::Ocsinventory::Server::Modperl1;
Apache::Ocsinventory::Server::Modperl1->import();
}elsif($ENV{'OCS_MODPERL_VERSION'} == 2){
require Apache::Ocsinventory::Server::Modperl2;
Apache::Ocsinventory::Server::Modperl2->import();
}
}
# These are the core modules you must include in addition
use Apache::Ocsinventory::Server::System;
use Apache::Ocsinventory::Server::Communication;
use Apache::Ocsinventory::Server::Constants;
use Apache::Ocsinventory::Server::Capacities::Snmp::Data;
use Apache::Ocsinventory::Server::Capacities::Snmp::Inventory;
#Getting sections for the 'ForceArray' option
my @forceArray = ('DEVICE');
&_get_snmp_parser_ForceArray(\@forceArray);
# Initialize option
push @{$Apache::Ocsinventory::OPTIONS_STRUCTURE},{
'NAME' => 'SNMP',
'HANDLER_PROLOG_READ' => undef, #or undef # Called before reading the prolog
'HANDLER_PROLOG_RESP' => \&snmp_prolog_resp, #or undef # Called after the prolog response building
'HANDLER_PRE_INVENTORY' => undef , #or undef # Called before reading inventory
'HANDLER_POST_INVENTORY' => undef, #or undef # Called when inventory is stored without error
'REQUEST_NAME' => 'SNMP', #or undef # Value of <QUERY/> xml tag
'HANDLER_REQUEST' => \&snmp_handler, #or undef # function that handle the request with the <QUERY>'REQUEST NAME'</QUERY>
'HANDLER_DUPLICATE' => \&snmp_duplicate, #or undef # Called when a computer is handle as a duplicate
'TYPE' => OPTION_TYPE_SYNC, # or OPTION_TYPE_ASYNC ASYNC=>with pr without inventory, SYNC=>only when inventory is required
'XML_PARSER_OPT' => {
'ForceArray' => [@forceArray]
}
};
sub snmp_prolog_resp{
my $current_context = shift;
my $resp = shift;
my $select_ip_req;
my $select_communities_req;
my $select_deviceid_req;
my $select_network_req;
my $select_mibs_req;
my @devicesToScan;
my @networksToScan;
my @communities;
my @mibs;
#Verify if SNMP is enable for this computer or in config
my $snmpSwitch = &_get_snmp_switch($current_context);
return unless $snmpSwitch;
#########
#SNMP
#########
# Ask computer to scan the requested snmp network devices
my @snmp;
my $dbh = $current_context->{'DBI_HANDLE'};
my $lanToDiscover = $current_context->{'PARAMS'}{'IPDISCOVER'}->{'TVALUE'};
my $behaviour = $current_context->{'PARAMS'}{'IPDISCOVER'}->{'IVALUE'};
my $groupsParams = $current_context->{'PARAMS_G'};
#Only if communication is https
if ($current_context->{'APACHE_OBJECT'}->subprocess_env('https')) {
$select_deviceid_req=$dbh->prepare('SELECT DEVICEID FROM hardware WHERE DEVICEID=?');
$select_deviceid_req->execute($current_context->{'DEVICEID'});
#Only if agent deviceid already exists in database
if ($select_deviceid_req->fetchrow_hashref) {
#Getting networks specified for scans
$select_network_req=$dbh->prepare("SELECT TVALUE FROM devices WHERE HARDWARE_ID=? AND NAME='SNMP_NETWORK'");
$select_network_req->execute($current_context->{'DATABASE_ID'});
#Getting networks separated by commas (will be removed when GUI will be OK to add several networks cleanly)
my $row = $select_network_req->fetchrow_hashref; #Only one line per HARDWARE_ID
@networksToScan= split(',',$row->{TVALUE});
#TODO: use this lines instead of previous ones when GUI will be OK to add several networks cleanly
#while(my $row = $select_network_req->fetchrow_hashref){
# push @networksToScan,$row;
#}
if (@networksToScan) {
#Adding devices informations in the XML
foreach my $network (@networksToScan) {
push @snmp,{
#'SUBNET' => $network->{TVALUE}, #TODO: uncomment this line when GUI will be OK to add several networks cleanly
'SUBNET' => $network,
'TYPE' => 'NETWORK',
};
}
}
#If the computer is Ipdicover elected
if ($behaviour == 1 || $behaviour == 2) {
#Getting non inventoried network devices for the agent subnet
$select_ip_req=$dbh->prepare('SELECT IP,MAC FROM netmap WHERE NETID=? AND mac NOT IN (SELECT DISTINCT(macaddr) FROM networks WHERE macaddr IS NOT NULL AND IPSUBNET=?)');
$select_ip_req->execute($lanToDiscover,$lanToDiscover);
while(my $row = $select_ip_req->fetchrow_hashref){
push @devicesToScan,$row;
}
if (@devicesToScan) {
#Adding devices informations in the XML
foreach my $device (@devicesToScan) {
push @snmp,{
'IPADDR' => $device->{IP},
'MACADDR' => $device->{MAC},
'TYPE' => 'DEVICE',
};
}
}
}
if (@snmp) {
#Getting snmp communities
$select_communities_req = $dbh->prepare('SELECT VERSION,NAME,USERNAME,AUTHKEY,AUTHPASSWD FROM snmp_communities');
$select_communities_req->execute();
while(my $row = $select_communities_req->fetchrow_hashref){
push @communities,$row;
}
if (@communities) {
foreach my $community (@communities) {
push @snmp,{
'VERSION' => $community->{'VERSION'}?$community->{'VERSION'}:'',
'NAME' => $community->{'NAME'}?$community->{'NAME'}:'',
'USERNAME'=> $community->{'USERNAME'}?$community->{'USERNAME'}:'',
'AUTHKEY' => $community->{'AUTHKEY'}?$community->{'AUTHKEY'}:'',
'AUTHPASSWD' => $community->{'AUTHPASSWD'}?$community->{'AUTHPASSWD'}:'',
'TYPE' => 'COMMUNITY',
};
}
}
#Getting custom mibs informations
$select_mibs_req = $dbh->prepare('SELECT VENDOR,URL,CHECKSUM,VERSION,PARSER FROM snmp_mibs');
$select_mibs_req->execute();
while(my $row = $select_mibs_req->fetchrow_hashref){
push @mibs,$row;
}
if (@mibs) {
foreach my $mib (@mibs) {
push @snmp,{
'VENDOR' => $mib->{'VENDOR'}?$mib->{'VENDOR'}:'',
'URL'=> $mib->{'URL'}?$mib->{'URL'}:'',
'CHECKSUM' => $mib->{'CHECKSUM'}?$mib->{'CHECKSUM'}:'',
'VERSION' => $mib->{'VERSION'}?$mib->{'VERSION'}:'',
'PARSER' => $mib->{'PARSER'}?$mib->{'PARSER'}:'',
'TYPE' => 'MIB',
};
}
}
#Final XML
push @{ $resp->{'OPTION'} },{
'NAME' => ['SNMP'],
'PARAM' => \@snmp,
};
}
} else { &_log(104,'snmp',"error: agent must have a deviceid in database !!") if $ENV{'OCS_OPT_LOGLEVEL'}; }
} else { &_log(103,'snmp',"error: agent must communicate using https to be able to get SNMP communities (only affects OCS unix agent) !!") if $ENV{'OCS_OPT_LOGLEVEL'} and $ENV{'OCS_OPT_SNMP_PRINT_HTTPS_ERROR'} }
}
sub snmp_handler{
my $current_context = shift;
#Verify if SNMP is enable for this computer or in config
my $snmpSwitch = &_get_snmp_switch($current_context);
return unless $snmpSwitch;
my $dbh = $current_context->{'DBI_HANDLE'};
my $result = $current_context->{'XML_ENTRY'};
my $r = $current_context->{'APACHE_OBJECT'};
my $hardware_id = $current_context->{'DATABASE_ID'};
# Remanent data
my ( %SNMP_SECTIONS, @SNMP_SECTIONS );
#We get snmp tables references from Map.pm
&_init_snmp_map( \%SNMP_SECTIONS, \@SNMP_SECTIONS );
#Inventory incoming
&_log(100,'snmp','inventory incoming') if $ENV{'OCS_OPT_LOGLEVEL'};
# Putting the SNMP inventory in the database
if (&_snmp_inventory( \%SNMP_SECTIONS, \@SNMP_SECTIONS, $current_context->{'DATABASE_ID'})) {
&_log(101,'snmp','inventory error !!') if $ENV{'OCS_OPT_LOGLEVEL'};
} else {
&_log(102,'snmp','inventory transmitted') if $ENV{'OCS_OPT_LOGLEVEL'};
}
#Sending Response to the agent
&_set_http_header('content-length', 0, $r);
&_send_http_headers($r);
return (APACHE_OK);
}
sub snmp_duplicate{
# Useful to manage duplicate with your own tables/structures when a computer is evaluated as a duplicate and replaced
return 1;
}
sub _get_snmp_switch {
my $current_context = shift ;
my $groupsParams = $current_context->{'PARAMS_G'};
my $snmpSwitch ;
if($ENV{'OCS_OPT_SNMP'}){
$snmpSwitch = 1;
# Groups custom parameter
for(keys(%$groupsParams)){
$snmpSwitch = $$groupsParams{$_}->{'SNMP_SWITCH'}->{'IVALUE'}
if exists( $$groupsParams{$_}->{'SNMP_SWITCH'}->{'IVALUE'} )
and $$groupsParams{$_}->{'SNMP_SWITCH'}->{'IVALUE'} < $snmpSwitch;
}
}
else{
$snmpSwitch = 0;
}
#Computer custom parameter
$snmpSwitch = $current_context->{'PARAMS'}{'SNMP_SWITCH'}->{'IVALUE'}
if defined($current_context->{'PARAMS'}{'SNMP_SWITCH'}->{'IVALUE'}) and $snmpSwitch;
return ($snmpSwitch);
}
1;
|