Mib   F
last analyzed

Complexity

Total Complexity 68

Size/Duplication

Total Lines 530
Duplicated Lines 0 %

Importance

Changes 9
Bugs 3 Features 0
Metric Value
eloc 253
c 9
b 3
f 0
dl 0
loc 530
rs 2.96
wmc 68

14 Methods

Rating   Name   Duplication   Size   Complexity  
B parse_object() 0 55 11
B detect_trap() 0 55 8
B trap_objects() 0 51 8
A getTrapsDB() 0 3 1
B get_trap_mib_description() 0 37 9
A reset_update_timers() 0 15 1
C update_mib_database() 0 89 12
A __construct() 0 6 1
A load_mibs_snmptranslate() 0 16 2
A getLogging() 0 3 1
A get_trap_objects() 0 25 5
A get_object_details() 0 29 5
A load_mibs_from_db() 0 18 3
A reset_oidDesc() 0 11 1

How to fix   Complexity   

Complex Class

Complex classes like Mib often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Mib, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Trapdirector;
4
5
6
/**
7
 * MIB queries and update
8
 * 
9
 * @license GPL
10
 * @author Patrick Proy
11
 * @package trapdirector
12
 * @subpackage Processing
13
 *
14
 */
15
class Mib
16
{
17
    use \MibDatabase;
0 ignored issues
show
introduced by
The trait MibDatabase requires some properties which are not provided by Trapdirector\Mib: $dbPrefix, $trapDBType
Loading history...
18
    
19
    /** @var Logging $logging logging class */
20
    protected $logging;
21
    /** @var Database $trapsDB Database class */
22
    protected $trapsDB;
23
    
24
    /** @var string $snmptranslate */
25
    public $snmptranslate;
26
    /** @var string $snmptranslateDirs */
27
    public $snmptranslateDirs;
28
    
29
    private $dbOidAll; //< All oid in database;
30
    private $dbOidIndex; //< Index of oid in dbOidAll
31
    private $objectsAll; //< output lines of snmptranslate list
32
    private $trapObjectsIndex; //< array of traps objects (as OID)
33
    
34
    private $oidDesc=array(); //< $oid,$mib,$name,$type,$textConv,$dispHint,$syntax,$type_enum,$description=NULL
35
36
    // Timing vars for update
37
    private $timing=array();
38
    
39
    /**
40
     * Setup Mib Class
41
     * @param Logging $logClass : where to log
42
     * @param Database $dbClass : Database
43
     */
44
    function __construct($logClass,$dbClass,$snmptrans,$snmptransdir)
45
    {
46
        $this->logging=$logClass;
47
        $this->trapsDB=$dbClass;
48
        $this->snmptranslate=$snmptrans;
49
        $this->snmptranslateDirs=$snmptransdir;
50
51
    }
52
    
53
    /**
54
     * @return \Trapdirector\Logging
55
     */
56
    public function getLogging()
57
    {
58
        return $this->logging;
59
    }
60
61
    /**
62
     * @return \Trapdirector\Database
63
     */
64
    public function getTrapsDB()
65
    {
66
        return $this->trapsDB;
67
    }
68
69
/**
70
 * Get object details & mib , returns snmptranslate output
71
 * @param string $object : object name
72
 * @param string $trapmib : mib of trap
73
 * @return NULL|array : null if not found, or output of snmptranslate
74
 */
75
    private function get_object_details($object,$trapmib)
76
    {
77
        $match=$snmptrans=array();
78
        $retVal=0;
79
        $this->oidDesc['mib']=$trapmib;
80
        exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslateDirs.
81
            ' -On -Td '.$this->oidDesc['mib'].'::'.$object . ' 2>/dev/null',$snmptrans,$retVal);
82
        if ($retVal!=0)
83
        {
84
            // Maybe not trap mib, search with IR
85
            exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslateDirs.
86
                ' -IR '.$object . ' 2>/dev/null',$snmptrans,$retVal);
87
            if ($retVal != 0 || !preg_match('/(.*)::(.*)/',$snmptrans[0],$match))
88
            { // Not found -> continue with warning
89
                $this->logging->log('Error finding trap object : '.$trapmib.'::'.$object,2,'');
90
                return null;
91
            }
92
            $this->oidDesc['mib']=$match[1];
93
            
94
            // Do the snmptranslate again.
95
            exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslateDirs.
96
                ' -On -Td '.$this->oidDesc['mib'].'::'.$object,$snmptrans,$retVal);
