Sfoglia il codice sorgente

add vlan members for device ports

Roman Dmitriev 2 anni fa
parent
commit
777cd66c24
3 ha cambiato i file con 258 aggiunte e 18 eliminazioni
  1. 19 10
      html/admin/devices/switchstatus.php
  2. 223 8
      html/inc/common.php
  3. 16 0
      html/inc/consts.php

+ 19 - 10
html/admin/devices/switchstatus.php

@@ -87,7 +87,7 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
         print "<b>" . WEB_device_port_state_list . "&nbsp" . $device['device_name'] . " - " . $device['ip'] . "</b><br>\n";
 
         $snmp_ok = 0;
-
+        $vlan_list = [];
         if (!empty($device['ip']) and $device['snmp_version'] > 0) {
             $snmp_ok = check_snmp_access($device['ip'], $device['community'], $device['snmp_version']);
             $modules_oids = NULL;
@@ -98,6 +98,7 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
                 if ($device['snmp_version'] == 1) {
                     $modules_oids = snmprealwalk($device['ip'], $device['community'], CISCO_MODULES, SNMP_timeout, SNMP_retry);
                     }
+                $vlan_list = get_switch_vlans($device['vendor_id'],$device['ip'], $device['community'], $device['snmp_version']);
                 }
             } else {
             $snmp_ok = 0;
@@ -129,6 +130,13 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
             print "<tr align=center>\n";
             $cl = "down";
             $new_info = NULL;
+            
+            $display_vlan= $row['vlan'];
+            if (!empty($row['untagged_vlan'])) { 
+                if ($row['untagged_vlan'] != $row['vlan']) { $display_vlan.=";U:".$row['untagged_vlan']; }
+                }
+            if (!empty($row['tagged_vlan'])) { $display_vlan.=";T:".$row['tagged_vlan']; }
+
             //fix empty port names
             if (empty($row['port_name'])) {
                 $row['port_name'] = $row['port'];
@@ -165,11 +173,9 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
             print "<td class='" . $cl . "' >" . get_qa($row['skip']) . "</td>\n";
             $poe_info = "POE:None";
 
-            $vlan = $row['vlan'];
             $ifname = $row['ifName'];
 
             if ($snmp_ok) {
-                $vlan = get_port_vlan($device['vendor_id'],  $row['port'] , $row['snmp_index'], $device['ip'], $device['community'], $device['snmp_version']);
                 $ifname = get_snmp_ifname1($device['ip'], $device['community'], $device['snmp_version'], $row['snmp_index']);
                 if (empty($ifname)) {
                     $ifname = get_snmp_ifname2($device['ip'], $device['community'], $device['snmp_version'], $row['snmp_index']);
@@ -189,12 +195,15 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
                         $poe_info = "POE:Off";
                     }
                 }
-                if (empty($vlan)) {
-                    $vlan = $row['vlan'];
-                } else {
-                    if ($vlan >= 1 and $row['vlan'] !== $vlan) {
-                        $new_info['vlan'] = $vlan;
-                    }
+                if (!empty($vlan_list) and !empty($vlan_list[$row['snmp_index']])) {
+                    $new_info['vlan'] = $vlan_list[$row['snmp_index']]['pvid'];
+                    $new_info['tagged_vlan']=$vlan_list[$row['snmp_index']]['tagged'];
+                    $new_info['untagged_vlan']=$vlan_list[$row['snmp_index']]['untagged'];
+                    $display_vlan = $new_info['vlan'];
+                    if (!empty($new_info['untagged_vlan'])) { 
+                        if ($new_info['untagged_vlan'] != $new_info['vlan']) { $display_vlan.=";U:".$new_info['untagged_vlan']; }
+                        }
+                    if (!empty($new_info['tagged_vlan'])) { $display_vlan.=";T:".$new_info['tagged_vlan']; }
                 }
                 if (!isset($row['ifName']) or $row['ifName'] !== $ifname) {
                     $new_info['ifName'] = $ifname;
@@ -224,7 +233,7 @@ print_editdevice_submenu($page_url, $id, $device['device_type'], $user_info['log
                 }
             }
 
-            print "<td class='" . $cl . "'>" . $vlan . "</td>\n";
+            print "<td class='" . $cl . "'>" . $display_vlan . "</td>\n";
             print "<td class='" . $cl . "'>" . $snmp_url . "</td>\n";
 
             $speed = "0";

+ 223 - 8
html/inc/common.php

@@ -2532,20 +2532,224 @@ function get_sfp_status($vendor_id, $port, $ip, $community, $version, $modules_o
     return;
 }
 
-function get_port_vlan($vendor, $port, $port_index, $ip, $community, $version)
+
+function get_switch_vlans($vendor,$ip,$community='public',$version='2') {
+
+    $switch_vlans = [];
+    $port_status  = [];
+    $vlan_status  = [];
+
+    //cisco...
+    if ($vendor == 16) {
+        //all vlan at switch
+        $vlan_list = walk_snmp($ip, $community, $version, vtpVlanName);
+        if (empty($vlan_list)) { return; }
+        foreach ($vlan_list as $key => $value) {
+            if (empty($value)) { $value = ''; }
+            $key = trim($key);
+            $value = parse_snmp_value($value);
+            $vlan_id = NULL;
+            if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $vlan_id = preg_replace('/^\./', '', $matches[0]); }
+            //skip service vlan
+            if (preg_match('/(1002|1003|1004|1005)/',$vlan_id)) { continue; }
+            if (isset($vlan_id) and !empty($vlan_id)) { $switch_vlans[$vlan_id]=$value; }
+            }
+
+        //native vlan for port - get list of all ports
+        $pvid_list = walk_snmp($ip, $community, $version, vlanTrunkPortNativeVlan);
+        if (!empty($pvid_list)) {
+            foreach ($pvid_list as $key => $value) {
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                $port = NULL;
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $port = preg_replace('/^\./', '', $matches[0]); }
+                if (isset($port) and !empty($port)) { $port_status[$port]['native']=$value; }
+                }
+            }
+
+        //pvid
+        $pvid_list = walk_snmp($ip, $community, $version, vmVlanPvid);
+        if (!empty($pvid_list)) {
+            foreach ($pvid_list as $key => $value) {
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                $port = NULL;
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $port = preg_replace('/^\./', '', $matches[0]); }
+                if (isset($port) and !empty($port)) { $port_status[$port]['pvid']=$value; }
+                }
+            }
+
+        //init port config
+        foreach  ($port_status as &$port) {
+            if (!is_array($port)) { continue; }
+            if (!isset($port['pvid'])) { $port['pvid']=$port['native']; }
+            $port['untagged']='';
+            $port['tagged']='';
+            }
+        unset($port);
+
+        //get vlan list at ports
+        $egress_vlan = walk_snmp($ip,$community,$version,vlanTrunkPortVlansEnabled);
+        if (!empty($egress_vlan)) {
+            $j = 0;
+            foreach ($egress_vlan as $key => $value) {
+                $j++;
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) {
+                    $port = preg_replace('/^\./', '', $matches[0]);
+                    }
+                if (isset($port) and !empty($port)) {
+                    //skip access ports
+                    if (!is_array($port_status[$port]) or !isset($port_status[$port]['pvid']) or !isset($port_status[$port]['native'])) { continue; }
+                    if ($port_status[$port]['pvid'] != $port_status[$port]['native']) { continue; }
+                    //get vlan at port in hex
+                    $hex_value = preg_replace('/\s+/','',$value);
+                    $bin_value = strHexToBin($hex_value);
+                    //analyze switch vlans
+                    foreach ($switch_vlans as $vlan_id => $vlan_name) {
+                        if (isset($bin_value[$vlan_id]) and $bin_value[$vlan_id]=='1') {
+                        $port_status[$port]['tagged']=$port_status[$port]['tagged'].','.$vlan_id;
+                            }
+                        }
+                    }
+                }
+            }
+
+        //remove lliding ,
+        foreach ($port_status as &$port) {
+            if (!is_array($port)) { continue; }
+            $port['untagged']=preg_replace('/^,/', '',$port['untagged']);
+            $port['tagged']=preg_replace('/^,/', '',$port['tagged']);
+            }
+        unset($port);
+
+        return $port_status;
+        }
+
+    //standart switches
+
+    //tplink
+    if ($vendor == 69) {
+        //pvid for port
+        $pvid_list = walk_snmp($ip, $community, $version, TPLINK_dot1qPortVlanEntry);
+        if (!empty($pvid_list)) {
+            foreach ($pvid_list as $key => $value) {
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                $port = NULL;
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $port = preg_replace('/^\./', '', $matches[0]); }
+                if (isset($port) and !empty($port)) { $port_status[$port]['pvid']=$value; }
+                }
+            }
+        return $port_status;
+        }
+
+    //default
+    //pvid for port
+    $pvid_list = walk_snmp($ip, $community, $version, dot1qPortVlanEntry);
+    if (!empty($pvid_list)) {
+            foreach ($pvid_list as $key => $value) {
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                $port = NULL;
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $port = preg_replace('/^\./', '', $matches[0]); }
+                if (isset($port) and !empty($port)) { $port_status[$port]['pvid']=$value; }
+                }
+            }
+
+    //init port config
+    foreach  ($port_status as &$port) {
+            if (!is_array($port)) { continue; }
+            $port['native']=$port['pvid'];
+            $port['untagged']='';
+            $port['tagged']='';
+            }
+    unset($port);
+
+    //all vlan at switch
+    $vlan_list = walk_snmp($ip, $community, $version, dot1qVlanStaticName);
+    if (empty($vlan_list)) { return $port_status; }
+    foreach ($vlan_list as $key => $value) {
+            if (empty($value)) { $value = ''; }
+            $key = trim($key);
+            $value = parse_snmp_value($value);
+            $vlan_id = NULL;
+            if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $vlan_id = preg_replace('/^\./', '', $matches[0]); }
+            if (isset($vlan_id) and !empty($vlan_id)) { $switch_vlans[$vlan_id]=$value; }
+        }
+
+    $untagged_vlan = walk_snmp($ip,$community,$version,dot1qVlanStaticUntaggedPorts);
+    if (!empty($untagged_vlan)) {
+            foreach ($untagged_vlan as $key => $value) {
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $vlan_id = preg_replace('/^\./', '', $matches[0]); }
+                if (isset($vlan_id) and !empty($vlan_id)) {
+                    $hex_value = preg_replace('/\s+/','',$value);
+                    $hex_value = preg_replace('/0*$/','',$hex_value);
+                    $bin_value = strHexToBin($hex_value);
+                    for ($i=0; $i<strlen($bin_value); $i++) {
+                        $port = $i+1;
+                        $vlan_status['untagged_vlan'][$vlan_id][$port] = $bin_value[$i];
+                        if ($bin_value[$i]=='1') { $port_status[$port]['untagged'].=','.$vlan_id; }
+                        }
+                    }
+                }
+            }
+
+    $egress_vlan = walk_snmp($ip,$community,$version,dot1qVlanStaticEgressPorts);
+    if (!empty($egress_vlan)) {
+            foreach ($egress_vlan as $key => $value) {
+                if (empty($value)) { $value = ''; }
+                $key = trim($key);
+                $value = parse_snmp_value($value);
+                if (preg_match('/\.(\d{1,10})$/', $key, $matches)) { $vlan_id = preg_replace('/^\./', '', $matches[0]); }
+                if (isset($vlan_id) and !empty($vlan_id)) {
+                    $hex_value = preg_replace('/\s+/','',$value);
+                    $hex_value = preg_replace('/0*$/','',$hex_value);
+                    $bin_value = strHexToBin($hex_value);
+                    for ($i=0; $i<strlen($bin_value); $i++) {
+                        $port = $i+1;
+                        $vlan_status['egress_vlan'][$vlan_id][$port] = $bin_value[$i];
+                        //analyze egress & untagged vlans
+                        if ($bin_value[$i]=='1') {
+                            if (!isset($vlan_status['untagged_vlan'][$vlan_id][$port]) or $vlan_status['untagged_vlan'][$vlan_id][$port]=='0') {
+                                $vlan_status['tagged_vlan'][$vlan_id][$port]='1';
+                                $port_status[$port]['tagged'].=','.$vlan_id;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+    foreach ($port_status as &$port) {
+        if (!is_array($port)) { continue; }
+        $port['untagged']=preg_replace('/^,/', '',$port['untagged']);
+        $port['tagged']=preg_replace('/^,/', '',$port['tagged']);
+        }
+    unset($port);
+
+    return $port_status;
+}
+
+
+function get_port_vlan($vendor, $port, $port_index, $ip, $community='public', $version='2')
 {
     if (!isset($port_index)) {
         return;
     }
+
     if (!isset($ip)) {
         return;
     }
-    if (!isset($community)) {
-        $community = 'public';
-    }
-    if (!isset($version)) {
-        $version = '2';
-    }
 
     //default - default port index
     $port_oid = dot1qPortVlanEntry . "." . $port_index;
@@ -2983,9 +3187,11 @@ function get_port_state_detail($port, $ip, $community, $version)
 function parse_snmp_value($value)
 {
     if (empty($value)) {
-        return NULL;
+        return '';
     }
+    if (!preg_match('/:/',$value)) { return ''; }
     list($p_type, $p_value) = explode(':', $value);
+    if (empty($p_value)) { return ''; }
     $p_value = trim($p_value);
     $p_value = preg_replace('/^\"/', '', $p_value);
     $p_value = preg_replace('/\"$/', '', $p_value);
@@ -2993,6 +3199,15 @@ function parse_snmp_value($value)
     return $p_value;
 }
 
+function strHexToBin ( $number )    {
+    $result = '';
+    for ( $i = 0; $i < strlen($number); $i++ ){
+        $conv = base_convert($number[$i], 16, 2);
+        $result .= str_pad($conv, 4, '0', STR_PAD_LEFT);
+    }
+    return $result;
+}
+
 function dec_to_hex($mac)
 {
     if (!isset($mac)) {

+ 16 - 0
html/inc/consts.php

@@ -14,6 +14,22 @@ define("dot1qVlanForbiddenEgressPorts",".1.3.6.1.2.1.17.7.1.4.3.1.3");
 define("dot1qVlanStaticUntaggedPorts",".1.3.6.1.2.1.17.7.1.4.3.1.4");
 define("dot1qVlanStaticRowStatus",".1.3.6.1.2.1.17.7.1.4.3.1.5");
 define("dot1qPortVlanEntry",".1.3.6.1.2.1.17.7.1.4.5.1.1");
+
+//fucking Cisco
+//vlan list
+define("vtpVlanName",".1.3.6.1.4.1.9.9.46.1.3.1.1.4.1");
+define("vtpVlanState",".1.3.6.1.4.1.9.9.46.1.3.1.1.2");
+//port vlan member - bit => port number
+define("vmMembershipSummaryMemberPorts",".1.3.6.1.4.1.9.9.68.1.2.1.1.2");
+//encapsulation type ( INTEGER {isl(1),dot10(2),lane(3),dot1Q(4),negotiate(5)})
+define("vlanTrunkPortEncapsulationType",".1.3.6.1.4.1.9.9.46.1.6.1.1.3");
+//trunk vlan - bit => vlan number
+define("vlanTrunkPortVlansEnabled",".1.3.6.1.4.1.9.9.46.1.6.1.1.4");
+//native vlan - all ports always exists
+define("vlanTrunkPortNativeVlan",".1.3.6.1.4.1.9.9.46.1.6.1.1.5");
+//pvid - if port exists => port mode access
+define("vmVlanPvid",".1.3.6.1.4.1.9.9.68.1.2.2.1.2");
+
 //tp-link
 define("TPLINK_dot1qPortVlanEntry",".1.3.6.1.4.1.11863.6.14.1.1.1.1.2");