Passed
Push — master ( df2595...b8f383 )
by Patrick
01:54
created

Trap::db_connect_ido()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
//use FontLib\EOT\File;
5
6
include (dirname(__DIR__).'/library/Trapdirector/Icinga2Api.php');
7
include (dirname(__DIR__).'/library/Trapdirector/TrapsProcess/Logging.php');
8
include (dirname(__DIR__).'/library/Trapdirector/TrapsProcess/Database.php');
9
10
use Icinga\Module\Trapdirector\Icinga2API;
11
use Trapdirector\Logging;
12
use Trapdirector\Database;
13
14
class Trap
15
{
16
	// Configuration files a dirs
17
	protected $icingaweb2_etc; //< Icinga etc path	
18
	protected $trap_module_config; //< config.ini of module	
19
	protected $icingaweb2_ressources; //< resources.ini of icingaweb2
20
	// Options from config.ini 
21
	protected $snmptranslate='/usr/bin/snmptranslate';
22
	protected $snmptranslate_dirs='/usr/share/icingaweb2/modules/trapdirector/mibs';
23
	protected $icinga2cmd='/var/run/icinga2/cmd/icinga2.cmd';
24
	protected $db_prefix='traps_';
25
26
	// API
27
	protected $api_use=false;
28
	protected $icinga2api=null;
29
	protected $api_hostname='';
30
	protected $api_port=0;
31
	protected $api_username='';
32
	protected $api_password='';
33
34
	// Logs 
35
	protected $logging;    //< Logging class.
36
	protected $logSetup;   //< bool true if log was setup in constructor
37
	
38
	//protected $debug_file="php://stdout";	
39
	// Databases
40
	protected $trapsDB; //< Database class
41
	
42
	protected $trapDB=null; //< trap database  // DUP
43
	protected $idoDB=null; //< ido database  // DUP
44
	protected $trapDBType; //< Type of database for traps (mysql, pgsql)  // DUP
45
	protected $idoDBType; //< Type of database for ido (mysql, pgsql)  // DUP
46
	
47
	// Trap received data
48
	protected $receivingHost;
49
	public $trap_data=array(); //< Main trap data (oid, source...)
50
	public $trap_data_ext=array(); //< Additional trap data objects (oid/value).
51
	public $trap_id=null; //< trap_id after sql insert
52
	public $trap_action=null; //< trap action for final write
53
	protected $trap_to_db=true; //< log trap to DB
54
	
55
	// Mib update data
56
	private $dbOidAll; //< All oid in database;
57
	private $dbOidIndex; //< Index of oid in dbOidAll
58
	private $objectsAll; //< output lines of snmptranslate list
59
	private $trapObjectsIndex; //< array of traps objects (as OID)
60
	
61
	function __construct($etc_dir='/etc/icingaweb2',$baseLogLevel=null,$baseLogMode='syslog',$baseLogFile='')
62
	{
63
	    // Paths of ini files
64
		$this->icingaweb2_etc=$etc_dir;
65
		$this->trap_module_config=$this->icingaweb2_etc."/modules/trapdirector/config.ini";		
66
		$this->icingaweb2_ressources=$this->icingaweb2_etc."/resources.ini";
67
68
		// Setup logging
69
		$this->logging = new Logging();
70
		if ($baseLogLevel != null)
71
		{
72
		    $this->logging->setLogging($baseLogLevel, $baseLogMode,$baseLogFile);
73
		    $this->logSetup=true;
74
		}
75
		else 
76
		    $this->logSetup=false;
77
		$this->logging->log('Loggin started', INFO);
78
79
		// Get options from ini files
80
		$trapConfig=parse_ini_file($this->trap_module_config,true);
81
		if ($trapConfig == false)
82
		{
83
		    $this->logging->log("Error reading ini file : ".$this->trap_module_config,ERROR,'syslog');
84
		}
85
		$this->getMainOptions($trapConfig); // Get main options from ini file
86
		$this->setupDatabase($trapConfig); // Setup database class
87
		
88
		$this->getDatabaseOptions(); // Get options in database
89
		if ($this->api_use === true) $this->getAPI(); // Setup API
90
		
91
		$this->trap_data=array(
92
			'source_ip'	=> 'unknown',
93
			'source_port'	=> 'unknown',
94
			'destination_ip'	=> 'unknown',
95
			'destination_port'	=> 'unknown',
96
			'trap_oid'	=> 'unknown',
97
		);
98
		
99
	}
100
	
101
	/**
102
	 * Get option from array of ini file, send message if empty
103
	 * @param string $option_array Array of ini file
104
	 * @param string $option_category category in ini file
105
	 * @param string $option_name name of option in category
106
	 * @param resource $option_var variable to fill if found, left untouched if not found
107
	 * @param integer $log_level default 2 (warning)
108
	 * @param string $message warning message if not found
109
	 * @return boolean true if found, or false
110
	 */
111
	protected function getOptionIfSet($option_array,$option_category,$option_name, &$option_var, $log_level = 2, $message = null)
112
	{
113
	    if (!isset($option_array[$option_category][$option_name]))
114
	    {
115
	        if ($message === null)
116
	        {
117
	            $message='No ' . $option_name . ' in config file: '. $this->trap_module_config;
118
	        }
119
	        $this->logging->log($message,$log_level,'syslog');
120
	        return false;
121
	    }
122
	    else
123
	    {
124
	        $option_var=$option_array[$option_category][$option_name];
125
	        return true;
126
	    }
127
	}
128
	
129
	/** 
130
	 * Get options from ini file and database
131
	 * Setup the database class with options.
132
	 * @param array : ini file array
0 ignored issues
show
Documentation Bug introduced by
The doc comment : ini at position 0 could not be parsed: Unknown type name ':' at position 0 in : ini.
Loading history...
133
	*/
134
	protected function getMainOptions($trap_config)
0 ignored issues
show
Unused Code introduced by
The parameter $trap_config is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

134
	protected function getMainOptions(/** @scrutinizer ignore-unused */ $trap_config)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
135
	{
136
		$trap_config=parse_ini_file($this->trap_module_config,true);
137
		if ($trap_config == false) 
138
		{
139
			$this->logging->log("Error reading ini file : ".$this->trap_module_config,ERROR,'syslog'); 
140
		}
141
		// Snmptranslate binary path
142
		$this->getOptionIfSet($trap_config,'config','snmptranslate', $this->snmptranslate);
0 ignored issues
show
Bug introduced by
$trap_config of type array|false is incompatible with the type string expected by parameter $option_array of Trap::getOptionIfSet(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
		$this->getOptionIfSet(/** @scrutinizer ignore-type */ $trap_config,'config','snmptranslate', $this->snmptranslate);
Loading history...
143
144
		// mibs path
145
		$this->getOptionIfSet($trap_config,'config','snmptranslate_dirs', $this->snmptranslate_dirs);
146
147
		// icinga2cmd path
148
		$this->getOptionIfSet($trap_config,'config','icingacmd', $this->icinga2cmd);
149
		
150
		// table prefix
151
		$this->getOptionIfSet($trap_config,'config','database_prefix', $this->db_prefix);
152
153
		// API options
154
		if ($this->getOptionIfSet($trap_config,'config','icingaAPI_host', $this->api_hostname))
155
		{
156
		    $this->api_use=true;
157
		    $this->getOptionIfSet($trap_config,'config','icingaAPI_port', $this->api_port);
0 ignored issues
show
Bug introduced by
$this->api_port of type integer is incompatible with the type resource expected by parameter $option_var of Trap::getOptionIfSet(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
		    $this->getOptionIfSet($trap_config,'config','icingaAPI_port', /** @scrutinizer ignore-type */ $this->api_port);
Loading history...
158
		    $this->getOptionIfSet($trap_config,'config','icingaAPI_user', $this->api_username);
0 ignored issues
show
Bug introduced by
$this->api_username of type string is incompatible with the type resource expected by parameter $option_var of Trap::getOptionIfSet(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

158
		    $this->getOptionIfSet($trap_config,'config','icingaAPI_user', /** @scrutinizer ignore-type */ $this->api_username);
Loading history...
159
		    $this->getOptionIfSet($trap_config,'config','icingaAPI_password', $this->api_password);
160
		}
161
	}
162
	
163
	
164
	protected function setupDatabase($trapConfig)
165
	{
166
	    // Trap database
167
	    if (!array_key_exists('database',$trapConfig['config']))
168
        {
169
            $this->logging->log("No database in config file: ".$this->trap_module_config,ERROR,'');
170
            return;
171
        }
172
        $dbTrapName=$trapConfig['config']['database'];
173
        $this->logging->log("Found database in config file: ".$dbTrapName,INFO );
174
	    
175
	   if ( ($dbConfig=parse_ini_file($this->icingaweb2_ressources,true)) === false)
176
	    {
177
	        $this->logging->log("Error reading ini file : ".$this->icingaweb2_ressources,ERROR,'');
178
	        return;
179
	    }
180
	    if (!array_key_exists($dbTrapName,$dbConfig))
181
	    {
182
	        $this->logging->log("No database '.$dbTrapName.' in config file: ".$this->icingaweb2_ressources,ERROR,'');
183
	        return;
184
	    }
185
	    
186
        $this->trapsDB = new Database($this->logging,$dbConfig[$dbTrapName]);
187
	    
188
	    if ($this->api_use === true) return; // In case of API use, no IDO is necessary
189
        
190
	    // IDO Database
191
	    if (!array_key_exists('IDOdatabase',$trapConfig['config']))
192
	    {
193
	        $this->logging->log("No IDOdatabase in config file: ".$this->trap_module_config,ERROR,'');
194
	    }
195
	    $dbIdoName=$trapConfig['config']['IDOdatabase'];		
196
197
	    $this->logging->log("Found IDO database in config file: ".$dbIdoName,INFO );
198
        if (!array_key_exists($dbIdoName,$dbConfig))
199
	    {
200
	        $this->logging->log("No database '.$dbIdoName.' in config file: ".$this->icingaweb2_ressources,ERROR,'');
201
	        return;
202
	    }
203
	    
204
	    $this->trapsDB->setupIDO($dbConfig[$dbIdoName]);
205
	}
206
	
207
	/**
208
	 * Get options in database
209
	 */
210
	protected function getDatabaseOptions()
211
	{
212
		// Database options
213
		if ($this->logSetup == false) // Only if logging was no setup in constructor
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
214
		{
215
    		$this->getDBConfigIfSet('log_level',$this->logging->debugLevel);
216
    		$this->getDBConfigIfSet('log_destination',$this->logging->outputMode);
217
    		$this->getDBConfigIfSet('log_file',$this->logging->outputFile);
218
		}
219
	}
220
221
	protected function getDBConfigIfSet($element,&$variable)
222
	{
223
		$value=$this->getDBConfig($element);
224
		if ($value != 'null') $variable=$value;
225
	}
226
	
227
	/** 
228
	*   Get data from db_config
229
	*	@param $element string name of param
230
	*	@return mixed : value (or null)
231
	*/	
232
	protected function getDBConfig($element)
233
	{
234
		$db_conn=$this->trapsDB->db_connect_trap();
235
		$sql='SELECT value from '.$this->db_prefix.'db_config WHERE ( name=\''.$element.'\' )';
236
		if (($ret_code=$db_conn->query($sql)) === false) {
237
			$this->logging->log('No result in query : ' . $sql,WARN,'');
238
			return null;
239
		}
240
		$value=$ret_code->fetch();
241
		if ($value != null && isset($value['value']))
242
		{
243
			return $value['value'];
244
		}
245
		return null;
246
	}
247
	
248
	/** OBSOLETE Send log. Throws exception on critical error
249
	*	@param	string $message Message to log
250
	*	@param	int $level 1=critical 2=warning 3=trace 4=debug
251
	*	@param  string $destination file/syslog/display
252
	*	@return void
253
	**/	
254
	public function trapLog( $message, $level, $destination ='') // OBSOLETE
255
	{	
256
		// TODO : replace ref with $this->logging->log 
257
	    $this->logging->log($message, $level, $destination);
258
	}
259
	
260
	public function setLogging($debugLvl,$outputType,$outputOption=null)  // OBSOLETE
261
	{
262
		$this->logging->setLogging($debugLvl, $outputType,$outputOption);
263
	}
264
	
265
	protected function getAPI()
266
	{
267
	    if ($this->icinga2api == null)
268
	    {
269
	        $this->icinga2api = new Icinga2API($this->api_hostname,$this->api_port);
270
	    }
271
	    return $this->icinga2api;
272
	}
273
	
274
	
275
	/** 
276
	 * read data from stream
277
	*	@param $stream string input stream, defaults to "php://stdin"
278
	*	@return mixed array trap data or exception with error
279
	*/
280
	public function read_trap($stream='php://stdin')
281
	{
282
		//Read data from snmptrapd from stdin
283
		$input_stream=fopen($stream, 'r');
284
285
		if ($input_stream === false)
286
		{
287
		    $this->writeTrapErrorToDB("Error reading trap (code 1/Stdin)");
288
			$this->logging->log("Error reading stdin !",ERROR,'');
289
			return null; // note : exception thrown by logging
290
		}
291
292
		// line 1 : host
293
		$this->receivingHost=chop(fgets($input_stream));
294
		if ($this->receivingHost === false)
295
		{
296
		    $this->writeTrapErrorToDB("Error reading trap (code 1/Line Host)");
297
			$this->logging->log("Error reading Host !",ERROR,''); 
298
		}
299
		// line 2 IP:port=>IP:port
300
		$IP=chop(fgets($input_stream));
301
		if ($IP === false)
302
		{
303
		    $this->writeTrapErrorToDB("Error reading trap (code 1/Line IP)");
304
			$this->logging->log("Error reading IP !",ERROR,''); 
305
		}
306
		$matches=array();
307
		$ret_code=preg_match('/.DP: \[(.*)\]:(.*)->\[(.*)\]:(.*)/',$IP,$matches);
308
		if ($ret_code===0 || $ret_code===false) 
309
		{
310
		    $this->writeTrapErrorToDB("Error parsing trap (code 2/IP)");
311
			$this->logging->log('Error parsing IP : '.$IP,ERROR,'');
312
		} 
313
		else 
314
		{		
315
			$this->trap_data['source_ip']=$matches[1];
316
			$this->trap_data['destination_ip']=$matches[3];
317
			$this->trap_data['source_port']=$matches[2];
318
			$this->trap_data['destination_port']=$matches[4];
319
		}
320
321
		while (($vars=fgets($input_stream)) !==false)
322
		{
323
			$vars=chop($vars);
324
			$ret_code=preg_match('/^([^ ]+) (.*)$/',$vars,$matches);
325
			if ($ret_code===0 || $ret_code===false) 
326
			{
327
				$this->logging->log('No match on trap data : '.$vars,WARN,'');
328
			}
329
			else 
330
			{
331
			    if (($matches[1]=='.1.3.6.1.6.3.1.1.4.1.0') || ($matches[1]=='.1.3.6.1.6.3.1.1.4.1'))
332
				{
333
					$this->trap_data['trap_oid']=$matches[2];				
334
				}
335
				else
336
				{
337
					$object= new stdClass;
338
					$object->oid =$matches[1];
339
					$object->value = $matches[2];
340
					array_push($this->trap_data_ext,$object);
341
				}
342
			}
343
		}
344
345
		if ($this->trap_data['trap_oid']=='unknown') 
346
		{
347
		    $this->writeTrapErrorToDB("No trap oid found : check snmptrapd configuration (code 3/OID)",$this->trap_data['source_ip']);
348
			$this->logging->log('no trap oid found',ERROR,'');
349
		} 
350
351
		// Translate oids.
352
		
353
		$retArray=$this->translateOID($this->trap_data['trap_oid']);
354
		if ($retArray != null)
355
		{
356
			$this->trap_data['trap_name']=$retArray['trap_name'];
357
			$this->trap_data['trap_name_mib']=$retArray['trap_name_mib'];
358
		}
359
		foreach ($this->trap_data_ext as $key => $val)
360
		{
361
			$retArray=$this->translateOID($val->oid);
362
			if ($retArray != null)
363
			{
364
				$this->trap_data_ext[$key]->oid_name=$retArray['trap_name'];
365
				$this->trap_data_ext[$key]->oid_name_mib=$retArray['trap_name_mib'];
366
			}			
367
		}
368
		
369
370
		$this->trap_data['status']= 'waiting';
371
		
372
		return $this->trap_data;
373
	}
374
375
	/** 
376
	 * Translate oid into array(MIB,Name)
377
	* @param $oid string oid to translate
378
	* @return mixed : null if not found or array(MIB,Name)
379
	*/
380
	public function translateOID($oid)
381
	{
382
		// try from database
383
		$db_conn=$this->trapsDB->db_connect_trap();
384
		
385
		$sql='SELECT mib,name from '.$this->db_prefix.'mib_cache WHERE oid=\''.$oid.'\';';
386
		$this->logging->log('SQL query : '.$sql,DEBUG );
387
		if (($ret_code=$db_conn->query($sql)) === false) {
388
			$this->logging->log('No result in query : ' . $sql,ERROR,'');
389
		}
390
		$name=$ret_code->fetch();
391
		if ($name['name'] != null)
392
		{
393
			return array('trap_name_mib'=>$name['mib'],'trap_name'=>$name['name']);
394
		}
395
		
396
		// Also check if it is an instance of OID
397
		$oid_instance=preg_replace('/\.[0-9]+$/','',$oid);
398
		
399
		$sql='SELECT mib,name from '.$this->db_prefix.'mib_cache WHERE oid=\''.$oid_instance.'\';';
400
		$this->logging->log('SQL query : '.$sql,DEBUG );
401
		if (($ret_code=$db_conn->query($sql)) === false) {
402
			$this->logging->log('No result in query : ' . $sql,ERROR,'');
403
		}
404
		$name=$ret_code->fetch();
405
		if ($name['name'] != null)
406
		{
407
			return array('trap_name_mib'=>$name['mib'],'trap_name'=>$name['name']);
408
		}
409
		
410
		// Try to get oid name from snmptranslate
411
		$translate=exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.
412
		    ' '.$oid);
413
		$matches=array();
414
		$ret_code=preg_match('/(.*)::(.*)/',$translate,$matches);
415
		if ($ret_code===0 || $ret_code === false) {
416
			return NULL;
417
		} else {
418
			$this->logging->log('Found name with snmptrapd and not in DB for oid='.$oid,INFO);
419
			return array('trap_name_mib'=>$matches[1],'trap_name'=>$matches[2]);
420
		}	
421
	}
422
	
423
	/** 
424
	 * Erase old trap records 
425
	*	@param integer $days : erase traps when more than $days old
426
	*	@return integer : number of lines deleted
427
	**/
428
	public function eraseOldTraps($days=0)
429
	{
430
		if ($days==0)
431
		{
432
			if (($days=$this->getDBConfig('db_remove_days')) == null)
433
			{
434
				$this->logging->log('No days specified & no db value : no tap erase' ,WARN,'');
435
				return;
436
			}
437
		}
438
		$db_conn=$this->trapsDB->db_connect_trap();
439
		$daysago = strtotime("-".$days." day");
440
		$sql= 'delete from '.$this->db_prefix.'received where date_received < \''.date("Y-m-d H:i:s",$daysago).'\';';
441
		if ($db_conn->query($sql) === false) {
442
			$this->logging->log('Error erasing traps : '.$sql,ERROR,'');
443
		}
444
		$this->logging->log('Erased traps older than '.$days.' day(s) : '.$sql,INFO);
445
	}
446
447
	/** Write error to received trap database
448
	 */
449
	public function writeTrapErrorToDB($message,$sourceIP=null,$trapoid=null)
450
	{
451
	    
452
	    $db_conn=$this->trapsDB->db_connect_trap();
453
	    
454
	    // add date time
455
	    $insert_col ='date_received,status';
456
	    $insert_val = "'" . date("Y-m-d H:i:s")."','error'";
457
        
458
	    if ($sourceIP !=null)
459
	    {
460
	        $insert_col .=',source_ip';
461
	        $insert_val .=",'". $sourceIP ."'";
462
	    }
463
	    if ($trapoid !=null)
464
	    {
465
	        $insert_col .=',trap_oid';
466
	        $insert_val .=",'". $trapoid ."'";
467
	    }
468
	    $insert_col .=',status_detail';
469
	    $insert_val .=",'". $message ."'";
470
	    
471
	    $sql= 'INSERT INTO '.$this->db_prefix.'received (' . $insert_col . ') VALUES ('.$insert_val.')';
472
	    
473
	    switch ($this->trapsDB->trapDBType)
474
	    {
475
	        case 'pgsql':
476
	            $sql .= ' RETURNING id;';
477
	            $this->logging->log('sql : '.$sql,INFO);
478
	            if (($ret_code=$db_conn->query($sql)) === false) {
479
	                $this->logging->log('Error SQL insert : '.$sql,1,'');
480
	            }
481
	            $this->logging->log('SQL insertion OK',INFO );
482
	            // Get last id to insert oid/values in secondary table
483
	            if (($inserted_id_ret=$ret_code->fetch(PDO::FETCH_ASSOC)) === false) {
484
	                
485
	                $this->logging->log('Erreur recuperation id',1,'');
486
	            }
487
	            if (! isset($inserted_id_ret['id'])) {
488
	                $this->logging->log('Error getting id',1,'');
489
	            }
490
	            $this->trap_id=$inserted_id_ret['id'];
491
	            break;
492
	        case 'mysql':
493
	            $sql .= ';';
494
	            $this->logging->log('sql : '.$sql,INFO );
495
	            if ($db_conn->query($sql) === false) {
496
	                $this->logging->log('Error SQL insert : '.$sql,1,'');
497
	            }
498
	            $this->logging->log('SQL insertion OK',INFO );
499
	            // Get last id to insert oid/values in secondary table
500
	            $sql='SELECT LAST_INSERT_ID();';
501
	            if (($ret_code=$db_conn->query($sql)) === false) {
502
	                $this->logging->log('Erreur recuperation id',1,'');
503
	            }
504
	            
505
	            $inserted_id=$ret_code->fetch(PDO::FETCH_ASSOC)['LAST_INSERT_ID()'];
506
	            if ($inserted_id==false) throw new Exception("Weird SQL error : last_insert_id returned false : open issue");
507
	            $this->trap_id=$inserted_id;
508
	            break;
509
	        default:
510
	            $this->logging->log('Error SQL type unknown  : '.$this->trapsDB->trapDBType,1,'');
511
	    }
512
	    
513
	    $this->logging->log('id found: '. $this->trap_id,INFO );    
514
	}
515
	
516
	/** Write trap data to trap database
517
	*/
518
	public function writeTrapToDB()
519
	{
520
		
521
		// If action is ignore -> don't send t DB
522
		if ($this->trap_to_db === false) return;
523
		
524
		
525
		$db_conn=$this->trapsDB->db_connect_trap();
526
		
527
		$insert_col='';
528
		$insert_val='';
529
		// add date time
530
		$this->trap_data['date_received'] = date("Y-m-d H:i:s");
531
532
		$firstcol=1;
533
		foreach ($this->trap_data as $col => $val)
534
		{
535
			if ($firstcol==0) 
536
			{
537
				$insert_col .=',';
538
				$insert_val .=',';
539
			}
540
			$insert_col .= $col ;
541
			$insert_val .= ($val==null)? 'NULL' : $db_conn->quote($val);
542
			$firstcol=0;
543
		}
544
		
545
		$sql= 'INSERT INTO '.$this->db_prefix.'received (' . $insert_col . ') VALUES ('.$insert_val.')';
546
		switch ($this->trapsDB->trapDBType)
547
		{
548
			case 'pgsql': 
549
				$sql .= ' RETURNING id;';
550
				$this->logging->log('sql : '.$sql,INFO );
551
				if (($ret_code=$db_conn->query($sql)) === false) {
552
					$this->logging->log('Error SQL insert : '.$sql,ERROR,'');
553
				}
554
				$this->logging->log('SQL insertion OK',INFO );
555
				// Get last id to insert oid/values in secondary table
556
				if (($inserted_id_ret=$ret_code->fetch(PDO::FETCH_ASSOC)) === false) {
557
														   
558
					$this->logging->log('Erreur recuperation id',ERROR,'');
559
				}
560
				if (! isset($inserted_id_ret['id'])) {
561
					$this->logging->log('Error getting id',ERROR,'');
562
				}
563
				$this->trap_id=$inserted_id_ret['id'];
564
			break;
565
			case 'mysql': 
566
				$sql .= ';';
567
				$this->logging->log('sql : '.$sql,INFO );
568
				if ($db_conn->query($sql) === false) {
569
					$this->logging->log('Error SQL insert : '.$sql,ERROR,'');
570
				}
571
				$this->logging->log('SQL insertion OK',INFO );
572
				// Get last id to insert oid/values in secondary table
573
				$sql='SELECT LAST_INSERT_ID();';
574
				if (($ret_code=$db_conn->query($sql)) === false) {
575
					$this->logging->log('Erreur recuperation id',ERROR,'');
576
				}
577
578
				$inserted_id=$ret_code->fetch(PDO::FETCH_ASSOC)['LAST_INSERT_ID()'];
579
				if ($inserted_id==false) throw new Exception("Weird SQL error : last_insert_id returned false : open issue");
580
				$this->trap_id=$inserted_id;
581
			break;
582
			default: 
583
				$this->logging->log('Error SQL type unknown : '.$this->trapsDB->trapDBType,ERROR,'');
584
		}
585
		$this->logging->log('id found: '.$this->trap_id,INFO );
586
		
587
		// Fill trap extended data table
588
		foreach ($this->trap_data_ext as $value) {			
589
			// TODO : detect if trap value is encoded and decode it to UTF-8 for database
590
			$firstcol=1;
591
			$value->trap_id = $this->trap_id;
592
			$insert_col='';
593
			$insert_val='';
594
			foreach ($value as $col => $val)
595
			{
596
				if ($firstcol==0) 
597
				{
598
					$insert_col .=',';
599
					$insert_val .=',';
600
				}
601
				$insert_col .= $col;
602
				$insert_val .= ($val==null)? 'NULL' : $db_conn->quote($val);
603
				$firstcol=0;
604
			}
605
606
			$sql= 'INSERT INTO '.$this->db_prefix.'received_data (' . $insert_col . ') VALUES ('.$insert_val.');';			
607
608
			if (($ret_code=$db_conn->query($sql)) === false) {
0 ignored issues
show
Unused Code introduced by
The assignment to $ret_code is dead and can be removed.
Loading history...
609
				$this->logging->log('Erreur insertion data : ' . $sql,WARN,'');
610
			}	
611
		}	
612
	}
613
614
	/** Get rules from rule database with ip and oid
615
	*	@param $ip string ipv4 or ipv6
616
	*	@param $oid string oid in numeric
617
	*	@return mixed : PDO object or false
618
	*/	
619
	protected function getRules($ip,$oid)
620
	{
621
		$db_conn=$this->trapsDB->db_connect_trap();
622
		// fetch rules based on IP in rule and OID
623
		$sql='SELECT * from '.$this->db_prefix.'rules WHERE trap_oid=\''.$oid.'\' ';
624
		$this->logging->log('SQL query : '.$sql,DEBUG );
625
		if (($ret_code=$db_conn->query($sql)) === false) {
626
			$this->logging->log('No result in query : ' . $sql,WARN,'');
627
			return false;
628
		}
629
		$rules_all=$ret_code->fetchAll();
630
		//echo "rule all :\n";print_r($rules_all);echo "\n";
631
		$rules_ret=array();
632
		$rule_ret_key=0;
633
		foreach ($rules_all as $key => $rule)
634
		{
635
			if ($rule['ip4']==$ip || $rule['ip6']==$ip)
636
			{
637
				$rules_ret[$rule_ret_key]=$rules_all[$key];
638
				//TODO : get host name by API (and check if correct in rule).
639
				$rule_ret_key++;
640
				continue;
641
			}
642
			// TODO : get hosts IP by API
643
			if (isset($rule['host_group_name']) && $rule['host_group_name']!=null)
644
			{ // get ips of group members by oid
645
				$db_conn2=$this->trapsDB->db_connect_ido();
646
				$sql="SELECT m.host_object_id, a.address as ip4, a.address6 as ip6, b.name1 as host_name
647
						FROM icinga_objects as o
648
						LEFT JOIN icinga_hostgroups as h ON o.object_id=h.hostgroup_object_id
649
						LEFT JOIN icinga_hostgroup_members as m ON h.hostgroup_id=m.hostgroup_id
650
						LEFT JOIN icinga_hosts as a ON a.host_object_id = m.host_object_id
651
						LEFT JOIN icinga_objects as b ON b.object_id = a.host_object_id
652
						WHERE o.name1='".$rule['host_group_name']."';";
653
				if (($ret_code2=$db_conn2->query($sql)) === false) {
654
					$this->logging->log('No result in query : ' . $sql,WARN,'');
655
					continue;
656
				}
657
				$grouphosts=$ret_code2->fetchAll();
658
				//echo "rule grp :\n";print_r($grouphosts);echo "\n";
659
				foreach ( $grouphosts as $host)
660
				{
661
					//echo $host['ip4']."\n";
662
					if ($host['ip4']==$ip || $host['ip6']==$ip)
663
					{
664
						//echo "Rule added \n";
665
						$rules_ret[$rule_ret_key]=$rules_all[$key];
666
						$rules_ret[$rule_ret_key]['host_name']=$host['host_name'];
667
						$rule_ret_key++;
668
					}	
669
				}
670
			}
671
		}
672
		//echo "rule rest :\n";print_r($rules_ret);echo "\n";exit(0);
673
		return $rules_ret;
674
	}
675
676
	/** Add rule match to rule
677
	*	@param id int : rule id
678
	*   @param set int : value to set
679
	*/
680
	protected function add_rule_match($id, $set)
681
	{
682
		$db_conn=$this->trapsDB->db_connect_trap();
683
		$sql="UPDATE ".$this->db_prefix."rules SET num_match = '".$set."' WHERE (id = '".$id."');";
684
		if ($db_conn->query($sql) === false) {
685
			$this->logging->log('Error in update query : ' . $sql,WARN,'');
686
		}
687
	}
688
	
689
	/** Send SERVICE_CHECK_RESULT with icinga2cmd or API
690
	 * 
691
	 * @param string $host
692
	 * @param string $service
693
	 * @param integer $state numerical staus 
694
	 * @param string $display
695
	 * @returnn bool true is service check was sent without error
696
	*/
697
	public function serviceCheckResult($host,$service,$state,$display)
698
	{
699
	    if ($this->api_use === false)
700
	    {
701
    		$send = '[' . date('U') .'] PROCESS_SERVICE_CHECK_RESULT;' .
702
    			$host.';' .$service .';' . $state . ';'.$display;
703
    		$this->logging->log( $send." : to : " .$this->icinga2cmd,INFO );
704
    		
705
    		// TODO : file_put_contents & fopen (,'w' or 'a') does not work. See why. Or not as using API will be by default....
706
    		exec('echo "'.$send.'" > ' .$this->icinga2cmd);
707
    		return true;
708
	    }
709
	    else
710
	    {
711
	        $api = $this->getAPI();
712
	        $api->setCredentials($this->api_username, $this->api_password);
713
	        list($retcode,$retmessage)=$api->serviceCheckResult($host,$service,$state,$display);
714
	        if ($retcode == false)
715
	        {
716
	            $this->logging->log( "Error sending result : " .$retmessage,WARN,'');
717
	            return false;
718
	        }
719
	        else 
720
	        {
721
	            $this->logging->log( "Sent result : " .$retmessage,INFO );
722
	            return true;
723
	        }
724
	    }
725
	}
726
	
727
	public function getHostByIP($ip)
728
	{
729
	    $api = $this->getAPI();
730
	    $api->setCredentials($this->api_username, $this->api_password);
731
	    return $api->getHostByIP($ip);
732
	}
733
	
734
	/** Resolve display. 
735
	*	Changes OID(<oid>) to value if found or text "<not in trap>"
736
	*	@param $display string
737
	*	@return string display
738
	*/
739
	protected function applyDisplay($display)
740
	{
741
	    $matches=array();
742
	    while (preg_match('/_OID\(([0-9\.]+)\)/',$display,$matches) == 1)
743
		{
744
			$oid=$matches[1];
745
			$found=0;
746
			foreach($this->trap_data_ext as $val)
747
			{
748
				if ($oid == $val->oid)
749
				{
750
					$val->value=preg_replace('/"/','',$val->value);
751
					$rep=0;
752
					$display=preg_replace('/_OID\('.$oid.'\)/',$val->value,$display,-1,$rep);
753
					if ($rep==0)
754
					{
755
						$this->logging->log("Error in display",WARN,'');
756
						return $display;
757
					}
758
					$found=1;
759
					break;
760
				}
761
			}
762
			if ($found==0)
763
			{
764
				$display=preg_replace('/_OID\('.$oid.'\)/','<not in trap>',$display,-1,$rep);
765
				if ($rep==0)
766
				{
767
					$this->logging->log("Error in display",WARN,'');
768
					return $display;
769
				}				
770
			}
771
		}
772
		return $display;
773
	}
774
775
	
776
	/***************** Eval & tokenizer functions ****************/
777
	protected function eval_getElement($rule,&$item)
778
	{
779
		while ($rule[$item]==' ') $item++;
780
		if (preg_match('/[0-9\.]/',$rule[$item]))
781
		{ // number
782
	
783
			$item2=$item+1; 
784
			while (($item2!=strlen($rule)) && (preg_match('/[0-9\.]/',$rule[$item2]))) { $item2++ ;}
785
			$val=substr($rule,$item,$item2-$item);
786
			$item=$item2;
787
			//echo "number ".$val."\n";
788
			return array(0,$val);
789
		}
790
		if ($rule[$item] == '"')
791
		{ // string
792
			$item++;
793
			$item2=$this->eval_getNext($rule,$item,'"');
794
			$val=substr($rule,$item,$item2-$item-1);
795
			$item=$item2;
796
			//echo "string : ".$val."\n";
797
			return array(1,$val);
798
		}
799
		
800
		if ($rule[$item] == '(')
801
		{ // grouping
802
		    $item++;
803
			$start=$item;
804
			$parenthesis_count=0; 
805
			while (($item < strlen($rule)) // Not end of string AND
806
			      && ( ($rule[$item] != ')' ) || $parenthesis_count > 0) ) // Closing ')' or embeded ()
807
			{ 
808
				if ($rule[$item] == '"' )
809
				{ // pass through string
810
					$item++;
811
					$item=$this->eval_getNext($rule,$item,'"');
812
				} 
813
				else{
814
				    if ($rule[$item] == '(')
815
				    {
816
				        $parenthesis_count++;
817
				    }
818
				    if ($rule[$item] == ')')
819
				    {
820
				        $parenthesis_count--;
821
				    }
822
					$item++;
823
				}
824
			}
825
			
826
			if ($item==strlen($rule)) {throw new Exception("no closing () in ".$rule ." at " .$item);}
827
			$val=substr($rule,$start,$item-$start);
828
			$item++;
829
			$start=0;
830
			//echo "group : ".$val."\n";
831
			// returns evaluation of group as type 2 (boolean)
832
			return array(2,$this->evaluation($val,$start));		
833
		}
834
		throw new Exception("number/string not found in ".$rule ." at " .$item . ' : ' .$rule[$item]);
835
		
836
	}
837
	
838
	protected function eval_getNext($rule,$item,$tok)
839
	{
840
		while (($rule[$item] != $tok ) && ($item < strlen($rule))) { $item++;}
841
		if ($item==strlen($rule)) throw new Exception("closing '".$tok."' not found in ".$rule ." at " .$item);
842
		return $item+1;
843
	}
844
	
845
	protected function eval_getOper($rule,&$item)
846
	{
847
		while ($rule[$item]==' ') $item++;
848
		switch ($rule[$item])
849
		{
850
			case '<':
851
				if ($rule[$item+1]=='=') { $item+=2; return array(0,"<=");}
852
				$item++; return array(0,"<");
853
			case '>':
854
				if ($rule[$item+1]=='=') { $item+=2; return array(0,">=");}
855
				$item++; return array(0,">");
856
			case '=':
857
				$item++; return array(0,"=");	
858
			case '!':
859
				if ($rule[$item+1]=='=') { $item+=2; return array(0,"!=");}
860
				throw new Exception("Erreur in expr - incorrect operator '!'  found in ".$rule ." at " .$item);
861
			case '~':
862
				$item++; return array(0,"~");	
863
			case '|':
864
				$item++; return array(1,"|");	
865
			case '&':
866
				$item++; return array(1,"&");
867
			default	:
868
				throw new Exception("Erreur in expr - operator not found in ".$rule ." at " .$item);
869
		}
870
	}
871
	
872
	/** Evaluation : makes token and evaluate. 
873
	*	Public function for expressions testing
874
	*	accepts : < > = <= >= !=  (typec = 0)
875
	*	operators : & | (typec=1)
876
	*	with : integers/float  (type 0) or strings "" (type 1) or results (type 2)
877
	*   comparison int vs strings will return null (error)
878
	*	return : bool or null on error
879
	*/
880
	public function evaluation($rule,&$item)
881
	{
882
	    //echo "Evaluation of ".substr($rule,$item)."\n";
883
		if ( $rule[$item] == '!') // If '!' found, negate next expression.
884
		{
885
		    $negate=true;
886
		    $item++;
887
		}
888
		else
889
		{
890
		    $negate=false;
891
		}
892
		// First element : number, string or ()
893
		list($type1,$val1) = $this->eval_getElement($rule,$item);
894
		//echo "Elmt1: ".$val1."/".$type1." : ".substr($rule,$item)."\n";
895
		
896
		if ($item==strlen($rule)) // If only element, return value, but only boolean
897
		{
898
		  if ($type1 != 2) throw new Exception("Cannot use num/string as boolean : ".$rule);
899
		  if ($negate === true) $val1= ! $val1;
900
		  return $val1;
901
		}  
902
		
903
		// Second element : operator
904
		list($typec,$comp) = $this->eval_getOper($rule,$item);
905
		//echo "Comp : ".$comp." : ".substr($rule,$item)."\n";
906
        
907
		// Third element : number, string or ()
908
		if ( $rule[$item] == '!') // starts with a ! so evaluate whats next
909
		{
910
		    $item++;
911
		    if ($typec != 1) throw new Exception("Mixing boolean and comparison : ".$rule);
912
		    $val2= ! $this->evaluation($rule,$item);
913
		    $type2=2; // result is a boolean 
914
		}
915
		else 
916
		{
917
		    list($type2,$val2) = $this->eval_getElement($rule,$item);
918
		}
919
		//echo "Elmt2: ".$val2."/".$type2." : ".substr($rule,$item)."\n";
920
		
921
		if ($type1!=$type2)  // cannot compare different types
922
		{ 
923
		    throw new Exception("Cannot compare string & number : ".$rule);
924
		}
925
		if ($typec==1 && $type1 !=2) // cannot use & or | with string/number
926
		{
927
		    throw new Exception("Cannot use boolean operators with string & number : ".$rule);
928
		}
929
		
930
		switch ($comp){
931
			case '<':	$retVal= ($val1 < $val2); break;
932
			case '<=':	$retVal= ($val1 <= $val2); break;
933
			case '>':	$retVal= ($val1 > $val2); break;
934
			case '>=':	$retVal= ($val1 >= $val2); break;
935
			case '=':	$retVal= ($val1 == $val2); break;
936
			case '!=':	$retVal= ($val1 != $val2); break;
937
			case '~':	$retVal= (preg_match('/'.preg_replace('/"/','',$val2).'/',$val1)); break;
938
			case '|':	$retVal= ($val1 || $val2); break;
939
			case '&':	$retVal= ($val1 && $val2); break;
940
			default:  throw new Exception("Error in expression - unknown comp : ".$comp);
941
		}
942
		if ($negate === true) $retVal = ! $retVal; // Inverse result if negate before expression
943
		
944
		if ($item==strlen($rule)) return $retVal; // End of string : return evaluation
945
		// check for logical operator :
946
		switch ($rule[$item])
947
		{
948
			case '|':	$item++; return ($retVal || $this->evaluation($rule,$item) );
949
			case '&':	$item++; return ($retVal && $this->evaluation($rule,$item) );
950
			
951
			default:  throw new Exception("Erreur in expr - garbadge at end of expression : ".$rule[$item]);
952
		}
953
	}
954
	// Remove all whitespaces (when not quoted)
955
	public function eval_cleanup($rule)
956
	{
957
		$item=0;
958
		$rule2='';
959
		while ($item < strlen($rule))
960
		{
961
			if ($rule[$item]==' ') { $item++; continue; }
962
			if ($rule[$item]=='"')
963
			{
964
				$rule2.=$rule[$item];
965
				$item++;
966
				while (($rule[$item]!='"') && ($item < strlen($rule)))
967
				{
968
					$rule2.=$rule[$item];
969
					$item++;
970
				}
971
				if ($item == strlen ($rule)) throw new Exception("closing '\"' not found in ".$rule ." at " .$item);
972
				$rule2.=$rule[$item];
973
				$item++;
974
				continue;
975
			}
976
			
977
			$rule2.=$rule[$item];
978
			$item++;		
979
		}
980
		
981
		return $rule2;		
982
	}		
983
	
984
	/** Evaluation rule (uses eval_* functions recursively)
985
	*	@param $rule string rule ( _OID(.1.3.6.1.4.1.8072.2.3.2.1)=_OID(.1.3.6.1.2.1.1.3.0) )
986
	*	@return bool : true : rule match, false : rule don't match , throw exception on error.
987
	*/
988
	
989
	protected function eval_rule($rule)
990
	{
991
		if ($rule==null || $rule == '') // Empty rule is always true
992
		{
993
			return true;
994
		}
995
		$matches=array();
996
		while (preg_match('/_OID\(([0-9\.\*]+)\)/',$rule,$matches) == 1)
997
		{
998
			$oid=$matches[1];
999
			$found=0;
1000
			// ** replaced by .*
1001
			$oidR=preg_replace('/\*\*/', '.*', $oid);
1002
			// * replaced by [^.]*  
1003
			$oidR=preg_replace('/\*/', '[0-9]+', $oidR);
1004
			
1005
			// replace * with \* in oid for preg_replace
1006
			$oid=preg_replace('/\*/', '\*', $oid);
1007
			
1008
			$this->logging->log('OID in rule : '.$oid.' / '.$oidR,DEBUG );
1009
			
1010
			foreach($this->trap_data_ext as $val)
1011
			{
1012
				if (preg_match("/^$oidR$/",$val->oid) == 1)
1013
				{
1014
					if (!preg_match('/^[0-9]*\.?[0-9]+$/',$val->value))
1015
					{ // If not a number, change " to ' and put " around it
1016
						$val->value=preg_replace('/"/',"'",$val->value);
1017
						$val->value='"'.$val->value.'"';
1018
					}
1019
					$rep=0;
1020
					$rule=preg_replace('/_OID\('.$oid.'\)/',$val->value,$rule,-1,$rep);
1021
					if ($rep==0)
1022
					{
1023
						$this->logging->log("Error in rule_eval",WARN,'');
1024
						return false;
1025
					}
1026
					$found=1;
1027
					break;
1028
				}
1029
			}
1030
			if ($found==0)
1031
			{	// OID not found : throw error
1032
			    throw new Exception('OID '.$oid.' not found in trap');
1033
			}
1034
		}
1035
		$item=0;
1036
		$rule=$this->eval_cleanup($rule);
1037
		$this->logging->log('Rule after clenup: '.$rule,INFO );
1038
		
1039
		return  $this->evaluation($rule,$item);
1040
	}
1041
	
1042
	/** Match rules for current trap and do action
1043
	*/
1044
	public function applyRules()
1045
	{
1046
		$rules = $this->getRules($this->trap_data['source_ip'],$this->trap_data['trap_oid']);
1047
		
1048
		if ($rules===false || count($rules)==0)
0 ignored issues
show
introduced by
The condition $rules === false is always true.
Loading history...
1049
		{
1050
			$this->logging->log('No rules found for this trap',INFO );
1051
			$this->trap_data['status']='unknown';
1052
			$this->trap_to_db=true;
1053
			return;
1054
		}
1055
		//print_r($rules);
1056
		// Evaluate all rules in sequence
1057
		$this->trap_action=null;
1058
		foreach ($rules as $rule)
1059
		{
1060
			
1061
			$host_name=$rule['host_name'];
1062
			$service_name=$rule['service_name'];
1063
			
1064
			$display=$this->applyDisplay($rule['display']);
1065
			$this->trap_action = ($this->trap_action==null)? '' : $this->trap_action . ', ';
1066
			try
1067
			{
1068
				$this->logging->log('Rule to eval : '.$rule['rule'],INFO );
1069
				$evalr=$this->eval_rule($rule['rule']);
1070
				
1071
				if ($evalr == true)
1072
				{
1073
					//$this->logging->log('rules OOK: '.print_r($rule),INFO );
1074
					$action=$rule['action_match'];
1075
					$this->logging->log('action OK : '.$action,INFO );
1076
					if ($action >= 0)
1077
					{
1078
						if ($this->serviceCheckResult($host_name,$service_name,$action,$display) == false)
1079
						{
1080
						    $this->trap_action.='Error sending status : check cmd/API';
1081
						}
1082
						else
1083
						{
1084
						    $this->add_rule_match($rule['id'],$rule['num_match']+1);
1085
						    $this->trap_action.='Status '.$action.' to '.$host_name.'/'.$service_name;
1086
						}
1087
					}
1088
					else
1089
					{
1090
						$this->add_rule_match($rule['id'],$rule['num_match']+1);
1091
					}
1092
					$this->trap_to_db=($action==-2)?false:true;
1093
				}
1094
				else
1095
				{
1096
					//$this->logging->log('rules KOO : '.print_r($rule),INFO );
1097
					
1098
					$action=$rule['action_nomatch'];
1099
					$this->logging->log('action NOK : '.$action,INFO );
1100
					if ($action >= 0)
1101
					{
1102
					    if ($this->serviceCheckResult($host_name,$service_name,$action,$display)==false)
1103
					    {
1104
					        $this->trap_action.='Error sending status : check cmd/API';
1105
					    }
1106
					    else
1107
					    {
1108
    						$this->add_rule_match($rule['id'],$rule['num_match']+1);
1109
    						$this->trap_action.='Status '.$action.' to '.$host_name.'/'.$service_name;
1110
					    }
1111
					}
1112
					else
1113
					{
1114
						$this->add_rule_match($rule['id'],$rule['num_match']+1);
1115
					}
1116
					$this->trap_to_db=($action==-2)?false:true;					
1117
				}
1118
				// Put name in source_name
1119
				if (!isset($this->trap_data['source_name']))
1120
				{
1121
					$this->trap_data['source_name']=$rule['host_name'];
1122
				}
1123
				else
1124
				{
1125
					if (!preg_match('/'.$rule['host_name'].'/',$this->trap_data['source_name']))
1126
					{ // only add if not present
1127
						$this->trap_data['source_name'].=','.$rule['host_name'];
1128
					}
1129
				}
1130
			}
1131
			catch (Exception $e) 
1132
			{ 
1133
			    $this->logging->log('Error in rule eval : '.$e->getMessage(),WARN,'');
1134
			    $this->trap_action.=' ERR : '.$e->getMessage();
1135
			    $this->trap_data['status']='error';
1136
			}
1137
			
1138
		}
1139
		if ($this->trap_data['status']=='error')
1140
		{
1141
		  $this->trap_to_db=true; // Always put errors in DB for the use can see
1142
		}
1143
		else
1144
		{
1145
		  $this->trap_data['status']='done';
1146
		}
1147
	}
1148
1149
	/** Add Time a action to rule
1150
	*	@param string $time : time to process to insert in SQL
1151
	*/
1152
	public function add_rule_final($time)
1153
	{
1154
		$db_conn=$this->trapsDB->db_connect_trap();
1155
		if ($this->trap_action==null) 
1156
		{
1157
			$this->trap_action='No action';
1158
		}
1159
		$sql="UPDATE ".$this->db_prefix."received SET process_time = '".$time."' , status_detail='".$this->trap_action."'  WHERE (id = '".$this->trap_id."');";
1160
		if ($db_conn->query($sql) === false) {
1161
			$this->logging->log('Error in update query : ' . $sql,WARN,'');
1162
		}
1163
	}
1164
	
1165
	/*********** UTILITIES *********************/
1166
	
1167
	/** Create database schema 
1168
	*	@param $schema_file	string File to read schema from
1169
	*	@param $table_prefix string to replace #PREFIX# in schema file by this
1170
	*/
1171
	public function create_schema($schema_file,$table_prefix)
1172
	{
1173
		//Read data from snmptrapd from stdin
1174
		$input_stream=fopen($schema_file, 'r');
1175
1176
		if ($input_stream=== false)
1177
		{
1178
			$this->logging->log("Error reading schema !",ERROR,''); 
1179
			return;
1180
		}
1181
		$newline='';
1182
		$cur_table='';
1183
		$cur_table_array=array();
1184
		$db_conn=$this->trapsDB->db_connect_trap();
1185
		
1186
		while (($line=fgets($input_stream)) !== false)
1187
		{
1188
			$newline.=chop(preg_replace('/#PREFIX#/',$table_prefix,$line));
1189
			if (preg_match('/; *$/', $newline)) 
1190
            {
1191
                $sql= $newline;
1192
                if ($db_conn->query($sql) === false) {
1193
                    $this->logging->log('Error create schema : '.$sql,ERROR,'');
1194
                }
1195
                if (preg_match('/^ *CREATE TABLE ([^ ]+)/',$newline,$cur_table_array))
1196
                {
1197
                    $cur_table='table '.$cur_table_array[1];
1198
                }
1199
                else
1200
                {
1201
                    $cur_table='secret SQL stuff :-)';
1202
                }
1203
                $this->logging->log('Creating : ' . $cur_table,INFO );
1204
                $newline='';
1205
            }
1206
		}
1207
		
1208
		$sql= $newline;
1209
		if ($sql != '')
1210
		{
1211
    		if ($db_conn->query($sql) === false) {
1212
    			$this->logging->log('Error create schema : '.$sql,ERROR,'');
1213
    		}
1214
		}
1215
		$this->logging->log('Schema created',INFO);		
1216
	}
1217
1218
	/** 
1219
	 * Update database schema from current (as set in db) to $target_version
1220
	 *     @param $prefix string file prefix of sql update File
1221
	 *     @param $target_version int target db version number
1222
	 *     @param $table_prefix string to replace #PREFIX# in schema file by this
1223
	 *     @param bool $getmsg : only get messages from version upgrades
1224
	 *     @return string : if $getmsg=true, return messages.
1225
	 */
1226
	public function update_schema($prefix,$target_version,$table_prefix,$getmsg=false)
1227
	{
1228
	    // Get current db number
1229
	    $db_conn=$this->trapsDB->db_connect_trap();
1230
	    $sql='SELECT id,value from '.$this->db_prefix.'db_config WHERE name=\'db_version\' ';
1231
	    $this->logging->log('SQL query : '.$sql,DEBUG );
1232
	    if (($ret_code=$db_conn->query($sql)) === false) {
1233
	        $this->logging->log('Cannot get db version. Query : ' . $sql,2,'');
1234
	        return;
1235
	    }
1236
	    $version=$ret_code->fetchAll();
1237
	    $cur_version=$version[0]['value'];
1238
	    $db_version_id=$version[0]['id'];
1239
	    
1240
	    if ($this->trapsDB->trapDBType == 'pgsql')
1241
	    {
1242
	        $prefix .= 'update_pgsql/schema_';
1243
	    }
1244
	    else
1245
	    {
1246
	        $prefix .= 'update_sql/schema_';
1247
	    }
1248
	    //echo "version all :\n";print_r($version);echo " \n $cur_ver \n";
1249
	    if ($getmsg === true)
1250
	    {
1251
	        $message='';
1252
	        $this->logging->log('getting message for upgrade',DEBUG );
1253
	        while($cur_version<$target_version)
1254
	        {
1255
	            $cur_version++;
1256
	            $updateFile=$prefix.'v'.($cur_version-1).'_v'.$cur_version.'.sql';
1257
	            $input_stream=fopen($updateFile, 'r');
1258
	            if ($input_stream=== false)
1259
	            {
1260
	                $this->logging->log("Error reading update file ". $updateFile,2,'');
1261
	                return;
1262
	            }
1263
	            do { $line=fgets($input_stream); }
1264
	            while ($line !== false && !preg_match('/#MESSAGE/',$line));
1265
	            if ($line === false)
1266
	            {
1267
	                $this->logging->log("No message in file ". $updateFile,2,'');
1268
	                return;
1269
	            }
1270
	            $message .= ($cur_version-1) . '->' . $cur_version. ' : ' . preg_replace('/#MESSAGE : /','',$line)."\n";
1271
	        }
1272
	        return $message;
1273
	    }
1274
	    while($cur_version<$target_version)
1275
	    { // tODO : execute pre & post scripts
1276
	       $cur_version++;
1277
	       $this->logging->log('Updating to version : ' .$cur_version ,INFO );
1278
	       $updateFile=$prefix.'v'.($cur_version-1).'_v'.$cur_version.'.sql';
1279
	       $input_stream=fopen($updateFile, 'r');
1280
	       if ($input_stream=== false)
1281
	       {
1282
	           $this->logging->log("Error reading update file ". $updateFile,2,'');
1283
	           return;
1284
	       }
1285
	       $newline='';
1286
	       $db_conn=$this->trapsDB->db_connect_trap();
1287
	       $db_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
1288
	       while (($line=fgets($input_stream)) !== false)
1289
	       {
1290
	           if (preg_match('/^#/', $line)) continue; // ignore comment lines
1291
	           $newline.=chop(preg_replace('/#PREFIX#/',$table_prefix,$line));
1292
	           if (preg_match('/; *$/', $newline))
1293
	           {
1294
	               $sql_req=$db_conn->prepare($newline);
1295
	               if ($sql_req->execute() === false) {
1296
	                   $this->logging->log('Error create schema : '.$newline,1,'');
1297
	               }
1298
	               $cur_table_array=array();
1299
	               if (preg_match('/^ *([^ ]+) TABLE ([^ ]+)/',$newline,$cur_table_array))
1300
	               {
1301
	                   $cur_table=$cur_table_array[1] . ' SQL table '.$cur_table_array[2];
1302
	               }
1303
	               else
1304
	               {
1305
	                   $cur_table='secret SQL stuff :-)';
1306
	                   //$cur_table=$newline;
1307
	               }
1308
	               $this->logging->log('Doing : ' . $cur_table,INFO );
1309
	               
1310
	               $newline='';
1311
	           }
1312
	       }
1313
	       fclose($input_stream);
1314
	       
1315
	       //$sql= $newline;
1316
	       //if ($db_conn->query($sql) === false) {
1317
	       //    $this->logging->log('Error updating schema : '.$sql,1,'');
1318
	       //}
1319
	       
1320
	       $sql='UPDATE '.$this->db_prefix.'db_config SET value='.$cur_version.' WHERE ( id = '.$db_version_id.' )';
1321
	       $this->logging->log('SQL query : '.$sql,DEBUG );
1322
	       if ($db_conn->query($sql) === false) {
1323
	           $this->logging->log('Cannot update db version. Query : ' . $sql,2);
1324
	           return;
1325
	       }
1326
	       
1327
	       $this->logging->log('Schema updated to version : '.$cur_version ,INFO);
1328
	    }
1329
	}
1330
	
1331
	/** reset service to OK after time defined in rule
1332
	*	TODO logic is : get all service in error + all rules, see if getting all rules then select services is better 
1333
	*	@return : like a plugin : status code (0->3) <message> | <perfdata>
0 ignored issues
show
Documentation Bug introduced by
The doc comment : like at position 0 could not be parsed: Unknown type name ':' at position 0 in : like.
Loading history...
1334
	**/
1335
	public function reset_services()
1336
	{
1337
		// Get all services not in 'ok' state
1338
		$sql_query="SELECT s.service_object_id,
1339
	 UNIX_TIMESTAMP(s.last_check) AS last_check,
1340
	s.current_state as state,
1341
	v.name1 as host_name,
1342
    v.name2 as service_name
1343
	FROM icinga_servicestatus AS s 
1344
    LEFT JOIN icinga_objects as v ON s.service_object_id=v.object_id
1345
    WHERE s.current_state != 0;";
1346
		$db_conn=$this->trapsDB->db_connect_ido();
1347
		if (($services_db=$db_conn->query($sql_query)) === false) { // set err to 1 to throw exception.
1348
			$this->logging->log('No result in query : ' . $sql_query,ERROR,'');
1349
		}
1350
		$services=$services_db->fetchAll();
1351
		
1352
		// Get all rules
1353
		$sql_query="SELECT host_name, service_name, revert_ok FROM ".$this->db_prefix."rules where revert_ok != 0;";
1354
		$db_conn2=$this->trapsDB->db_connect_trap();
1355
		if (($rules_db=$db_conn2->query($sql_query)) === false) {
1356
			$this->logging->log('No result in query : ' . $sql_query,ERROR,''); 
1357
		}
1358
		$rules=$rules_db->fetchAll();
1359
		
1360
		$now=date('U');
1361
		
1362
		$numreset=0;
1363
		foreach ($rules as $rule)
1364
		{
1365
			foreach ($services as $service)
1366
			{
1367
				if ($service['service_name'] == $rule['service_name'] &&
1368
					$service['host_name'] == $rule['host_name'] &&
1369
					($service['last_check'] + $rule['revert_ok']) < $now)
1370
				{
1371
					$this->serviceCheckResult($service['host_name'],$service['service_name'],0,'Reset service to OK after '.$rule['revert_ok'].' seconds');
1372
					$numreset++;
1373
				}
1374
			}
1375
		}
1376
		echo "\n";
1377
		echo $numreset . " service(s) reset to OK\n";
1378
		return 0;
1379
		
1380
	}
1381
1382
	
1383
	/*********** MIB cache update functions *********************/
1384
	
1385
	/**
1386
	 * Update or add an OID to database uses $this->dbOidIndex for mem cache
1387
	 * @param string $oid
1388
	 * @param string $mib
1389
	 * @param string $name
1390
	 * @param string $type
1391
	 * @param string $textConv
1392
	 * @param string $dispHint
1393
	 * @param string $syntax
1394
	 * @param string $type_enum
1395
	 * @param string $description
1396
	 * @return number : 0=unchanged, 1 = changed, 2=created
1397
	 */
1398
	public function update_oid($oid,$mib,$name,$type,$textConv,$dispHint,$syntax,$type_enum,$description=NULL)
1399
	{
1400
		$db_conn=$this->trapsDB->db_connect_trap();
1401
		$description=$db_conn->quote($description);
1402
		if (isset($this->dbOidIndex[$oid]))
1403
		{
1404
		    if ($this->dbOidIndex[$oid]['key'] == -1)
1405
		    { // newly created.
1406
		        return 0;
1407
		    }
1408
			if ( $name != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['name'] ||
1409
			    $mib != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['mib'] ||
1410
			    $type != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['type'] //||
1411
			    //$textConv != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['textual_convention'] //||
1412
			    //$dispHint != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['display_hint'] ||
1413
			    //$syntax != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['syntax'] ||
1414
			    //$type_enum != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['type_enum'] ||
1415
			    //$description != $this->dbOidAll[$this->dbOidIndex[$oid]['key']]['description']
1416
			    )
1417
			{ // Do update
1418
			    $sql='UPDATE '.$this->db_prefix.'mib_cache SET '.
1419
 			    'name = :name , type = :type , mib = :mib , textual_convention = :tc , display_hint = :display_hint'. 
1420
 			    ', syntax = :syntax, type_enum = :type_enum, description = :description '.
1421
 			    ' WHERE id= :id';
1422
			    $sqlQuery=$db_conn->prepare($sql);
1423
			    
1424
			    $sqlParam=array(
1425
			        ':name' => $name,
1426
			        ':type' => $type, 
1427
			        ':mib' => $mib, 
1428
			        ':tc' =>  ($textConv==null)?'null':$textConv , 
1429
			        ':display_hint' => ($dispHint==null)?'null':$dispHint ,
1430
			        ':syntax' => ($syntax==null)?'null':$syntax,
1431
			        ':type_enum' => ($type_enum==null)?'null':$type_enum, 
1432
			        ':description' => ($description==null)?'null':$description,
1433
			        ':id' => $this->dbOidAll[$this->dbOidIndex[$oid]['id']]
1434
			    );
1435
			    
1436
			    if ($sqlQuery->execute($sqlParam) === false) {
1437
			        $this->logging->log('Error in query : ' . $sql,ERROR,'');
1438
			    }
1439
			    $this->logging->log('Trap updated : '.$name . ' / OID : '.$oid,DEBUG );
1440
				return 1;
1441
			}
1442
			else
1443
			{
1444
			    $this->logging->log('Trap unchanged : '.$name . ' / OID : '.$oid,DEBUG );
1445
			    return 0;
1446
			}
1447
		}
1448
        // create new OID.
1449
			
1450
		// Insert data
1451
1452
		$sql='INSERT INTO '.$this->db_prefix.'mib_cache '.
1453
		      '(oid, name, type , mib, textual_convention, display_hint '.
1454
              ', syntax, type_enum , description ) ' . 
1455
              'values (:oid, :name , :type ,:mib ,:tc , :display_hint'.
1456
              ', :syntax, :type_enum, :description )';
1457
        
1458
		if ($this->trapsDB->trapDBType == 'pgsql') $sql .= 'RETURNING id';
1459
		
1460
		$sqlQuery=$db_conn->prepare($sql);
1461
		
1462
		$sqlParam=array(
1463
		    ':oid' => $oid,
1464
		    ':name' => $name,
1465
		    ':type' => $type,
1466
		    ':mib' => $mib,
1467
		    ':tc' =>  ($textConv==null)?'null':$textConv ,
1468
		    ':display_hint' => ($dispHint==null)?'null':$dispHint ,
1469
		    ':syntax' => ($syntax==null)?'null':$syntax,
1470
		    ':type_enum' => ($type_enum==null)?'null':$type_enum,
1471
		    ':description' => ($description==null)?'null':$description
1472
		);
1473
		
1474
		if ($sqlQuery->execute($sqlParam) === false) {
1475
		    $this->logging->log('Error in query : ' . $sql,1,'');
1476
		}
1477
		
1478
		switch ($this->trapsDB->trapDBType)
1479
		{
1480
		    case 'pgsql':
1481
		        // Get last id to insert oid/values in secondary table
1482
		        if (($inserted_id_ret=$sqlQuery->fetch(PDO::FETCH_ASSOC)) === false) {		            
1483
		            $this->logging->log('Error getting id - pgsql - ',1,'');
1484
		        }
1485
		        if (! isset($inserted_id_ret['id'])) {
1486
		            $this->logging->log('Error getting id - pgsql - empty.',1,'');
1487
		        }
1488
		        $this->dbOidIndex[$oid]['id']=$inserted_id_ret['id'];
1489
		        break;
1490
		    case 'mysql':
1491
		        // Get last id to insert oid/values in secondary table
1492
		        $sql='SELECT LAST_INSERT_ID();';
1493
		        if (($ret_code=$db_conn->query($sql)) === false) {
1494
		            $this->logging->log('Erreur getting id - mysql - ',1,'');
1495
		        }
1496
		        
1497
		        $inserted_id=$ret_code->fetch(PDO::FETCH_ASSOC)['LAST_INSERT_ID()'];
1498
		        if ($inserted_id==false) throw new Exception("Weird SQL error : last_insert_id returned false : open issue");
1499
		        $this->dbOidIndex[$oid]['id']=$inserted_id;
1500
		        break;
1501
		    default:
1502
		        $this->logging->log('Error SQL type Unknown : '.$this->trapsDB->trapDBType,1,'');
1503
		}
1504
1505
		// Set as newly created.
1506
		$this->dbOidIndex[$oid]['key']=-1;
1507
		return 2;
1508
	}
1509
1510
    /**
1511
     * create or update (with check_existing = true) objects of trap
1512
     * @param string $trapOID : trap oid
1513
     * @param string $trapmib : mib of trap
1514
     * @param array $objects : array of objects name (without MIB)
1515
     * @param bool $check_existing : check instead of create
1516
     */
1517
	public function trap_objects($trapOID,$trapmib,$objects,$check_existing)
1518
	{
1519
	    $dbObjects=null; // cache of objects for trap in db
1520
	    $db_conn=$this->trapsDB->db_connect_trap();
1521
	    
1522
	    // Get id of trapmib.
1523
1524
	    $trapId = $this->dbOidIndex[$trapOID]['id'];
1525
	    if ($check_existing === true)
1526
	    {
1527
	        // Get all objects
1528
	        $sql='SELECT * FROM '.$this->db_prefix.'mib_cache_trap_object where trap_id='.$trapId.';';
1529
	        $this->logging->log('SQL query get all traps: '.$sql,DEBUG );
1530
	        if (($ret_code=$db_conn->query($sql)) === false) {
1531
	            $this->logging->log('No result in query : ' . $sql,1,'');
1532
	        }
1533
	        $dbObjectsRaw=$ret_code->fetchAll();
1534
	        
1535
	        foreach ($dbObjectsRaw as $val)
1536
	        {
1537
	            $dbObjects[$val['object_id']]=1;
1538
	        }
1539
	    }
1540
	    foreach ($objects as $object)
1541
	    {
1542
	        $match=$snmptrans=array();
1543
	        $retVal=0;
1544
	        $objOid=$objTc=$objDispHint=$objSyntax=$objDesc=$objEnum=NULL;
1545
	        $tmpdesc='';$indesc=false;
1546
	        
1547
	        $objMib=$trapmib;
1548
	        exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.
1549
	            ' -On -Td '.$objMib.'::'.$object . ' 2>/dev/null',$snmptrans,$retVal);
1550
	        if ($retVal!=0)
1551
	        {
1552
	            // Maybe not trap mib, search with IR
1553
	            exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.
1554
	                ' -IR '.$object . ' 2>/dev/null',$snmptrans,$retVal);
1555
	            if ($retVal != 0 || !preg_match('/(.*)::(.*)/',$snmptrans[0],$match))
1556
	            { // Not found -> continue with warning
1557
	               $this->logging->log('Error finding trap object : '.$trapmib.'::'.$object,2,'');
1558
	               continue;
1559
	            }
1560
	            $objMib=$match[1];
1561
	            
1562
	            // Do the snmptranslate again.
1563
	            exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.
1564
	                ' -On -Td '.$objMib.'::'.$object,$snmptrans,$retVal);
1565
	            if ($retVal!=0) {
1566
	                $this->logging->log('Error finding trap object : '.$objMib.'::'.$object,2,'');
1567
	            }
1568
	            
1569
	        }
1570
	        foreach ($snmptrans as $line)
1571
	        {
1572
	            if ($indesc===true)
1573
	            {
1574
	                $line=preg_replace('/[\t ]+/',' ',$line);
1575
	                if (preg_match('/(.*)"$/', $line,$match))
1576
	                {
1577
	                    $objDesc = $tmpdesc . $match[1];
1578
	                    $indesc=false;
1579
	                }
1580
	                $tmpdesc.=$line;
1581
	                continue;
1582
	            }
1583
	            if (preg_match('/^\.[0-9\.]+$/', $line))
1584
	            {
1585
	                $objOid=$line;
1586
	                continue;
1587
	            }
1588
	            if (preg_match('/^[\t ]+SYNTAX[\t ]+([^{]*) \{(.*)\}/',$line,$match))
1589
	            {
1590
	                $objSyntax=$match[1];
1591
                    $objEnum=$match[2];
1592
	                continue;
1593
	            }
1594
	            if (preg_match('/^[\t ]+SYNTAX[\t ]+(.*)/',$line,$match))
1595
	            {
1596
	                $objSyntax=$match[1];
1597
	                continue;
1598
	            }
1599
	            if (preg_match('/^[\t ]+DISPLAY-HINT[\t ]+"(.*)"/',$line,$match))
1600
	            {
1601
	                $objDispHint=$match[1];
1602
	                continue;
1603
	            }
1604
	            if (preg_match('/^[\t ]+DESCRIPTION[\t ]+"(.*)"/',$line,$match))
1605
	            {
1606
	                $objDesc=$match[1];
1607
	                continue;
1608
	            }
1609
	            if (preg_match('/^[\t ]+DESCRIPTION[\t ]+"(.*)/',$line,$match))
1610
	            {
1611
	                $tmpdesc=$match[1];
1612
	                $indesc=true;
1613
	                continue;
1614
	            }
1615
	            if (preg_match('/^[\t ]+-- TEXTUAL CONVENTION[\t ]+(.*)/',$line,$match))
1616
	            {
1617
	                $objTc=$match[1];
1618
	                continue;
1619
	            }
1620
	        }
1621
	        $this->logging->log("Adding trap $object : $objOid / $objSyntax / $objEnum / $objDispHint / $objTc",DEBUG );
1622
	        //echo "$object : $objOid / $objSyntax / $objEnum / $objDispHint / $objTc / $objDesc\n";
1623
	        // Update 
1624
	        $this->update_oid($objOid, $objMib, $object, '3', $objTc, $objDispHint, $objSyntax, $objEnum,$objDesc);
1625
            
1626
	        if (isset($dbObjects[$this->dbOidIndex[$objOid]['id']]))
1627
	        {   // if link exists, continue
1628
	            $dbObjects[$this->dbOidIndex[$objOid]['id']]=2;
1629
	            continue;
1630
	        }
1631
	        if ($check_existing === true) 
1632
	        {
1633
	            // TODO : check link trap - objects exists, mark them.
1634
	        }
1635
	        // Associate in object table
1636
	        $sql='INSERT INTO '.$this->db_prefix.'mib_cache_trap_object (trap_id,object_id) '.
1637
	   	        'values (:trap_id, :object_id)';	        
1638
	        $sqlQuery=$db_conn->prepare($sql);	        
1639
	        $sqlParam=array(
1640
	            ':trap_id' => $trapId,
1641
	            ':object_id' => $this->dbOidIndex[$objOid]['id'],
1642
	        );
1643
	        
1644
	        if ($sqlQuery->execute($sqlParam) === false) {
1645
	            $this->logging->log('Error adding trap object : ' . $sql . ' / ' . $trapId . '/'. $this->dbOidIndex[$objOid]['id'] ,1,'');
1646
	        }
1647
	    }
1648
	    if ($check_existing === true)
1649
	    {
1650
	        // TODO : remove link trap - objects that wasn't marked.
1651
	    }
1652
	    
1653
	}