97
            if ($retVal!=0) {
98
                $this->logging->log('Error finding trap object : '.$this->oidDesc['mib'].'::'.$object,2,'');
99
                return null;
100
            }
101
            
102
        }
103
        return $snmptrans;
104
    }
105
106
/**
107
 * Parse snmptranslate output and set  $this->oidDesc with elements 
108
 * @param array $snmptrans : multi line output of snmptrans
109
 */
110
    private function parse_object($snmptrans)
111
    {
112
        $tmpdesc=''; // For multiline description
113
        $indesc=false; // true if currently inside multiline description
114
        $match=array();
115
        
116
        foreach ($snmptrans as $line)
117
        {
118
            if ($indesc===true)
119
            {
120
                $line=preg_replace('/[\t ]+/',' ',$line);
121
                if (preg_match('/(.*)"$/', $line,$match))
122
                {
123
                    $this->oidDesc['description'] = $tmpdesc . $match[1];
124
                    $indesc=false;
125
                }
126
                $tmpdesc.=$line;
127
                continue;
128
            }
129
            if (preg_match('/^\.[0-9\.]+$/', $line))
130
            {
131
                $this->oidDesc['oid']=$line;
132
                continue;
133
            }
134
            if (preg_match('/^[\t ]+SYNTAX[\t ]+([^{]*) \{(.*)\}/',$line,$match))
135
            {
136
                $this->oidDesc['syntax']=$match[1];
137
                $this->oidDesc['type_enum']=$match[2];
138
                continue;
139
            }
140
            if (preg_match('/^[\t ]+SYNTAX[\t ]+(.*)/',$line,$match))
141
            {
142
                $this->oidDesc['syntax']=$match[1];
143
                continue;
144
            }
145
            if (preg_match('/^[\t ]+DISPLAY-HINT[\t ]+"(.*)"/',$line,$match))
146
            {
147
                $this->oidDesc['dispHint']=$match[1];
148
                continue;
149
            }
150
            if (preg_match('/^[\t ]+DESCRIPTION[\t ]+"(.*)"/',$line,$match))
151
            {
152
                $this->oidDesc['description']=$match[1];
153
                continue;
154
            }
155
            if (preg_match('/^[\t ]+DESCRIPTION[\t ]+"(.*)/',$line,$match))
156
            {
157
                $tmpdesc=$match[1];
158
                $indesc=true;
159
                continue;
160
            }
161
            if (preg_match('/^[\t ]+-- TEXTUAL CONVENTION[\t ]+(.*)/',$line,$match))
162
            {
163
                $this->oidDesc['textconv']=$match[1];
164
                continue;
165
            }
166
        }
167
    }
168
169
    /**
170
     * create or update (with check_existing = true) objects of trap
171
     * @param string $trapOID : trap oid
172
     * @param string $trapmib : mib of trap
173
     * @param array $objects : array of objects name (without MIB)
174
     * @param bool $check_existing : check instead of create
175
     */
176
    public function trap_objects($trapOID,$trapmib,$objects,$check_existing)
