Change Mail Address
[racktables-contribs] / snmplive.php
CommitLineData
af6161bd 1<?php
2
3/********************************************
4 *
5 * RackTables 0.20.x snmp live extension
6 *
7 * displays SNMP port status
8 *
9 *
10 * needs PHP >= 5.4.0
11 * saved SNMP settings ( see snmpgeneric.php extension )
12 * also RT port names and SNMP port names must be the same ( should work fine with snmpgeneric.php created ports )
13 *
14 * (c)2015 Maik Ehinger <m.ehinger@ltur.de>
15 */
16
17/****
18 * INSTALL
19 * just place file in plugins directory
20 *
21 */
22
23/**
24 * The newest version of this plugin can be found at:
25 *
26 * https://github.com/github138/myRT-contribs/tree/develop-0.20.x
27 *
28 */
29
30/* TODOs
31 *
32 * - code cleanup
33 */
34
35/* RackTables Debug Mode */
36//$debug_mode=1;
37
38$tab['object']['snmplive'] = 'SNMP Live';
39$tabhandler['object']['snmplive'] = 'snmplive_tabhandler';
40$trigger['object']['snmplive'] = 'snmplive_tabtrigger';
41
42$ophandler['object']['snmplive']['ajax'] = 'snmplive_opajax';
43
44function snmplive_tabtrigger() {
45 // display tab only on IPv4 Objects
46 return considerConfiguredConstraint (spotEntity ('object', getBypassValue()), 'IPV4OBJ_LISTSRC') ? 'std' : '';
47} /* snmplive_tabtrigger */
48
49function snmplive_tabhandler($object_id)
50{
51
52 addCSS(<<<ENDCSS
53 .ifoperstatus-default { background-color:#ddd; }
54 .ifoperstatus-1, .ifoperstatus-up { background-color:#00ff00; }
55 .ifoperstatus-2, .ifoperstatus-down { background-color:#ff0000; }
56 .ifoperstatus-3, .ifoperstatus-testing { background-color:#ffff66; }
57 .ifoperstatus-4, .ifoperstatus-unknown { background-color:#ffffff; }
58 .ifoperstatus-5, .ifoperstatus-dormant { background-color:#90bcf5; }
59 .ifoperstatus-6, .ifoperstatus-notPresent { }
60 .ifoperstatus-7, .ifoperstatus-lowerLayerDown { }
61
62 .port-groups { border-spacing:1px;display:table; }
63 .port-group { display:table-cell;border:3px solid #000;background-color:#c0c0c0; }
64
65 .port-column { display:table-cell;position:relative; }
66
67 .port { position:relative;width:42px;height:100px;border:2px solid #000;overflow:hidden; }
68 .port-pos-1 { margin-bottom:1px; }
69 .port-pos-2 { }
70 .port-pos-0 { margin-top:1px; }
71
72 .port-header { position:absolute }
73 .port-header-pos-1 { top:0px; }
74 .port-header-pos-0 { bottom:0px; }
75
76 .port-status { position:absolute;min-width:42px;text-align:center;font-size:10pt; }
77
78 .port-status-pos-1 { top:35px; }
79 .port-status-pos-0 { bottom:35px; }
80
81 .port-info { position:absolute;width:90%;background-color:#ddd;overflow:hidden; }
82 .port-info-pos-1 { top: 80px; }
83 .port-info-pos-0 { bottom: 80px;}
84
85 .port-name { font-size:10pt;margin:0px auto;width:40px;text-align:center; }
86 .port-number { font-size:8pt;color:#eee; }
87
88 .port-detail { position:fixed;z-index:1000;top:0px;right:0px;border:3px solid #000;background-color:#fff }
89 .port-detail-links { background-color:#ccc }
90 .hidden { visibility:hidden; }
91 .info-footer { }
92
93ENDCSS
94, TRUE);
95
96 echo "<div id=\"info\"></div>";
97
98 if(isset($_GET['debug']))
99 $debug = $_GET['debug'];
100 else
101 $debug = 0;
102
103 $object = spotEntity('object', $object_id);
104 amplifyCell($object);
105
106 if(isset($_GET['modules']))
107 $modules = $_GET['modules'];
108 else
109 $modules = false;
110
111 if($modules)
112 unset($_GET['modules']);
113 else
114 $_GET['modules'] = 1;
115
116 echo "<a href=".makeHref($_GET).">".($modules ? "Hide" : "Show" )." Modules</a>";
117
118 pl_layout_default($object, 0, false, $modules);
119
120 addJS(<<<ENDJS
121 function togglevisibility(elem, hide)
122 {
123 if(hide)
124 elem.css('visibility', 'hidden');
125 else
126 elem.css('visibility', 'visible');
127 //a.show();
128 //a.hide();
129 }
130
131 function setdetail(elem, hide)
132 {
133 var a = $( "#port" + elem.id + "-detail");
134
135 togglevisibility(a, hide);
136 }
137
138 function setports( data, textStatus, jqHXR ) {
139 if(data.debug)
140 $( "#info" ).html($( "#info" ).html() + "DEBUG: " + data.name + ": " + data.debug);
141
142 for(var index in data.ports)
143 {
144 setport(data, data.ports[index]);
145 }
146 }
147
148 function setportstatus( obj, port , id , detail)
149 {
150
151 tagidsuffix = "";
152
153 if(detail)
154 tagidsuffix = tagidsuffix + "-detail";
155
156 if(!detail)
157 {
158 $( "#port" + id + "-status" + tagidsuffix ).html("<table class=\"ifoperstatus-" + port.snmpinfos.
159operstatus + "\"><tr><td>"
160 + port.snmpinfos.operstatus + "<br>" + port.snmpinfos.speed
161 + ( port.snmpinfos.vlan ? "<br>" + port.snmpinfos.vlan : "" )
162 + "</td></tr></table>");
163 return;
164 }
165
166 $( "#port" + id + "-status" + tagidsuffix ).html(port.snmpinfos.alias
167 + "<table class=\"ifoperstatus-" + port.snmpinfos.operstatus + "\"><tr><td>"
168 + (port.snmpinfos.ipv4 ? port.snmpinfos.ipv4 : "")
169 + "<br>" + port.snmpinfos.operstatus
170 + ( port.snmpinfos.vlan ? "<br>" + port.snmpinfos.vlan_name + " (" + port.snmpinfos.vlan + ")" : "" )
171 + "</td></tr></table>");
172 }
173
174 function setport( obj, port ) {
175
176 if(port.debug)
177 $( "#info" ).html($( "#info" ).html() + port.name + " " + port.debug);
178
179 if(port.snmpinfos)
180 {
181 setportstatus(obj, port, port.id, false);
182 setportstatus(obj, port, port.id, true);
183 }
184
185 }
186
187 function ajaxerror(jqHXR, textStatus, qXHR, errorThrown)
188 {
189 $( "#info" ).html($( "#info" ).html() + "<br>" + textStatus + " " + qXHR + " " + errorThrown);
190 }
191
192 $.ajax({
193 dataType: "json",
194 url: "index.php",
195 data: {
196 page: "object",
197 tab: "snmplive",
198 module: "redirect",
199 op: "ajax",
200 json: "get",
201 object_id: "$object_id",
202 debug: $debug
203 },
204 error: ajaxerror,
205 success: setports
206 });
207
208ENDJS
209, TRUE);
210
211} /* snmplive_tabhandler */
212
213/* -------------------------------------------------- */
214
215function snmplive_opajax()
216{
217
218 ob_start();
219 $object_id = $_REQUEST['object_id'];
220 $object = spotEntity('object', $object_id);
221
222 $object['ports'] = getObjectPortsAndLinks ($object_id);
223
224 if(isset($_GET['debug']))
225 $debug = $_GET['debug'];
226 else
227 $debug = 0;
228
229 $object['iftable'] = sl_getsnmp($object, $debug);
230
231 if($object['iftable'])
232 foreach($object['ports'] as $key => &$port)
233 {
234 // snmpinfos
235 $port['snmpinfos'] = sl_getportsnmp($object, $port, $debug);
236
237 if(!$port['snmpinfos'])
238 unset($object['ports'][$key]);
239 }
240
241 /* not needed anymore */
242 unset($object['iftable']);
243
244 /* set debug output */
245 if(ob_get_length())
246 $object['debug'] = ob_get_contents();
247
248 ob_end_clean();
249
250 echo json_encode($object);
251 exit;
252
253} /* snmpgeneric_opcreate */
254
255/* -------------------------------------------------- */
256
257function pl_layout_default(&$object, $groupports = 8, $bottomstart = false, $modules = false, $portrows = 2)
258{
259 $i = 0;
260 $portcolumn = "";
261 $linkcount = 0;
262
263 $lastmodule = null;
264 $nomodul = array();
265
266 echo "<div class=\"port-groups\">";
267 foreach($object['ports'] as $key => $port)
268 {
269
270 $object['portnames'][$port['name']] = $port;
271
272 $port_id = $port['id'];
273 $port_name = $port['name'];
274
275 $pname = $port_name;
276 $module = "";
277 $pport = "";
278 // split name in name, module, port
279 if(preg_match('/^([a-zA-Z]+)?(?:[\W]?([\d]+)?[\W])?([\d]+)?$/', $port_name, $match))
280 if(count($match) == 4)
281 list($tmp,$pname,$module,$pport) = $match;
282
283 if($port['linked'])
284 $linkcount++;
285
286 if($module == "")
287 {
288 $nomodul[] = pl_layout_port($port, count($nomodul) + 1, 1);
289 continue;
290 }
291
292 if($modules)
293 {
294 // port modules
295 if($module != $lastmodule)
296 {
297 if(($i % $portrows) != 0)
298 echo "$portcolumn</div>"; // port-column
299
300 if($groupports)
301 if(($i % $groupports) != 0)
302 echo "</div>"; // port-group
303
304 echo "</div>"; // port-groups
305
306 $i = 0;
307 $portcolumn = "";
308 echo "Modul: $module";
309 echo "<br><div class=\"port-groups\">";
310 }
311
312 $lastmodule = $module;
313 }
314
315 $i++;
316
317 if($groupports)
318 if(($i % $groupports) == 1)
319 echo "<div class=\"port-group\">";
320
321 if($portrows == 2)
322 {
323 // print each row different
324 if(($i % $portrows) == 1)
325 $pos = ($bottomstart ? 0 : 1); // 0 = bottom; 1 = top
326 else
327 $pos = ($bottomstart ? 1 : 0); // 0 = bottom; 1 = top
328 }
329 else
330 $pos = ($bottomstart ? 0 : 1); // 0 = bottom; 1 = top
331
332 $portdiv = pl_layout_port($port, $i, $pos);
333
334 if(!$bottomstart)
335 $portcolumn = "$portcolumn$portdiv";
336 else
337 $portcolumn = "$portdiv$portcolumn";
338
339 if(($i % $portrows) == 0)
340 {
341 echo "<div class=\"port-column\">";
342 echo "$portcolumn</div>";
343 $portcolumn = "";
344 }
345
346 if($groupports)
347 if(($i % $groupports) == 0)
348 echo "</div>";
349 }
350
351 if(($i % $portrows) != 0)
352 {
353 $fillcount = $portrows - ($i % $portrows);
354
355 $fill = "";
356 for($f=0;$f<$fillcount;$f++)
357 $fill .= "<div class=\"port\"></div>";
358
359 if(!$bottomstart)
360 $portcolumn .= $fill;
361 else
362 $portcolumn = "$fill$portcolumn";
363
364 echo "<div class=\"port-column\">";
365 echo "$portcolumn</div>"; // port-column
366 }
367
368 if($groupports)
369 if(($i % $groupports) != 0)
370 echo "</div>"; // port-group
371
372 echo "</div>"; // port-groups
373
374 /* Port without modul */
375 if($nomodul)
376 {
377 echo "Other Ports:<br><div id=\"nomodule\" class=\"port-groups\">";
378 foreach($nomodul as $portdiv)
379 echo "<div class=\"port-column\">$portdiv</div>";
380 echo "</div>";
381 }
382
383 return $linkcount;
384
385} // layout_default
386
387function pl_layout_port($port, $number, $pos)
388{
389
390 $port_id = $port['id'];
391 $port_name = $port['name'];
392
393 $title = "Name: $port_name - No: $number - ID: $port_id";
394
395 $portdiv = "<div id=\"$port_id\" class=\"port port-pos-$pos\" onmouseover=\"setdetail(this,false);\" onmouseout=\"setdetail(this,true);\">";
396 $portheader = "<div class=\"port-header port-header-pos-$pos\">";
397 $portlabel = "<div class=\"port-number\">$number</div>";
398 $portname = "<div class=\"port-name\">$port_name</div>";
399
400 $details = "<table><tr><td>No.: $number (ID: ".$port['id'].")<br>".$port['object_name']."<br>".$port['name']."<br>"
401 .$port['label']."<br>".$port['reservation_comment']
402 ."<div id=\"port${port_id}-status-detail\">No Status</div></td>";
403
404 if($port['linked'])
405 $details .= "<td>Remote:<br>".$port['cableid']."<br>".$port['remote_object_name']."<br>".$port['remote_name']."<div id=\"port${port_id}-status-detail-remote\">No Remote Status</div></td>";
406
407 $details .= "</tr></table>";
408
409
410 $portdetail = "<div id=\"port${port_id}-detail\" class=\"port-detail hidden\" onclick=\"togglevisibility(this,true);\">$details</div>";
411
412 $portstatus = "<div id=\"port${port_id}-status\" class=\"port-status port-status-pos-$pos\" title=\"$title\">-</div>";
413
414 if($pos) {
415 $portheader .= "$portlabel$portname</div>";
416 $portdiv .= "$portheader$portstatus<div class=\"port-info port-info-pos-$pos\"></div></div>$portdetail";
417 }
418 else
419 {
420 $portheader .= "$portname$portlabel</div>";
421 $portdiv .= "<div class=\"port-info port-info-pos-$pos\"></div>$portstatus$portheader</div>$portdetail";
422 }
423
424 return $portdiv;
425}
426/* ------------------------------------------------------- */
427
428function sl_getportsnmp(&$object, $port, $debug = false)
429{
430 $ipv4 = $object['SNMP']['IP'];
431
432 $port_name = $port['name'];
433
434 // SNMP up / down
435 if(!isset($object['iftable'][$port_name]))
436 return false;
437
438 $ifoperstatus = $object['iftable'][$port_name]['status'];
439
440 $ifspeed = $object['iftable'][$port_name]['speed'];
441
442 $ifalias = $object['iftable'][$port_name]['alias'];
443
444 $vlan="";
445 $vlan_name="";
446
447 if(isset($object['iftable'][$port_name]['vlan']))
448 {
449 $vlan = $object['iftable'][$port_name]['vlan'];
450 $vlan_name = $object['iftable'][$port_name]['vlan_name'];
451 }
452
453 return array(
454 'ipv4' => $ipv4,
455 'operstatus' => $ifoperstatus,
456 'alias' => $ifalias,
457 'speed' => $ifspeed,
458 'name' => $port_name,
459 'vlan' => $vlan,
460 'vlan_name' => $vlan_name,
461 );
462
463} // sl_getportsnmp
464
465function sl_getsnmp(&$object, $debug = false)
466{
467 $object_id = $object['id'];
468 $object_name = $object['name'];
469
4399cfe0 470 $breed = detectDeviceBreed ($object_id);
471
af6161bd 472 if(isset($object['SNMP']))
473 {
474 if($debug)
475 echo "INFO: No SNMP Object \"$object_name\" ID: $object_id<br>";
476 return null;
477 }
478
479 if(!considerConfiguredConstraint($object, 'IPV4OBJ_LISTSRC'))
480 {
481 if($debug)
482 echo "INFO: No IPv4 Object \"$object_name\" ID: $object_id<br>";
483
484 return False;
485 }
486
487 /* get object saved SNMP settings */
488 $snmpconfig = explode(':', strtok($object['comment'],"\n\r"));
489
490 if($snmpconfig[0] != "SNMP")
491 {
492
493 if($debug)
494 echo "INFO: No saved SNMP Settings for \"$object_name\" ID: $object_id<br>";
495
496 return False;
497 }
498
499 /* set objects SNMP ip address */
500 $ipv4 = $snmpconfig[1];
501
502 if(0)
503 var_dump_html($snmpconfig);
504
505 if(!$ipv4)
506 {
507 echo "ERROR: no ip for \"$object_name!!\"<br>";
508
509 return False;
510 }
511
512 $object['SNMP']['IP'] = $ipv4;
513
514 if(count($snmpconfig) < 4 )
515 {
516 echo "SNMP Error: Missing Setting for $object_name ($ipv4)";
517
518 return False;
519 }
520
521 /* SNMP prerequisites successfull */
522
4399cfe0 523 $s = new sl_ifxsnmp($snmpconfig[2], $ipv4, $snmpconfig[3], $snmpconfig, $breed);
af6161bd 524
525 if(!$s->error)
526 {
527
528 /* get snmp data */
529 $iftable = $s->getiftable();
530
531 if($debug && $s->error)
532 echo $s->getError();
533
534 if($iftable)
535 return $iftable;
536 else
537 {
538
539 echo "SNMP Error: ".$s->getError()." for $object_name ($ipv4)<br>";
540 return False;
541 }
542
543 }
544 else
545 {
546 echo "SNMP Config Error: ".$s->error." for \"$object_name\"<br>";
547 return False;
548 }
549
550 return null;
551
552} // sl_getsnmp
553/* ------------------ */
554class sl_ifxsnmp extends SNMP
555{
556
557 public $error = false;
558
4399cfe0 559 private $devicebreed = null;
560
561 function __construct($version, $hostname, $community, $security = null, $breed = null)
af6161bd 562 {
563
4399cfe0 564 $this->devicebreed = $breed;
565
af6161bd 566 switch($version)
567 {
568 case "1":
569 case "v1":
570 $version = parent::VERSION_1;
571 break;
572 case "2":
573 case "2c":
574 case "v2c":
575 $version = parent::VERSION_2c;
576 break;
577 case "3":
578 case "v3":
579 $version = parent::VERSION_3;
580 break;
581 }
582
583 parent::__construct($version, $hostname, $community);
584
585 if($version == SNMP::VERSION_3)
586 {
587 if($security !== null && count($security) == 9)
588 {
589 $auth_passphrase = base64_decode($security[6]);
590 $priv_passphrase = base64_decode($security[8]);
591
592 if(!$this->setsecurity($security[4], $security[5], $auth_passphrase, $security[7], $priv_passphrase))
593 {
594
595 $this->error = "Security Error for v3 ($hostname)";
596 return;
597 }
598
599 }
600 else
601 {
602 $this->error = "Missing security settings for v3 ($hostname)";
603 return;
604 }
605 }
606
607 $this->quick_print = 1;
608 $this->oid_output_format = SNMP_OID_OUTPUT_NUMERIC;
609 }
610
611 function getiftable()
612 {
613 $oid_ifindex = '.1.3.6.1.2.1.2.2.1.1'; // iftable
614 $oid_ifoperstatus = '.1.3.6.1.2.1.2.2.1.8'; //iftable
615 $oid_ifspeed = '.1.3.6.1.2.1.2.2.1.5'; //iftable
b87c1189 616 $oid_ifdescr = '.1.3.6.1.2.1.2.2.1.2'; //iftable
af6161bd 617 $oid_ifhighspeed = '.1.3.6.1.2.1.31.1.1.1.15'; //ifXtable
618 $oid_ifname = '.1.3.6.1.2.1.31.1.1.1.1'; //ifXtable
619 $oid_ifalias = '.1.3.6.1.2.1.31.1.1.1.18'; //ifXtable
620
621 $ifindex = $this->walk($oid_ifindex); // iftable
622
623 if($ifindex === FALSE)
624 {
625 return FALSE;
626 exit;
627 }
628
629 $ifname = $this->walk($oid_ifname, TRUE); //ifXtable
b87c1189 630
631 if($ifname == false)
632 $ifname = $this->walk($oid_ifdescr, TRUE); //ifXtable
633
af6161bd 634 $ifalias = $this->walk($oid_ifalias, TRUE); //ifXtable
635
636 $ifspeed = $this->walk($oid_ifspeed, TRUE); //iftable
637 $ifhighspeed = $this->walk($oid_ifhighspeed, TRUE); //ifXtable
638
639 $this->enum_print = false;
640 $ifoperstatus = $this->walk($oid_ifoperstatus, TRUE); //iftable
641
642 $retval = array();
643 foreach($ifindex as $index)
644 {
4399cfe0 645 $ifname[$index] = shortenIfName ($ifname[$index], $this->devicebreed);
646
af6161bd 647 $retval[$ifname[$index]]['ifindex'] = $index;
648
649 $retval[$ifname[$index]]['status'] = $ifoperstatus[$index];
650
651 $retval[$ifname[$index]]['alias'] = $ifalias[$index];
652
653 $highspeed = $ifhighspeed[$index];
654 if($highspeed)
655 $speed = $highspeed;
656 else
657 $speed = $ifspeed[$index];
658
659 if($speed >= 1000000) // 1Mbit
660 $speed /= 1000000;
661
662 $speed = ($speed >= 1000 ? ($speed / 1000)."Gb" : $speed."Mb" );
663
664 $retval[$ifname[$index]]['speed'] = "$speed";
665
666 }
667
668 $this->get8021qvlan($retval);
669
670 if(0)
671 sl_var_dump_html($retval);
672
673 return $retval;
674 }
675
676 /* append vlan to each port in retval */
677 function get8021qvlan(&$retval)
678 {
679 //$oid_dot1dBasePort = '.1.3.6.1.2.1.17.1.4.1.1';
680 $oid_dot1dBasePortIfIndex = '.1.3.6.1.2.1.17.1.4.1.2'; // dot1 index -> if index
681 $oid_dot1qPvid = '.1.3.6.1.2.1.17.7.1.4.5.1.1';
682 $oid_dot1qVlanStaticName = '.1.3.6.1.2.1.17.7.1.4.3.1.1';
683
684 // @ supprress warning
685 $dot1dbaseportifindex = @$this->walk($oid_dot1dBasePortIfIndex, TRUE);
686
687 if($dot1dbaseportifindex === false)
688 {
689 $this->error = true;
690 return;
691 }
692
693 $dot1qpvid = $this->walk($oid_dot1qPvid, TRUE);
694 $dot1qvlanstaticname = $this->walk($oid_dot1qVlanStaticName, TRUE);
695
696 $ifindexdot1dbaseport = array_flip($dot1dbaseportifindex);
697
698 $ret = array();
699 foreach($retval as $ifname => &$port)
700 {
701 if(!isset($ifindexdot1dbaseport[$port['ifindex']]))
702 continue;
703
704 $dot1index = $ifindexdot1dbaseport[$port['ifindex']];
705 $vlan = $dot1qpvid[$dot1index];
706 $retval[$ifname]['vlan'] = $vlan;
707 $retval[$ifname]['vlan_name'] = $dot1qvlanstaticname[$vlan];
708 }
709
710 }
711} // sl_ifxsnmp
712
713/* ------------------------------------------------------- */
714/* for debugging */
715function sl_var_dump_html(&$var, $text = '') {
716
717 echo "<pre>------------------Start Var Dump - $text -----------------------\n";
718 var_dump($var);
719 echo "\n---------------------END Var Dump - $text -----------------------</pre>";
720}