1654
	
1655
	/** 
1656
	 * Cache mib in database
1657
	 * @param boolean $display_progress : Display progress on standard output
1658
	 * @param boolean $check_change : Force check of trap params & objects
1659
	 * @param boolean $onlyTraps : only cache traps and objects (true) or all (false)
1660
	 * @param string $startOID : only cache under startOID (NOT IMPLEMENTED)
1661
	*/	
1662
	public function update_mib_database($display_progress=false,$check_change=false,$onlyTraps=true,$startOID='.1')
0 ignored issues
show
Unused Code introduced by
The parameter $startOID is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1662
	public function update_mib_database($display_progress=false,$check_change=false,$onlyTraps=true,/** @scrutinizer ignore-unused */ $startOID='.1')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1663
	{
1664
		// Timing 
1665
		$timeTaken = microtime(true);
1666
		$retVal=0;
1667
		// Get all mib objects from all mibs
1668
		$snmpCommand=$this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.' -On -Tto 2>/dev/null';
1669
		$this->logging->log('Getting all traps : '.$snmpCommand,DEBUG );
1670
		unset($this->objectsAll);
1671
		exec($snmpCommand,$this->objectsAll,$retVal);		
1672
		if ($retVal!=0)
1673
		{
1674
			$this->logging->log('error executing snmptranslate',ERROR,'');
1675
		}
1676
		
1677
		// Get all mibs from databse to have a memory index
1678
		
1679
		$db_conn=$this->trapsDB->db_connect_trap();
1680
		
1681
		$sql='SELECT * from '.$this->db_prefix.'mib_cache;';
1682
		$this->logging->log('SQL query : '.$sql,DEBUG );
1683
		if (($ret_code=$db_conn->query($sql)) === false) {
1684
			$this->logging->log('No result in query : ' . $sql,ERROR,'');
1685
		}
1686
		$this->dbOidAll=$ret_code->fetchAll();
1687
		$this->dbOidIndex=array();
1688
		// Create the index for db;
1689
		foreach($this->dbOidAll as $key=>$val)
1690
		{
1691
			$this->dbOidIndex[$val['oid']]['key']=$key;
1692
			$this->dbOidIndex[$val['oid']]['id']=$val['id'];
1693
		}
1694
		
1695
		// Count elements to show progress
1696
		$numElements=count($this->objectsAll);
1697
		$this->logging->log('Total snmp objects returned by snmptranslate : '.$numElements,INFO );
1698
		
1699
		$step=$basestep=$numElements/10; // output display of % done
1700
		$num_step=0;
1701
		$timeFiveSec = microtime(true); // Used for display a '.' every <n> seconds
1702
		
1703
		// Create index for trap objects
1704
		$this->trapObjectsIndex=array();
1705
		
1706
		// detailed timing (time_* vars)
1707
		$time_parse1=$time_check1=$time_check2=$time_check3=$time_update=$time_objects=0;
1708
		$time_parse1N=$time_check1N=$time_check2N=$time_check3N=$time_updateN=$time_objectsN=0;
1709
		$time_num_traps=0;
1710
		
1711
		for ($curElement=0;$curElement < $numElements;$curElement++)
1712
		{
1713
		    $time_1= microtime(true);
1714
			if ((microtime(true)-$timeFiveSec) > 2 && $display_progress)
1715
			{ // echo a . every 2 sec
1716
				echo '.';
1717
				$timeFiveSec = microtime(true);
1718
			}
1719
			if ($curElement>$step) 
1720
			{ // display progress
1721
				$num_step++;
1722
				$step+=$basestep;
1723
				if ($display_progress)
1724
				{				
1725
					echo "\n" . ($num_step*10). '% : ';
1726
				}
1727
			}
1728
			// Get oid or pass if not found
1729
			if (!preg_match('/^\.[0-9\.]+$/',$this->objectsAll[$curElement]))
1730
			{
1731
			    $time_parse1 += microtime(true) - $time_1;
1732
			    $time_parse1N ++;
1733
				continue;
1734
			}
1735
			$oid=$this->objectsAll[$curElement];
1736
			
1737
			// get next line 
1738
			$curElement++;
1739
			$match=$snmptrans=array();
1740
			if (!preg_match('/ +([^\(]+)\(.+\) type=([0-9]+)( tc=([0-9]+))?( hint=(.+))?/',
1741
						$this->objectsAll[$curElement],$match))
1742
			{
1743
			    $time_check1 += microtime(true) - $time_1;
1744
				$time_check1N++;
1745
				continue;
1746
			}
1747
			
1748
			$name=$match[1]; // Name 
1749
			$type=$match[2]; // type (21=trap, 0: may be trap, else : not trap
1750
			
1751
			if ($type==0) // object type=0 : check if v1 trap
1752
			{
1753
				// Check if next is suboid -> in that case is cannot be a trap
1754
				if (preg_match("/^$oid/",$this->objectsAll[$curElement+1]))
1755
				{
1756
				    $time_check2 += microtime(true) - $time_1;
1757
				    $time_check2N++;
1758
					continue;
1759
				}		
1760
				unset($snmptrans);
1761
				exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.
1762
					' -Td '.$oid . ' | grep OBJECTS ',$snmptrans,$retVal);
1763
				if ($retVal!=0)
1764
				{
1765
				    $time_check2 += microtime(true) - $time_1;
1766
				    $time_check2N++;
1767
					continue;
1768
				}
1769
				//echo "\n v1 trap found : $oid \n";
1770
				// Force as trap.
1771
				$type=21;
1772
			}
1773
			if ($onlyTraps===true && $type!=21) // if only traps and not a trap, continue
1774
			{
1775
			    $time_check3 += microtime(true) - $time_1;
1776
				$time_check3N++;
1777
				continue;
1778
			}
1779
			
1780
			$time_num_traps++;
1781
			
1782
			$this->logging->log('Found trap : '.$match[1] . ' / OID : '.$oid,INFO );
1783
			if ($display_progress) echo '#'; // echo a # when trap found
1784
				
1785
			// get trap objects & source MIB
1786
			unset($snmptrans);
1787
			exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslate_dirs.
1788
					' -Td '.$oid,$snmptrans,$retVal);