177
    {              
178
        $trapId = $this->dbOidIndex[$trapOID]['id']; // Get id of trap
179
        
180
        if ($check_existing === true)
181
        {
182
            $dbObjects=$this->cache_db_objects($trapId);
183
        }
184
        
185
        foreach ($objects as $object)
186
        {
187
            
188
            $this->reset_oidDesc();
189
            
190
            $snmptrans=$this->get_object_details($object, $trapmib); // Get object mib & details
191
            if ($snmptrans === null) continue; // object not found
192
            
193
            $this->parse_object($snmptrans);
194
195
            $this->oidDesc['name'] = $object;
196
            
197
            $this->logging->log("Adding object ".$this->oidDesc['name']." : ".$this->oidDesc['oid']." / ".$this->oidDesc['syntax']." / ".$this->oidDesc['type_enum']." / ".$this->oidDesc['dispHint']." / ".$this->oidDesc['textconv'],DEBUG );
198
199
            // Update
200
            $this->update_oid();
201
            
202
            if (isset($dbObjects[$this->dbOidIndex[$this->oidDesc['oid']]['id']]))
203
            {   // if link exists, continue
204
                $dbObjects[$this->dbOidIndex[$this->oidDesc['oid']]['id']]=2;
205
                continue;
206
            }
207
            if ($check_existing === true)
208
            {
209
                // TODO : check link trap - objects exists, mark them.
210
            }
211
            // Associate in object table
212
            $db_conn=$this->trapsDB->db_connect_trap();
213
            $sql='INSERT INTO '.$this->trapsDB->dbPrefix.'mib_cache_trap_object (trap_id,object_id) '.
214
                'values (:trap_id, :object_id)';
215
            $sqlQuery=$db_conn->prepare($sql);
216
            $sqlParam=array(
217
                ':trap_id' => $trapId,
218
                ':object_id' => $this->dbOidIndex[$this->oidDesc['oid']]['id'],
219
            );
220
            
221
            if ($sqlQuery->execute($sqlParam) === false) {
222
                $this->logging->log('Error adding trap object : ' . $sql . ' / ' . $trapId . '/'. $this->dbOidIndex[$this->oidDesc['oid']]['id'] ,1,'');
223
            }
224
        }
225
        if ($check_existing === true)
226
        {
227
            // TODO : remove link trap - objects that wasn't marked.
228
        }
229
        
230
    }
231
232
    private function reset_oidDesc()
233
    {
234
        $this->oidDesc['oid']=null;
235
        $this->oidDesc['name']=null;
236
        $this->oidDesc['type']=null;
237
        $this->oidDesc['mib']=null;
238
        $this->oidDesc['textconv']=null;
239
        $this->oidDesc['dispHint'] =null;
240
        $this->oidDesc['syntax']=null;
241
        $this->oidDesc['type_enum']=null;
242
        $this->oidDesc['description']=null;
243
    }
244
    
245
    /**
246
     * Fills $this->objectsAll with all mibs from snmptranslate
247
     * @return integer : number of elements 
248
     */
249
    private function load_mibs_snmptranslate()
250
    {
251
        $retVal=0;
252
        // Get all mib objects from all mibs
253
        $snmpCommand=$this->snmptranslate . ' -m ALL -M +'.$this->snmptranslateDirs.' -On -Tto 2>/dev/null';
254
        $this->logging->log('Getting all traps : '.$snmpCommand,DEBUG );
255
        unset($this->objectsAll);
256
        exec($snmpCommand,$this->objectsAll,$retVal);
257
        if ($retVal!=0)
258
        {
259
            $this->logging->log('error executing snmptranslate',ERROR,'');
260
        }
261
        // Count elements to show progress
262
        $numElements=count($this->objectsAll);
263
        $this->logging->log('Total snmp objects returned by snmptranslate : '.$numElements,INFO );
264
        return $numElements;
265
    }
266
267
    /**
268
     * load all mib objects db in dbOidAll (raw) and index in dbOidIndex
269
     */
270
    private function load_mibs_from_db()
271
    {
272
        // Get all mibs from databse to have a memory index
273
        
274
        $db_conn=$this->trapsDB->db_connect_trap();
275
        
276
        $sql='SELECT * from '.$this->trapsDB->dbPrefix.'mib_cache;';
277
        $this->logging->log('SQL query : '.$sql,DEBUG );
278
        if (($ret_code=$db_conn->query($sql)) === false) {
279
            $this->logging->log('No result in query : ' . $sql,ERROR,'');
280
        }
281
        $this->dbOidAll=$ret_code->fetchAll();
282
        $this->dbOidIndex=array();
283
        // Create the index for db;
284
        foreach($this->dbOidAll as $key=>$val)
285
        {
286
            $this->dbOidIndex[$val['oid']]['key']=$key;
287
            $this->dbOidIndex[$val['oid']]['id']=$val['id'];
288
        }
289
    }
290
291
    /**
292
     * Reset all update timers & count to zero
293
     */
294
    private function reset_update_timers()
295
    {
296
        $this->timing['base_parse_time']=0;
297
        $this->timing['base_check_time']=0;
298
        $this->timing['type0_check_time']=0;
299
        $this->timing['nottrap_time']=0;
300
        $this->timing['update_time']=0;
301
        $this->timing['objects_time']=0;
302
        $this->timing['base_parse_num']=0;
303
        $this->timing['base_check_num']=0;
304
        $this->timing['type0_check_num']=0;
305
        $this->timing['nottrap_num']=0;
306
        $this->timing['update_num']=0;
307
        $this->timing['objects_num']=0;
308
        $this->timing['num_traps']=0;
309
    }
310
311
    /**
312
     * Detect if $this->objectsAll[$curElement] is a trap 
313
     * @param integer $curElement
314
     * @param bool $onlyTraps : set to false to get all and not only traps.
315
     * @return boolean : false if it's a trap , true if not
316
     */
317
    private function detect_trap($curElement,$onlyTraps)
318
    {
319
        // Get oid or pass if not found
320
        if (!preg_match('/^\.[0-9\.]+$/',$this->objectsAll[$curElement]))
321
        {
322
            $this->timing['base_parse_time'] += microtime(true) - $this->timing['base_time'];
323
            $this->timing['base_parse_num'] ++;
324
            return true;
325
        }
326
        $this->oidDesc['oid']=$this->objectsAll[$curElement];
327
        
328
        // get next line
329
        $curElement++;
330
        $match=$snmptrans=array();
331
        if (!preg_match('/ +([^\(]+)\(.+\) type=([0-9]+)( tc=([0-9]+))?( hint=(.+))?/',
332
            $this->objectsAll[$curElement],$match))
333
        {
334
            $this->timing['base_check_time'] += microtime(true) - $this->timing['base_time'];
335
            $this->timing['base_check_num']++;
336
            return true;
337
        }
338
        
339
        $this->oidDesc['name']=$match[1]; // Name
340
        $this->oidDesc['type']=$match[2]; // type (21=trap, 0: may be trap, else : not trap
341
        
342
        if ($this->oidDesc['type']==0) // object type=0 : check if v1 trap
343
        {
344
            // Check if next is suboid -> in that case is cannot be a trap
345
            if (preg_match("/^".$this->oidDesc['oid']."/",$this->objectsAll[$curElement+1]))
346
            {
347
                $this->timing['type0_check_time'] += microtime(true) - $this->timing['base_time'];
348
                $this->timing['type0_check_num']++;
349
                return true;
350
            }
351
            unset($snmptrans);
352
            $retVal=0;
353
            exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslateDirs.
354
                ' -Td '.$this->oidDesc['oid'] . ' | grep OBJECTS ',$snmptrans,$retVal);
355
            if ($retVal!=0)
356
            {
357
                $this->timing['type0_check_time'] += microtime(true) - $this->timing['base_time'];
358
                $this->timing['type0_check_num']++;
359
                return true;
360
            }
361
            //echo "\n v1 trap found : $this->oidDesc['oid'] \n";
362
            // Force as trap.
363
            $this->oidDesc['type']=21;
364
        }