1789
			if ($retVal!=0)
1790
			{
1791
				$this->logging->log('error executing snmptranslate',ERROR,'');
1792
			}
1793
			
1794
			if (!preg_match('/^(.*)::/',$snmptrans[0],$match))
1795
			{
1796
			    $this->logging->log('Error getting mib from trap '.$oid.' : ' . $snmptrans[0],1,'');
1797
			}
1798
			$trapMib=$match[1];
1799
			
1800
			$numLine=1;$trapDesc='';
1801
			while (isset($snmptrans[$numLine]) && !preg_match('/^[\t ]+DESCRIPTION[\t ]+"(.*)/',$snmptrans[$numLine],$match)) $numLine++;
1802
			if (isset($snmptrans[$numLine]))
1803
			{
1804
			    $snmptrans[$numLine] = preg_replace('/^[\t ]+DESCRIPTION[\t ]+"/','',$snmptrans[$numLine]);
1805
1806
			    while (isset($snmptrans[$numLine]) && !preg_match('/"/',$snmptrans[$numLine]))
1807
			    {
1808
			        $trapDesc.=preg_replace('/[\t ]+/',' ',$snmptrans[$numLine]);
1809
			        $numLine++;
1810
			    }
1811
			    if (isset($snmptrans[$numLine])) {
1812
			        $trapDesc.=preg_replace('/".*/','',$snmptrans[$numLine]);
1813
			        $trapDesc=preg_replace('/[\t ]+/',' ',$trapDesc);
1814
			    }
1815
1816
			}