365
        if ($onlyTraps===true && $this->oidDesc['type']!=21) // if only traps and not a trap, continue
366
        {
367
            $this->timing['nottrap_time'] += microtime(true) - $this->timing['base_time'];
368
            $this->timing['nottrap_num']++;
369
            return true;
370
        }
371
        return false;
372
    }
373
   
374
    /**
375
     * get_trap_mib_description
376
     * @return array|null : array of snmptranslate output or null on error
377
    **/
378
    private function get_trap_mib_description()
379
    {
380
        $retVal=0;
381
        $match=$snmptrans=array();
382
        exec($this->snmptranslate . ' -m ALL -M +'.$this->snmptranslateDirs.
383
            ' -Td '.$this->oidDesc['oid'],$snmptrans,$retVal);
384
        if ($retVal!=0)
385
        {
386
            $this->logging->log('error executing snmptranslate',ERROR);
387
            return $snmptrans;
388
        }
389
        
390
        if (!preg_match('/^(.*)::/',$snmptrans[0],$match))
391
        {
392
            $this->logging->log('Error getting mib from trap '.$this->oidDesc['oid'].' : ' . $snmptrans[0],ERROR);
393
            return $snmptrans;
394
        }
395
        $this->oidDesc['mib']=$match[1];
396
        
397
        $numLine=1;
398
        while (isset($snmptrans[$numLine]) && !preg_match('/^[\t ]+DESCRIPTION[\t ]+"(.*)/',$snmptrans[$numLine],$match)) $numLine++;
399
        if (isset($snmptrans[$numLine]))
400
        {
401
            $snmptrans[$numLine] = preg_replace('/^[\t ]+DESCRIPTION[\t ]+"/','',$snmptrans[$numLine]);
402
            
403
            while (isset($snmptrans[$numLine]) && !preg_match('/"/',$snmptrans[$numLine]))
404
            {
405
                $this->oidDesc['description'].=preg_replace('/[\t ]+/',' ',$snmptrans[$numLine]);
406
                $numLine++;
407
            }
408
            if (isset($snmptrans[$numLine])) {
409
                $this->oidDesc['description'].=preg_replace('/".*/','',$snmptrans[$numLine]);
410
                $this->oidDesc['description']=preg_replace('/[\t ]+/',' ',$this->oidDesc['description']);
411
            }
412
            
413
        }
414
        return $snmptrans;
415
    }
416
417
    /**
418
     * Get trap objects
419
     * @param array $snmptrans : output of snmptranslate for TrapModuleConfig
420
     * @return array|null : array of objects or null if not found
421
    **/
422
    private function get_trap_objects($snmptrans)
423
    {
424
        $objectName=null;
425
        $match=array();
426
        foreach ($snmptrans as $line)
427
        {
428
            if (preg_match('/OBJECTS.*\{([^\}]+)\}/',$line,$match))
429
            {
430
                $objectName=$match[1];
431
            }
432
        }
433
        if ($objectName == null)
434
        {
435
            $this->logging->log('No objects for ' . $this->oidDesc['oid'],DEBUG);
436
            $this->timing['objects_time'] += microtime(true) - $this->timing['base_time'];
437
            return null;
438
        }
439
        
440
        $trapObjects=array();
441
        while (preg_match('/ *([^ ,]+) *,* */',$objectName,$match))
442
        {
443
            array_push($trapObjects,$match[1]);
444
            $objectName=preg_replace('/'.$match[0].'/','',$objectName);
445
        }
446
        return $trapObjects;
447
    }
448
    
449
    /**
450
     * Cache mib in database
451
     * @param boolean $display_progress : Display progress on standard output
452
     * @param boolean $check_change : Force check of trap params & objects
453
     * @param boolean $onlyTraps : only cache traps and objects (true) or all (false)
454
     * @param string $startOID : only cache under startOID (NOT IMPLEMENTED)
455
     */
456
    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

456
    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...
457
    {
458
        // Global Timing
459
        $timeTaken = microtime(true);
460
        
461
        $numElements=$this->load_mibs_snmptranslate(); // Load objectsAll
462
        
463
        $this->load_mibs_from_db(); // Load from db dbOidAll & dbOidIndex
464
        
465
        $step=$basestep=$numElements/10; // output display of % done
466
        $num_step=0;
467
        $timeFiveSec = microtime(true); // Used for display a '.' every <n> seconds
468
        
469
        // Create index for trap objects
470
        $this->trapObjectsIndex=array();
471
        
472
        // detailed timing (time_* vars)
473
        $this->reset_update_timers();
474
        
475
        for ($curElement=0;$curElement < $numElements;$curElement++)
476
        {
477
            $this->timing['base_time']= microtime(true);
478
            if ($display_progress)
479
            {
480
                if ((microtime(true)-$timeFiveSec) > 2)
481
                { // echo a . every 2 sec
482
                    echo '.';
483
                    $timeFiveSec = microtime(true);
484
                }
485
                if ($curElement>$step)
486
                { // display progress
487
                    $num_step++;
488
                    $step+=$basestep;   
489
                    echo "\n" . ($num_step*10). '% : ';
490
                }
491
            }
492
            
493
            $this->reset_oidDesc();
494
            if ($this->detect_trap($curElement,$onlyTraps)===true)
495
            {
496
                continue;
497
            }
498
            
499
            $this->timing['num_traps']++;
500
            
501
            $this->logging->log('Found trap : '.$this->oidDesc['name'] . ' / OID : '.$this->oidDesc['oid'],INFO );
502
            if ($display_progress) echo '#'; // echo a # when trap found
503
504
            // get trap objects & source MIB
505
            
506
            $snmptrans=$this->get_trap_mib_description(); // get MIB & description
507
508
509
            $update=$this->update_oid(); // Do update of trap.
510
            
511
            $this->timing['update_time'] += microtime(true) - $this->timing['base_time'];
512
            $this->timing['update_num']++;
513
            
514
            $this->timing['base_time']= microtime(true); // Reset to check object time
515
            
516
            if (($update==0) && ($check_change===false))
517
            { // Trapd didn't change & force check disabled
518
                $this->timing['objects_time'] += microtime(true) - $this->timing['base_time'];
519
                if ($display_progress) echo "C";
520
                continue;
521
            }
522
            
523
            $trapObjects=$this->get_trap_objects($snmptrans); // Get trap objects from snmptranslate output            
524
            if ($trapObjects == null)
525
            {
526
                continue;
527
            }
528
           
529
            $this->trap_objects($this->oidDesc['oid'], $this->oidDesc['mib'], $trapObjects, false);
530
            
531
            $this->timing['objects_time'] += microtime(true) - $this->timing['base_time'];
532
            $this->timing['objects_num']++;
533
        }
534
        
535
        if ($display_progress)
536
        {
537
            echo "\nNumber of processed traps :  ". $this->timing['num_traps'] ."\n";
538
            echo "\nParsing : " . number_format($this->timing['base_parse_time']+$this->timing['base_check_time'],1) ." sec / " . ($this->timing['base_parse_num']+ $this->timing['base_check_num'])  . " occurences\n";
539
            echo "Detecting traps : " . number_format($this->timing['type0_check_time']+$this->timing['nottrap_time'],1) . " sec / " . ($this->timing['type0_check_num']+$this->timing['nottrap_num']) ." occurences\n";
540
            echo "Trap processing (".$this->timing['update_num']."): ".number_format($this->timing['update_time'],1)." sec , ";
541
            echo "Objects processing (".$this->timing['objects_num'].") : ".number_format($this->timing['objects_time'],1)." sec \n";
542
            
543
            $timeTaken=microtime(true) - $timeTaken;
544
            echo "Global time : ".round($timeTaken)." seconds\n";
545
        }
546
    }
547
    
548
    
549
}