1817
			$update=$this->update_oid($oid,$trapMib,$name,$type,NULL,NULL,NULL,NULL,$trapDesc);
1818
			$time_update += microtime(true) - $time_1; $time_1= microtime(true);
1819
			
1820
			if (($update==0) && ($check_change===false))
1821
			{ // Trapd didn't change & force check disabled
1822
			    $time_objects += microtime(true) - $time_1;
1823
			    if ($display_progress) echo "C";
1824
			    continue;
1825
			}
1826
			
1827
			$synt=null;
1828
			foreach ($snmptrans as $line)
1829
			{	
1830
    			if (preg_match('/OBJECTS.*\{([^\}]+)\}/',$line,$match))
1831
    				{
1832
    					$synt=$match[1];
1833
    				}
1834
			}
1835
			if ($synt == null) 
1836
			{
1837
				//echo "No objects for $trapOID\n";
1838
			    $time_objects += microtime(true) - $time_1;
1839
				continue;
1840
			}
1841
			//echo "$synt \n";
1842
			$trapObjects=array();
1843
			while (preg_match('/ *([^ ,]+) *,* */',$synt,$match))
1844
			{
1845
				array_push($trapObjects,$match[1]);
1846
				$synt=preg_replace('/'.$match[0].'/','',$synt);
1847
			}
1848
			
1849
			$this->trap_objects($oid, $trapMib, $trapObjects, false);
1850
			
1851
			$time_objects += microtime(true) - $time_1;
1852
			$time_objectsN++;
1853
		}
1854
		
1855
		if ($display_progress)
1856
		{
1857
    		echo "\nNumber of processed traps : $time_num_traps \n";
1858
    		echo "\nParsing : " . number_format($time_parse1+$time_check1,1) ." sec / " . ($time_parse1N+ $time_check1N)  . " occurences\n";
1859
    		echo "Detecting traps : " . number_format($time_check2+$time_check3,1) . " sec / " . ($time_check2N+$time_check3N) ." occurences\n";
1860
    		echo "Trap processing ($time_updateN): ".number_format($time_update,1)." sec , ";
1861
    		echo "Objects processing ($time_objectsN) : ".number_format($time_objects,1)." sec \n";
1862
		}
1863
		
1864
		// Timing ends
1865
		$timeTaken=microtime(true) - $timeTaken;
1866
		if ($display_progress)
1867
		{
1868
		    echo "Global time : ".round($timeTaken)." seconds\n";
1869
		}
1870
		
1871
	}
1872
	
1873
}
1874
1875
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...