demo: simplify demoreload.sh
[racktables-contribs] / snmpgeneric.php
index 9b90af3..9fa9979 100644 (file)
 
 /********************************************
  *
- * RackTables snmpgeneric extension
+ * RackTables 0.20.x snmpgeneric extension
  *
+ *     sync an RackTables object with an SNMP device.
  *
- * Let you create ports and ip addresses by reading snmp ifTable / ifxTable / ipAdEntIfIndex (ipAddrTable) / ipAddressIfIndex (ipAddressTable) 
- * If Port name or L2Address already exists the port is not checked for adding.
+ *     Should work with almost any SNMP capable device.
  *
- * Also bind ip addresses to Object if not already allocated.
- * 
- * Let you select the interfaces, ip address and attributes to be created / set.
+ *     reads SNMP tables:
+ *             - system
+ *             - ifTable
+ *             - ifxTable
+ *             - ipAddrTable (ipv4 only)
+ *             - ipAddressTable (ipv4 + ipv6)
+ *             - ipv6AddrAddress (ipv6)
+ *
+ *     Features:
+ *             - update object attributes
+ *             - create networks
+ *             - create ports
+ *             - add and bind ip addresses
+ *             - create as new object
+ *             - save snmp settings per object (uses comment field)
+ *
+ *     Known to work with:
+ *             - Enterasys SecureStacks, S-Series
+ *             - cisco 2620XM (thx to Rob)
+ *             - hopefully many others
+ *
+ *
+ *     Usage:
+ *
+ *             1. select "SNMP generic sync" tap
+ *             2. select your SNMP config (host, v1, v2c or v3, ...)
+ *             3. hit "Show List"
+ *             4. you will see a selection of all information that could be retrieved
+ *             5. select what should be updated and/or created
+ *             6. hit "Create" Button to make changes to RackTables
+ *             7. repeat step 1. to 6. as often as you like / need
  *
- * Won't add anything until "Create Ports and IPs" pressed!
- * 
  *
- * Tested only with some Enterasys switches C/B and S !!!!
- *     cisco 2620XM (thx to Rob)
- * 
- * 
  * needs PHP 5
- * 
+ *
  * TESTED on FreeBSD 9.0, nginx/1.0.12, php 5.3.10, NET-SNMP 5.7.1
- *     and RackTables 0.19.11
+ *     and RackTables <= 0.20.3
  *
- * (c)2012 Maik Ehinger <m.ehinger@ltur.de>
+ * (c)2015 Maik Ehinger <github138@t-online.de>
  */
 
 /****
  * INSTALL
+ *     just place file in plugins directory
+ *
+ *     Increase max_input_vars in php.ini if not all ports were added on one run.
+ *
+ */
+
+/**
+ * The newest version of this plugin can be found at:
+ *
+ * https://github.com/github138/myRT-contribs/tree/develop-0.20.x
  *
- * add to local.php
- *     include 'inc/snmpgeneric.php';
- * 
  */
 
 /* TODOs
- * 
- *  - code cleanup
  *
- *  - update visible label on ifAlias change !?
+ *  - code cleanup
  *
- *  - test if device supprots mibs
+ *  - test if device supports mibs
  *  - gethostbyaddr / gethostbyname host list
  *  - correct iif_name display if != 1
  *
  *  - set more Object attributs / fields
- *  
- */
-
-/*************************
-
- * Change Log
- * 
- * 09.12.11    minor cleanups
- * 10.02.12    make host selectable
- * 16.02.12    use getConfigVar('DEFAULT_SNMP_COMMUNITY');
- *             make snmp port types ignorable (see sg_ifType2oif_id array)
- *             add create_noconnector_ports
- * 17.02.12    changed operator & to &&
- *             make attributes, add port, add ip and port type changeable before create
- *             add sg_oid2attr
- *             add trigger (prepared only)
- *             add sg_ifType_ignore
- * 19.02.12    add ifAlias to visible label 
- *             allow ifName input if empty (preset with ifDescr)
- * 20.02.12    change attribute code
- *             add $sg_known_sysObjectIDs (add $known_switches from snmp.php) to set HW Type
- *             added attribute processor function code
- * 21.02.12    add vendor / device specific ports
- *             change processor function code
- *                     allow to return attributes and ports
- *             add check / uncheck all (doesn't work with IE)
- *             hide snmpv3 settings if not needed
- *             add ifInOctets and ifOutOctets to interface list
- * 22.02.12    add hrefs to l2address and ipaddr
- *             add readonly textfields for ifDescr and ifAlias
- * 23.02.12    change sysObjectID merge code 
- *             change attrib processing code
- *             add regex processor function
- * 25.02.12    prefix global vars with sg_
- *             add SW version for Enterasys devices 
- * 29.02.12    add snmpgeneric_pf_entitymib
- * 03.03.12    fix SNMPv3 support (tested with Enterasys only)
- *             snmpconfig form changes
- * 07.03.12    add commitUpdatePortl2address handling
- *             change to allow multiple ip addresses per interface
- *             get snmp ipv6 addresses ( !!! column order changed !!! ) (experimental)
- * 08.03.12    snmpconfig focus submit button onload
- *             add snmpgeneric_pf_swtype (experimental)
- * 09.03.12    add snmptranslate (set $sg_cmd_snmptranslate) (experimental)
- *             exclude ipv6 link-local addresses (fe80:) (experimental)
- *             handle reserved ip addresses
- *             destroy remaining foreach variables
- * 10.03.12    add missing IPv4 / IPv6 spaces (experimental)
- * 11.03.12    add bcast to ip address
- *             foreach by reference workaround (&$attr)
- *             changed ipv6 link-local addresses handling (fe80:) now ignoring ipv6z address type (experimental)
- * 12.03.12    add regex replacement
- *             changes snmpgeneric_pf_swtype (add oid, regex, replacement)
- *             fix update mac
- * 13.03.12    changed ipv6 link-local addresses handling (fe80:) again (experimental)
- *             update mac fix
- *             don't set attributes if values are equal
- * 20.03.12    correct broadcast calculation for ipaddresstable ipv4
- *             removed disabled checkboxes
- *             snmpgeneric_pf_catalyst multiline sysDescr fix
- *             add device pf
- * 26.03.12    ip spaces create by default
- *             set create button focus
- *                     add confirm message
- *             ip space create fix (invalid ipv6 prefix)
- * 29.03.12    fix cisco OEM S/N 1
- * 02.04.12    add snmpgeneric_pf_ciscoflash
- * 03.04.12    add ciscoMemoryPoolMIB
- *             
+ *
+ *  - Input variables exceeded 1000
+ *  - update iftypes
  *
  */
 
-require_once('snmp.php');
+/* RackTables Debug Mode */
+//$debug_mode=1;
+
+require_once(realpath (dirname (__FILE__).'/../wwwroot').'/inc/snmp.php');
 
 $tab['object']['snmpgeneric'] = 'SNMP Generic sync';
 $tabhandler['object']['snmpgeneric'] = 'snmpgeneric_tabhandler';
-//$trigger['object']['snmpgeneric'] = 'snmpgeneric_tabtrigger';
+$trigger['object']['snmpgeneric'] = 'snmpgeneric_tabtrigger';
 
 $ophandler['object']['snmpgeneric']['create'] = 'snmpgeneric_opcreate';
 
@@ -138,7 +102,7 @@ $sg_ifType_ignore = array(
         '24',  /* softwareLoopback */
         '23',  /* ppp */
         '33',  /* rs232 */
-        '34',  /* para */
+        '34',  /* para */
         '53',  /* propVirtual */
         '77',  /* lapd */
        '131',  /* tunnel */
@@ -150,17 +114,17 @@ $sg_ifType_ignore = array(
 /* ifType to RT oif_id mapping */
 $sg_ifType2oif_id = array(
        /* 440 causes SQLSTATE[23000]: Integrity constraint violation:
-        *                               1452 Cannot add or update a child row: 
+        *                              1452 Cannot add or update a child row:
         *                                      a foreign key constraint fails
         */
        //  '1' => 440, /* other => unknown 440 */
          '1' => 1469,  /* other => virutal port 1469 */
-         '6' => 24,    /* ethernetCsmacd => 1000BASE-T 24 */
+         '6' => 24,    /* ethernetCsmacd => 1000BASE-T 24 */
         '24' => 1469,  /* softwareLoopback => virtual port 1469 */
         '33' => 1469,  /*  rs232 => RS-232 (DB-9) 681 */
-        '34' => 1469,  /* para => virtual port 1469 */
+        '34' => 1469,  /* para => virtual port 1469 */
         '53' => 1469,  /* propVirtual => virtual port 1469 */
-        '62' => 1195,  /* fastEther => 100BASE-FX 1195 */
+        '62' => 19,    /* fastEther => 100BASE-TX 19 */
        '131' => 1469,  /* tunnel => virtual port 1469 */
        '136' => 1469,  /* l3ipvlan => virtual port 1469 */
        '160' => 1469,  /* usb => virtual port 1469 */
@@ -180,16 +144,16 @@ $sg_known_sysObjectIDs = array
                'pf' => array('snmpgeneric_pf_entitymib'),
                'attr' => array
                (
-                        2 => array('pf' => 'snmpgeneric_pf_hwtype'),                                   /* HW Typ*/
+                        2 => array('pf' => 'snmpgeneric_pf_hwtype'),                                   /* HW Typ*/
                         3 => array('oid' => 'sysName.0'),
                                /* FQDN check only if regex matches */
                         //3 => array('oid' => 'sysName.0', 'regex' => '/^[^ .]+(\.[^ .]+)+\.?/', 'uncheck' => 'no FQDN'),
                         4 => array('pf' => 'snmpgeneric_pf_swtype', 'uncheck' => 'experimental'),      /* SW type */
                         14 => array('oid' => 'sysContact.0'),                                          /* Contact person */
                        // 1235 => array('value' => 'Constant'),
-               ), 
+               ),
                'port' => array
-               ( 
+               (
                        // 'AC-in' => array('porttypeid' => '1-16', 'uncheck' => 'uncheck reason/comment'),
                        // 'name' => array('porttypeid' => '1-24', 'ifDescr' => 'visible label'),
                ),
@@ -207,9 +171,9 @@ $sg_known_sysObjectIDs = array
                'attr' => array(
                                4 => array('pf' => 'snmpgeneric_pf_catalyst'), /* SW type/version */
                                16 => array('pf' => 'snmpgeneric_pf_ciscoflash'), /*  flash memory */
-                       
+
                                ),
-               
+
        ),
        /* ------------ Microsoft --------------- */
        '311' => array
@@ -230,72 +194,78 @@ $sg_known_sysObjectIDs = array
 
        /* Enterasys N3 */
        '5624.2.1.53' => array
-       (       
-               'dict_key' => 50000,
-               'text' => 'N3', 
-       ), 
+       (
+               'dict_key' => 2021,
+               'text' => 'Matrix N3',
+       ),
 
        '5624.2.2.284' => array
-       (       
+       (
                'dict_key' => 50002,
-               'text' => 'Securestack C2', 
-       ), 
+               'text' => 'Securestack C2',
+       ),
 
        '5624.2.1.98' => array
-       (       
+       (
                'dict_key' => 50002,
-               'text' => 'Securestack C3', 
-       ), 
+               'text' => 'Securestack C3',
+       ),
 
        '5624.2.1.100' => array
-       (       
+       (
                'dict_key' => 50002,
-               'text' => 'Securestack B3', 
-       ), 
+               'text' => 'Securestack B3',
+       ),
 
        '5624.2.1.128' => array
-       (       
-               'dict_key' => 50001,
-               'text' => 'S-series', 
-       ), 
+       (
+               'dict_key' => 1970,
+               'text' => 'S-series SSA130',
+       ),
 
        '5624.2.1.129' => array
-       (       
-               'dict_key' => 50001,
-               'text' => 'S-series', 
-       ), 
+       (
+               'dict_key' => 1970,
+               'text' => 'S-series SSA150',
+       ),
 
        '5624.2.1.137' => array
-       (       
-               'dict_key' => 50002,
-               'text' => 'Securestack B5 POE', 
-       ), 
+       (
+               'dict_key' => 1987,
+               'text' => 'Securestack B5 POE',
+       ),
 
        /* S3 */
        '5624.2.1.131' => array
        (
-               'dict_key' => 50001,
-               'text' => 'S-series',
+               'dict_key' => 1974,
+               'text' => 'S-series S3',
        ),
 
        /* S4 */
        '5624.2.1.132' => array
        (
-               'dict_key' => 50001, 
-               'text' => 'S-series'
+               'dict_key' => 1975,
+               'text' => 'S-series S4'
        ),
 
        /* S8 */
        '5624.2.1.133' => array
        (
-               'dict_key' => 50001, 
-               'text' => 'S-series'
+               'dict_key' => 1977,
+               'text' => 'S-series S8'
+       ),
+
+       '5624.2.1.165' => array
+       (
+               'dict_key' => 1971,
+               'text' => 'S-series Bonded SSA',
        ),
 
        /* ------------ net-snmp --------------- */
        '8072' => array
        (
-               'text' => 'net-snmp',
+               'text' => 'net-snmp',
                'attr' => array(
                                4 => array('pf' => 'snmpgeneric_pf_swtype', 'oid' => 'sysDescr.0', 'regex' => '/(.*?) .*? (.*?) .*/', 'replacement' => '\\1 \\2', 'uncheck' => 'TODO RT matching'), /*SW type */
                                ),
@@ -366,29 +336,30 @@ function snmpgeneric_pf_enterasys(&$snmp, &$sysObjectID, $attr_id) {
                /* TODO find correct way to get Bootroom and Firmware versions */
 
                /* Model */
-               /*if(preg_match('/.*\.([^.]+)$/', $sysObjectID['value'], $matches)) {
+               /*if(preg_match('/.*\.([^.]+)$/', $sysObjectID['value'], $matches)) {
                 *      showNotice('Device '.$matches[1]);
                 *}
                 */
 
                /* TODO SW type */
                //$attrs[4]['value'] = 'Enterasys'; /* SW type */
+               $attrs[4]['key'] = '0'; /* SW type dict key 0 = NOT SET*/
 
                /* set SW version only if not already set by entitymib */
                if(isset($attrs[5]['value']) && !empty($attrs[5]['value'])) {
-               
+
                        /* SW version from sysDescr */
-                       if(preg_match('/^Enterasys .* Inc\. (.+) [Rr]ev ([^ ]+) ?(.*)$/', $snmp->sysDescr, $matches)) {
+                       if(preg_match('/^Enterasys .* Inc\. (.+) [Rr]ev ([^ ]+) ?(.*)$/', $snmp->sysDescr, $matches)) {
 
                                $attrs[5]['value'] = $matches[2]; /* SW version */
-       
+
                        //      showSuccess("Found Enterasys Model ".$matches[1]);
                        }
 
                } /* SW version */
 
                /* add serial port */
-               //$sysObjectID['port']['console'] = array('porttypeid' => '1-29',  'ifDescr' => 'console', 'disabled' => 'disabled');
+               //$sysObjectID['port']['console'] = array('porttypeid' => '1-29',  'ifDescr' => 'console', 'disabled' => 'disabled');
 
 }
 
@@ -397,24 +368,27 @@ function snmpgeneric_pf_enterasys(&$snmp, &$sysObjectID, $attr_id) {
 /* logic from snmp.php */
 function snmpgeneric_pf_catalyst(&$snmp, &$sysObjectID, $attr_id) {
                $attrs = &$sysObjectID['attr'];
-               $ports = &$sysObjectID['port'];
+               $ports = &$sysObjectID['port'];
 
                /* sysDescr multiline on C5200 */
                 if(preg_match ('/.*, Version ([^ ]+), .*/', $snmp->sysDescr, $matches)) {
                        $exact_release = $matches[1];
-                       $major_line = preg_replace ('/^([[:digit:]]+\.[[:digit:]]+)[^[:digit:]].*/', '\\1', $exact_release);
+               $major_line = preg_replace ('/^([[:digit:]]+\.[[:digit:]]+)[^[:digit:]].*/', '\\1', $exact_release);
 
                        $ios_codes = array
-                       (
-                                       '12.0' => 244,
-                                       '12.1' => 251,
-                                       '12.2' => 252,
-                       );
-               
+               (
+                               '12.0' => 244,
+                               '12.1' => 251,
+                               '12.2' => 252,
+               );
+
                        $attrs[5]['value'] = $exact_release;
 
-                       if (array_key_exists ($major_line, $ios_codes))
+                       if (array_key_exists ($major_line, $ios_codes))
+                       {
                                $attrs[4]['value'] = $ios_codes[$major_line];
+                               $attrs[4]['key'] = $ios_codes[$major_line];
+                       }
 
                } /* sw type / version */
 
@@ -422,22 +396,22 @@ function snmpgeneric_pf_catalyst(&$snmp, &$sysObjectID, $attr_id) {
                 if ($sysChassi !== FALSE or $sysChassi !== NULL)
                        $attrs[1]['value'] = str_replace ('"', '', $sysChassi);
 
-               $ports['con0'] = array('porttypeid' => '1-29',  'ifDescr' => 'console'); // RJ-45 RS-232 console
+               $ports['con0'] = array('porttypeid' => '1-29',  'ifDescr' => 'console'); // RJ-45 RS-232 console
 
                if (preg_match ('/Cisco IOS Software, C2600/', $snmp->sysDescr))
-                       $ports['aux0'] = array('porttypeid' => '1-29', 'ifDescr' => 'auxillary'); // RJ-45 RS-232 aux port
+                       $ports['aux0'] = array('porttypeid' => '1-29', 'ifDescr' => 'auxillary'); // RJ-45 RS-232 aux port
 
                 // blade devices are powered through internal circuitry of chassis
                 if ($sysObjectID['value'] != '9.1.749' and $sysObjectID['value'] != '9.1.920')
                 {
-                       $ports['AC-in'] = array('porttypeid' => '1-16');
+                       $ports['AC-in'] = array('porttypeid' => '1-16');
                 }
 
 } /* snmpgeneric_pf_catalyst */
 
 /* -------------------------------------------------- */
 function snmpgeneric_pf_ciscoflash(&$snmp, &$sysObjectID, $attr_id) {
-       /* 
+       /*
         * ciscoflashMIB = 1.3.6.1.4.1.9.9.10
         */
        /*
@@ -445,7 +419,10 @@ function snmpgeneric_pf_ciscoflash(&$snmp, &$sysObjectID, $attr_id) {
        */
        $attrs = &$sysObjectID['attr'];
 
-       $ciscoflash = $snmp->walk('1.3.6.1.4.1.9.9.10.1.1.2'); /* ciscoFlashDeviceTable */ 
+       $ciscoflash = $snmp->walk('1.3.6.1.4.1.9.9.10.1.1.2'); /* ciscoFlashDeviceTable */
+
+       if(!$ciscoflash)
+               return;
 
        $flash = array_keys($ciscoflash, 'flash');
 
@@ -458,7 +435,7 @@ function snmpgeneric_pf_ciscoflash(&$snmp, &$sysObjectID, $attr_id) {
 
                showSuccess("Found Flash: ".$ciscoflash[$prefix.'.8.'.$index]." ".$ciscoflash[$prefix.'.2.'.$index]." bytes");
 
-               $attrs[16]['value'] = $ciscoflash[$prefix.'.2.'.$index] / 1024 / 1024; /* ciscoFlashDeviceSize */
+               $attrs[16]['value'] = ceil($ciscoflash[$prefix.'.2.'.$index] / 1024 / 1024); /* ciscoFlashDeviceSize */
 
        }
 
@@ -476,7 +453,7 @@ function snmpgeneric_pf_ciscoflash(&$snmp, &$sysObjectID, $attr_id) {
                $free = 0;
 
                foreach($ciscomem as $oid => $value) {
-                       
+
                        switch(preg_replace('/.*?(\.1\.1\.1\.[^\.]+)\.[^\.]+$/','\\1',$oid)) {
                                case '.1.1.1.5':
                                        $used += $value;
@@ -488,7 +465,7 @@ function snmpgeneric_pf_ciscoflash(&$snmp, &$sysObjectID, $attr_id) {
 
                }
 
-               $attrs[17]['value'] = (int)(($free + $used) / 1024 / 1024); /* RAM, MB */
+               $attrs[17]['value'] = ceil(($free + $used) / 1024 / 1024); /* RAM, MB */
        }
 
 } /* snmpgeneric_pf_ciscoflash */
@@ -505,9 +482,10 @@ function snmpgeneric_pf_hwtype(&$snmp, &$sysObjectID, $attr_id) {
 
                $value = $sysObjectID['dict_key'];
                showSuccess("Found HW type dict_key: $value");
-       
+
                /* return array of attr_id => attr_value) */
                $attr['value'] = $value;
+               $attr['key'] = $value;
 
        } else {
                showNotice("HW type dict_key not set - Unknown OID");
@@ -524,7 +502,7 @@ function snmpgeneric_pf_swtype(&$snmp, &$sysObjectID, $attr_id) {
 
        /* 4 = SW type */
 
-       $attr = &$sysObjectID['attr'][$attr_id]; 
+       $attr = &$sysObjectID['attr'][$attr_id];
 
        $object = &$sysObjectID['object'];
 
@@ -533,7 +511,7 @@ function snmpgeneric_pf_swtype(&$snmp, &$sysObjectID, $attr_id) {
        if(isset($attr['oid']))
                $oid = $attr['oid'];
        else
-               $oid = 'sysDescr.0'; 
+               $oid = 'sysDescr.0';
 
        $raw_value = $snmp->get($oid);
 
@@ -558,12 +536,12 @@ function snmpgeneric_pf_swtype(&$snmp, &$sysObjectID, $attr_id) {
        if(!empty($value) && $count > 0) {
                /* search dict_key for value in RT Dictionary */
                /* depends on object type server(13)/switch(14)/router(15) */
-                $result = usePreparedSelectBlade
-                       (       
-                               'SELECT dict_key,dict_value FROM Dictionary WHERE chapter_id in (13,14,15) and dict_value like ? order by dict_key desc limit 1',
-                               array ('%'.$value.'%')
-                       );
-                       $row = $result->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_COLUMN);
+               $result = usePreparedSelectBlade
+               (
+                       'SELECT dict_key,dict_value FROM Dictionary WHERE chapter_id in (13,14,15) and dict_value like ? order by dict_key desc limit 1',
+                       array ('%'.$value.'%')
+               );
+               $row = $result->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_COLUMN);
 
                if(!empty($row)) {
                        $RTvalue = key($row);
@@ -579,6 +557,7 @@ function snmpgeneric_pf_swtype(&$snmp, &$sysObjectID, $attr_id) {
 
                /* set attr value */
                $attr['value'] = $value;
+               $attr['key'] = $value;
        //      unset($attr['uncheck']);
 
        }
@@ -591,13 +570,13 @@ function snmpgeneric_pf_swtype(&$snmp, &$sysObjectID, $attr_id) {
 } /* snmpgeneric_pf_swtype */
 
 /* -------------------------------------------------- */
-/* try to set SW version 
+/* try to set SW version
  * and add some AC ports
  *
  */
 /* needs more testing */
 function snmpgeneric_pf_entitymib(&$snmp, &$sysObjectID, $attr_id) {
-       
+
        /* $attr_id == NULL -> device pf */
 
        $attrs = &$sysObjectID['attr'];
@@ -610,7 +589,7 @@ function snmpgeneric_pf_entitymib(&$snmp, &$sysObjectID, $attr_id) {
 
        showNotice("Found Entity Table (Experimental)");
 
-/*             PhysicalClass 
+/*             PhysicalClass
  *             1:other
  *             2:unknown
  *             3:chassis
@@ -636,16 +615,16 @@ function snmpgeneric_pf_entitymib(&$snmp, &$sysObjectID, $attr_id) {
 
                foreach($chassis as $key => $oid) {
                        /* get index */
-                       if(!preg_match('/\.(\d+)$/',$oid, $matches)) 
+                       if(!preg_match('/\.(\d+)$/',$oid, $matches))
                                continue;
 
-                       $index = $matches[1]; 
+                       $index = $matches[1];
+
+                       $name = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.7.$index");
+                       $serialnum = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.11.$index");
+                       $mfgname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.12.$index");
+                       $modelname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.13.$index");
 
-                       $name = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.7.$index"); 
-                       $serialnum = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.11.$index"); 
-                       $mfgname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.12.$index"); 
-                       $modelname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.13.$index"); 
-               
                        //showNotice("$name $mfgname $modelname $serialnum");
 
                        echo("<tr><td>$name</td><td>$mfgname</td><td>$modelname</td><td>$serialnum</td>");
@@ -666,23 +645,27 @@ function snmpgeneric_pf_entitymib(&$snmp, &$sysObjectID, $attr_id) {
 
                echo '<br><br>Modules<br><table>';
                echo("<tr><th>Name</th><th>MfgName</th><th>ModelName</th><th>HardwareRev</th><th>FirmwareRev</th><th>SoftwareRev</th><th>SerialNum</th>");
-       
+
                foreach($modules as $key => $oid) {
 
                        /* get index */
-                       if(!preg_match('/\.(\d+)$/',$oid, $matches)) 
+                       if(!preg_match('/\.(\d+)$/',$oid, $matches))
                                continue;
 
-                       $index = $matches[1]; 
+                       $index = $matches[1];
+
+                       $name = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.7.$index");
+
+                       if(!$name)
+                               continue;
+
+                       $hardwarerev = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.8.$index");
+                       $firmwarerev = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.9.$index");
+                       $softwarerev = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.10.$index");
+                       $serialnum = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.11.$index");
+                       $mfgname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.12.$index");
+                       $modelname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.13.$index");
 
-                       $name = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.7.$index"); 
-                       $hardwarerev = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.8.$index"); 
-                       $firmwarerev = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.9.$index"); 
-                       $softwarerev = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.10.$index"); 
-                       $serialnum = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.11.$index"); 
-                       $mfgname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.12.$index"); 
-                       $modelname = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.13.$index"); 
-               
                        //showNotice("$name $mfgname $modelname $hardwarerev $firmwarerev $softwarerev $serialnum");
 
                        echo("<tr><td>".(empty($name) ? '-' : $name )."</td><td>$mfgname</td><td>$modelname</td><td>$hardwarerev</td><td>$firmwarerev</td><td>$softwarerev</td><td>$serialnum</td>");
@@ -708,13 +691,13 @@ function snmpgeneric_pf_entitymib(&$snmp, &$sysObjectID, $attr_id) {
        foreach($powersupply as $oid) {
 
                /* get index */
-               if(!preg_match('/\.(\d+)$/',$oid, $matches)) 
+               if(!preg_match('/\.(\d+)$/',$oid, $matches))
                        continue;
 
-               $index = $matches[1]; 
-               $descr = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.2.$index"); 
+               $index = $matches[1];
+               $descr = $snmp->get(".1.3.6.1.2.1.47.1.1.1.1.2.$index");
 
-               $ports['AC-'.$count] = array('porttypeid' => '1-16', 'ifDescr' => $descr, 'comment' => 'entity MIB', 'uncheck' => '');
+               $ports['AC-'.$count] = array('porttypeid' => '1-16', 'ifDescr' => $descr, 'comment' => 'entity MIB', 'uncheck' => '');
                $count++;
        }
        unset($oid);
@@ -745,11 +728,11 @@ function snmpgeneric_pf_regex(&$snmp, &$sysObjectID, $attr_id) {
                        $replace = '\\1';
 
                $value = preg_replace($regex,$replace, $raw_value);
-       
+
                /* return array of attr_id => attr_value) */
                $attr['value'] = $value;
 
-       } 
+       }
        // else Warning ??
 
 } /* snmpgeneric_pf_regex */
@@ -759,17 +742,125 @@ function snmpgeneric_pf_regex(&$snmp, &$sysObjectID, $attr_id) {
 $sg_portiifoptions= getPortIIFOptions();
 $sg_portiifoptions[-1] = 'sfp'; /* generic sfp */
 
-$sg_portoifoptions= getPortOIOptions();
+$sg_portoifoptions= getPortOIFOptions();
 
 /* -------------------------------------------------- */
 /* -------------------------------------------------- */
 
 function snmpgeneric_tabhandler($object_id) {
 
-       if(isset($_POST['snmpconfig'])) {
-               if($_POST['snmpconfig'] == '1') {
-                       snmpgeneric_list($object_id);
-               }       
+//     sg_var_dump_html($_POST);
+
+       if(isset($_POST['asnewobject']) && $_POST['asnewobject'] == "1")
+       {
+               $newobject_name = $_POST['object_name'];
+               $newobject_label = $_POST['object_label'];
+               $newobject_type_id = $_POST['object_type_id'];
+               $newobject_asset_no = $_POST['object_asset_no'];
+
+               if(sg_checkObjectNameUniqueness($newobject_name, $newobject_type_id))
+               {
+
+                       $object_id = commitAddObject($newobject_name, $newobject_label, $newobject_type_id, $newobject_asset_no);
+
+                       $_POST['asnewobject'] = "0";
+
+                       parse_str($_SERVER['QUERY_STRING'],$query_string);
+
+                       $query_string['object_id'] = $object_id;
+
+                       $_SERVER['QUERY_STRING'] = http_build_query($query_string);
+
+                       list($path, $qs) = explode('?',$_SERVER['REQUEST_URI'],2);
+                       $_SERVER['REQUEST_URI'] = $path.'?'.$_SERVER['QUERY_STRING'];
+
+
+                       // switch to new object
+                       echo '<body>';
+                       echo '<body onload="document.forms[\'newobject\'].submit();">';
+
+                       echo '<form method=POST id=newobject action='.$_SERVER['REQUEST_URI'].'>';
+
+                       foreach($_POST as $name => $value)
+                       {
+                               echo "<input type=hidden name=$name value=$value>";
+                       }
+
+                       echo '<input type=submit id="submitbutton" tabindex="1" value="Show List">';
+                       echo '</from></body>';
+                       exit;
+               }
+               else
+               {
+                       showError("Object with name: \"$newobject_name\" already exists!!!");
+                       $_POST['snmpconfig'] = "0";
+               }
+       }
+
+       // save snmp settings
+       if(isset($_POST['save']) && $_POST['save'] == "1")
+       {
+               // TODO save only on success !!
+
+               $object = spotEntity('object', $object_id);
+
+               $snmpvalues[0] = 'SNMP';
+               $snmpnames = array('host', 'version', 'community');
+               if($_POST['version'] == "v3")
+                       $snmpnames = array_merge($snmpnames, array('sec_level','auth_protocol','auth_passphrase','priv_protocol','priv_passphrase'));
+
+               foreach($snmpnames as $key => $value)
+               {
+                       if(isset($_POST[$value]))
+                       {
+                               switch($value)
+                               {
+                                       case "auth_passphrase":
+                                       case "priv_passphrase":
+                                               $snmpvalues[$key + 1] = base64_encode($_POST[$value]);
+                                               break;
+
+                                       default: $snmpvalues[$key + 1] = $_POST[$value];
+                               }
+                       }
+               }
+
+       //      sg_var_dump_html($snmpvalues);
+
+               $newsnmpstr = implode($snmpvalues,":");
+
+               $snmpstr = strtok($object['comment'],"\n\r");
+
+               $snmpstrarray = explode(':', $snmpstr);
+
+               $setcomment = "set";
+                if($snmpstrarray[0] == "SNMP")
+               {
+                       if($newsnmpstr == $snmpstr)
+                               $setcomment = "ok";
+                       else
+                               $setcomment = "update";
+               }
+
+               if($setcomment != "ok")
+               {
+
+                       if($setcomment == "update")
+                               $comment = str_replace($snmpstr,$newsnmpstr, $object['comment']);
+                       else
+                               $comment = "$newsnmpstr\n".$object['comment'];
+
+               //      echo "$snmpnewstr ".$object['comment']." --> $comment";
+
+                       commitUpdateObject($object_id, $object['name'], NULL, $object['has_problems'], NULL, $comment );
+                       showNotice("$setcomment SNMP Settings: $newsnmpstr");
+
+               }
+
+       }
+
+       if(isset($_POST['snmpconfig']) && $_POST['snmpconfig'] == '1') {
+               snmpgeneric_list($object_id);
        } else {
                snmpgeneric_snmpconfig($object_id);
        }
@@ -777,22 +868,23 @@ function snmpgeneric_tabhandler($object_id) {
 
 /* -------------------------------------------------- */
 
-//function snmpgeneric_tabtrigger() {
-//     return 'std';
-//} /* snmpgeneric_tabtrigger */
+function snmpgeneric_tabtrigger() {
+       // display tab only on IPv4 Objects
+       return considerConfiguredConstraint (spotEntity ('object', getBypassValue()), 'IPV4OBJ_LISTSRC') ? 'std' : '';
+} /* snmpgeneric_tabtrigger */
 
 /* -------------------------------------------------- */
 
 function snmpgeneric_snmpconfig($object_id) {
 
-       echo '<body onload="document.getElementById(\'submitbutton\').focus();">';
 
        $object = spotEntity ('object', $object_id);
        //$object['attr'] = getAttrValues($object_id);
         $endpoints = findAllEndpoints ($object_id, $object['name']);
 
        addJS('function showsnmpv3(element) {
-                               if(element.value != \''.SNMPgeneric::VERSION_3.'\') {
+                               var style;
+                               if(element.value != \'v3\') {
                                        style = \'none\';
                                        document.getElementById(\'snmp_community_label\').style.display=\'\';
                                } else {
@@ -800,12 +892,46 @@ function snmpgeneric_snmpconfig($object_id) {
                                        document.getElementById(\'snmp_community_label\').style.display=\'none\';
                                }
 
-                               elements = document.getElementsByName(\'snmpv3\');
-                               for(i=0;i<elements.length;i++) {
+                               var elements = document.getElementsByName(\'snmpv3\');
+                               for(var i=0;i<elements.length;i++) {
                                        elements[i].style.display=style;
                                }
                        };',TRUE);
 
+       addJS('function shownewobject(element) {
+                               var style;
+
+                               if(element.checked) {
+                                       style = \'\';
+                               } else {
+                                       style = \'none\';
+                               }
+
+                               var elements = document.getElementsByName(\'newobject\');
+                               for(var i=0;i<elements.length;i++) {
+                                       elements[i].style.display=style;
+                               }
+                       };',TRUE);
+
+       addJS('function checkInput() {
+                               var host = document.getElementById(\'host\');
+
+                               if(host.value == "-1") {
+                                       var newvalue = prompt("Enter Hostname or IP Address","");
+                                       if(newvalue != "") {
+                                               host.options[host.options.length] = new Option(newvalue, newvalue);
+                                               host.value = newvalue;
+                                       }
+                               }
+
+                               if(host.value != "-1" && host.value != "")
+                                       return true;
+                               else
+                                       return false;
+                       };',TRUE);
+
+       echo '<body onload="document.getElementById(\'submitbutton\').focus(); showsnmpv3(document.getElementById(\'snmpversion\')); shownewobject(document.getElementById(\'asnewobject\'));">';
+
        foreach( $endpoints as $key => $value) {
                $endpoints[$value] = $value;
                unset($endpoints[$key]);
@@ -815,6 +941,8 @@ function snmpgeneric_snmpconfig($object_id) {
 
        foreach( getObjectIPv4Allocations($object_id) as $ip => $value) {
 
+               $ip = ip_format($ip);
+
                if(!in_array($ip, $endpoints))
                        $endpoints[$ip] = $ip;
        }
@@ -822,17 +950,69 @@ function snmpgeneric_snmpconfig($object_id) {
        unset($value);
 
        foreach( getObjectIPv6Allocations($object_id) as $value) {
-               $ip = $value['addrinfo']['ip'];
+               $ip = ip_format(ip_parse($value['addrinfo']['ip']));
 
                if(!in_array($ip, $endpoints))
                        $endpoints[$ip] = $ip;
        }
        unset($value);
 
-       $snmpconfig = $_POST;
+       /* ask for ip/host name on submit see js checkInput() */
+       $endpoints['-1'] = 'ask me';
+
+       // saved snmp settings
+       $snmpstr = strtok($object['comment'],"\n\r");
+       $snmpstrarray = explode(':', $snmpstr);
+
+       if($snmpstrarray[0] == "SNMP")
+       {
+               /* keep it compatible with older version */
+               switch($snmpstrarray[2])
+               {
+                       case "1":
+                               $snmpstrarray[2] = 'v1';
+                               break;
+                       case "2":
+                       case "v2C":
+                               $snmpstrarray[2] = 'v2c';
+                               break;
+                       case "3":
+                               $snmpstrarray[2] = 'v3';
+                               break;
+               }
+
+               $snmpnames = array('SNMP','host', 'version', 'community');
+               if($snmpstrarray[2] == "v3")
+                       $snmpnames = array_merge($snmpnames, array('sec_level','auth_protocol','auth_passphrase','priv_protocol','priv_passphrase'));
+
+               $snmpvalues = array();
+               foreach($snmpnames as $key => $value)
+               {
+                       if(isset($snmpstrarray[$key]))
+                       {
+                               switch($key)
+                               {
+                                       case 6:
+                                       case 8:
+                                               $snmpvalues[$value] = base64_decode($snmpstrarray[$key]);
+                                               break;
+
+                                       default: $snmpvalues[$value] = $snmpstrarray[$key];
+                               }
+                       }
+               }
+
+               unset($snmpvalues['SNMP']);
+
+               $snmpconfig = $snmpvalues;
+       }
+       else
+               $snmpconfig = array();
+
+       $snmpconfig += $_POST;
 
        if(!isset($snmpconfig['host'])) {
-               $snmpconfig['host'] = NULL;
+               $snmpconfig['host'] = -1;
 
                /* try to find first FQDN or IP */
                foreach($endpoints as $value) {
@@ -844,9 +1024,9 @@ function snmpgeneric_snmpconfig($object_id) {
                unset($value);
        }
 
-//     sg_var_dump_html($endpoints);   
+//     sg_var_dump_html($endpoints);
 
-       if(!isset($snmpconfig['snmpversion']))
+       if(!isset($snmpconfig['version']))
                $snmpconfig['version'] = mySNMP::SNMP_VERSION;
 
        if(!isset($snmpconfig['community']))
@@ -870,20 +1050,46 @@ function snmpgeneric_snmpconfig($object_id) {
        if(!isset($snmpconfig['priv_passphrase']))
                $snmpconfig['priv_passphrase'] = NULL;
 
+       if(!isset($snmpconfig['asnewobject']))
+               $snmpconfig['asnewobject'] = NULL;
+
+       if(!isset($snmpconfig['object_type_id']))
+               $snmpconfig['object_type_id'] = '8';
+
+       if(!isset($snmpconfig['object_name']))
+               $snmpconfig['object_name'] = NULL;
+
+       if(!isset($snmpconfig['object_label']))
+               $snmpconfig['object_label'] = NULL;
+
+       if(!isset($snmpconfig['object_asset_no']))
+               $snmpconfig['object_asset_no'] = NULL;
+
+       if(!isset($snmpconfig['save']))
+               $snmpconfig['save'] = true;
+
+//     sg_var_dump_html($snmpconfig);
+
+//     $snmpv3displaystyle = ($snmpconfig['version'] == "3" ? "style=\"\"" : "style=\"display:none;\"");
+
        echo '<h1 align=center>SNMP Config</h1>';
-       echo '<form method=post name="snmpconfig" action='.$_SERVER['REQUEST_URI'].' />';
+       echo '<form method=post name="snmpconfig" onsubmit="return checkInput()" action='.$_SERVER['REQUEST_URI'].' />';
 
         echo '<table cellspacing=0 cellpadding=5 align=center class=widetable>
        <tr><th class=tdright>Host:</th><td>';
-       
-       echo getSelect ($endpoints, array ('name' => 'host'), $snmpconfig['host'], FALSE);
+
+       //if($snmpconfig['asnewobject'] == '1' )
+       if($snmpconfig['host'] != '-1' and !isset($endpoints[$snmpconfig['host']]))
+               $endpoints[$snmpconfig['host']] = $snmpconfig['host'];
+
+       echo getSelect ($endpoints, array ('id' => 'host','name' => 'host'), $snmpconfig['host'], FALSE);
 
        echo'</td></tr>
-               <tr>
+       <tr>
                 <th class=tdright><label for=snmpversion>Version:</label></th>
                 <td class=tdleft>';
 
-       echo getSelect (array(SNMPgeneric::VERSION_1 => 'v1', SNMPgeneric::VERSION_2C => 'v2c', SNMPgeneric::VERSION_3 => 'v3'),
+       echo getSelect (array("v1" => 'v1', "v2c" => 'v2c', "v3" => 'v3'),
                         array ('name' => 'version', 'id' => 'snmpversion', 'onchange' => 'showsnmpv3(this)'),
                         $snmpconfig['version'], FALSE);
 
@@ -891,7 +1097,7 @@ function snmpgeneric_snmpconfig($object_id) {
         </tr>
         <tr>
                 <th id="snmp_community_label" class=tdright><label for=community>Community:</label></th>
-                <th name="snmpv3" style="display:none" class=tdright><label for=community>Security Name:</label></th>
+                <th name="snmpv3" style="display:none;" class=tdright><label for=community>Security Name:</label></th>
                 <td class=tdleft><input type=text name=community value='.$snmpconfig['community'].' ></td>
         </tr>
         <tr name="snmpv3" style="display:none;">
@@ -929,6 +1135,39 @@ function snmpgeneric_snmpconfig($object_id) {
                 <td class=tdleft><input type=password name=priv_passphrase value="'.$snmpconfig['priv_passphrase'].'"></td>
         </tr>
        </tr>
+
+       <tr>
+               <th></th>
+               <td class=tdleft>
+               <input name=asnewobject id=asnewobject type=checkbox value=1 onchange="shownewobject(this)"'.($snmpconfig['asnewobject'] == '1' ? ' checked="checked"' : '').'>
+               <label>Create as new object</label></td>
+       </tr>';
+
+//     $newobjectdisplaystyle = ($snmpconfig['asnewobject'] == '1' ? "" : "style=\"display:none;\"");
+
+       echo '<tr name="newobject" style="display:none;">
+       <th class=tdright>Type:</th><td class=tdleft>';
+
+       $typelist = withoutLocationTypes (readChapter (CHAP_OBJTYPE, 'o'));
+        $typelist = cookOptgroups ($typelist);
+
+       printNiftySelect ($typelist, array ('name' => "object_type_id"), $snmpconfig['object_type_id']);
+
+        echo '</td></tr>
+
+       <tr name="newobject" style="display:none;">
+       <th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='.$snmpconfig['object_name'].'></td></tr>
+       <tr name="newobject" style="display:none;">
+       <th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='.$snmpconfig['object_label'].'></td></tr>
+       <tr name="newobject" style="display:none;">
+       <th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='.$snmpconfig['object_asset_no'].'></td></tr>
+
+       <tr>
+               <th></th>
+               <td class=tdleft>
+               <input name=save id=save type=checkbox value=1'.($snmpconfig['save'] == '1' ? ' checked="checked"' : '').'>
+               <label>Save SNMP settings for object</label></td>
+       </tr>
        <td colspan=2>
 
         <input type=hidden name=snmpconfig value=1>
@@ -940,19 +1179,21 @@ function snmpgeneric_snmpconfig($object_id) {
 
 function snmpgeneric_list($object_id) {
 
-       global $sg_create_noconnector_ports, $sg_known_sysObjectIDs, $sg_portoifoptions, $sg_ifType_ignore;
+       global $sg_create_noconnector_ports, $sg_known_sysObjectIDs, $sg_portoifoptions, $sg_ifType_ignore;
 
        if(isset($_POST['snmpconfig'])) {
-               $snmpconfig = $_POST;   
+               $snmpconfig = $_POST;
        } else {
                showError("Missing SNMP Config");
                return;
        }
 
+//     sg_var_dump_html($snmpconfig);
+
        echo '<body onload="document.getElementById(\'createbutton\').focus();">';
 
        addJS('function setchecked(classname) { var boxes = document.getElementsByClassName(classname);
-                                value = document.getElementById(classname).checked;
+                                var value = document.getElementById(classname).checked;
                                 for(i=0;i<boxes.length;i++) {
                                        if(boxes[i].disabled == false)
                                                boxes[i].checked=value;
@@ -965,7 +1206,7 @@ function snmpgeneric_list($object_id) {
 
        $snmpdev = new mySNMP($snmpconfig['version'], $snmpconfig['host'], $snmpconfig['community']);
 
-       if($snmpconfig['version'] == SNMPgeneric::VERSION_3 ) {
+       if($snmpconfig['version'] == "v3" ) {
                $snmpdev->setSecurity( $snmpconfig['sec_level'],
                                        $snmpconfig['auth_protocol'],
                                        $snmpconfig['auth_passphrase'],
@@ -983,7 +1224,7 @@ function snmpgeneric_list($object_id) {
 
        /* SNMP connect successfull */
 
-       showSuccess("SNMP v".$snmpconfig['version']." connect to ${snmpconfig['host']} successfull");
+       showSuccess("SNMP ".$snmpconfig['version']." connect to ${snmpconfig['host']} successfull");
 
        echo '<form name=CreatePorts method=post action='.$_SERVER['REQUEST_URI'].'&module=redirect&op=create>';
 
@@ -1037,7 +1278,7 @@ function snmpgeneric_list($object_id) {
        /* array_merge doesn't work with numeric keys !! */
        $sysObjectID['attr'] = array();
        $sysObjectID['port'] = array();
-               
+
        $sysobjid = $sysObjectID['value'];
 
        $count = 1;
@@ -1046,20 +1287,20 @@ function snmpgeneric_list($object_id) {
 
                if(isset($sg_known_sysObjectIDs[$sysobjid])) {
                        $sysObjectID = $sysObjectID + $sg_known_sysObjectIDs[$sysobjid];
-       
+
                        if(isset($sg_known_sysObjectIDs[$sysobjid]['attr']))
                                $sysObjectID['attr'] = $sysObjectID['attr'] + $sg_known_sysObjectIDs[$sysobjid]['attr'];
-       
+
                        if(isset($sg_known_sysObjectIDs[$sysobjid]['port']))
                                $sysObjectID['port'] = $sysObjectID['port'] + $sg_known_sysObjectIDs[$sysobjid]['port'];
-       
+
                        if(isset($sg_known_sysObjectIDs[$sysobjid]['text'])) {
                                showSuccess("found sysObjectID ($sysobjid) ".$sg_known_sysObjectIDs[$sysobjid]['text']);
                        }
                }
 
                $sysobjid = preg_replace('/\.[[:digit:]]+$/','',$sysobjid, 1, $count);
-               
+
                /* add default sysobjectid */
                if($count == 0 && $sysobjid != 'default') {
                        $sysobjid = 'default';
@@ -1089,13 +1330,16 @@ function snmpgeneric_list($object_id) {
 
        /* needs PHP >= 5 foreach call by reference */
        /* php 5.1.6 doesn't seem to work */
-       //foreach($sysObjectID['attr'] as $attr_id => &$attr) {
+       //foreach($sysObjectID['attr'] as $attr_id => &$attr)
        foreach($sysObjectID['attr'] as $attr_id => $value) {
 
                $attr = &$sysObjectID['attr'][$attr_id];
 
                if(isset($object['attr'][$attr_id])) {
 
+                       if(array_key_exists('key',$object['attr'][$attr_id]))
+                               $attr['key'] = $object['attr'][$attr_id]['key'];
+
                        switch(TRUE) {
 
                                case isset($attr['pf']):
@@ -1123,12 +1367,12 @@ function snmpgeneric_list($object_id) {
                                                        if(!preg_match($regex, $attrvalue)) {
                                                                if(!isset($attr['uncheck']))
                                                                        $attr['uncheck'] = "regex doesn't match";
-                                                       } else 
+                                                       } else
                                                                unset($attr['uncheck']);
                                                }
                                        }
 
-                                       $attr['value'] = $attrvalue;    
+                                       $attr['value'] = $attrvalue;
 
                                        break;
 
@@ -1159,12 +1403,20 @@ function snmpgeneric_list($object_id) {
        /* DEBUG */
        //sg_var_dump_html($sysObjectID['attr'], "After processing");
 
-       foreach($sysObjectID['attr'] as $attr_id => &$attr) {                   
+       foreach($sysObjectID['attr'] as $attr_id => &$attr) {
+
+               $attr['id'] = $attr_id;
 
                if(isset($object['attr'][$attr_id]) && isset($attr['value'])) {
 
                        if($attr['value'] == $object['attr'][$attr_id]['value'])
-                               $attr['uncheck'] = 'Current = new value';       
+                               $attr['uncheck'] = 'Current = new value';
+
+                       if(isset($attr['key']) && isset($object['attr'][$attr_id]['key']))
+                       {
+                               if($attr['key'] == $object['attr'][$attr_id]['key'])
+                                       $attr['uncheck'] = 'Current = new key';
+                       }
 
                        $value = $attr['value'];
 
@@ -1199,14 +1451,19 @@ function snmpgeneric_list($object_id) {
 
        echo '</table>';
 
+       $object['breed'] = sg_detectDeviceBreedByObject($sysObjectID);
+
+       if(!empty($object['breed']))
+               echo "Found Breed: ".$object['breed']."<br>";
+
        /* ports */
 
        /* get ports */
        amplifyCell($object);
 
-       /* set array key to port name */ 
+       /* set array key to lowercase port name */
        foreach($object['ports'] as $key => $values) {
-               $object['ports'][$values['name']] = $values;
+               $object['ports'][strtolower(shortenIfName($values['name'], $object['breed']))] = $values;
                unset($object['ports'][$key]);
        }
 
@@ -1218,10 +1475,10 @@ function snmpgeneric_list($object_id) {
 
                echo '<br>Vendor / Device specific ports<br>';
                echo '<table><tr><th><input type="checkbox" id="moreport" checked="checked" onclick="setchecked(this.id)"></th><th>ifName</th><th>porttypeid</th></tr>';
-       
+
                foreach($sysObjectID['port'] as $name => $port) {
 
-                       if(array_key_exists($name,$object['ports']))
+                       if(array_key_exists(strtolower($name),$object['ports']))
                                $disableport = TRUE;
                        else
                                $disableport = FALSE;
@@ -1256,13 +1513,13 @@ function snmpgeneric_list($object_id) {
 
                                if($key == 'uncheck' || $key == 'comment')
                                        continue;
-       
+
                                /* TODO iif_name */
                                if($key == 'porttypeid')
                                        $displayvalue = getNiftySelect($newporttypeoptions,
                                                         array('name' => "porttypeid[$name]") + $disabledselect, $value);
                                                                                        /* disabled formfied won't be submitted ! */
-                               else 
+                               else
                                        $displayvalue = $value;
 
                                $formfield = '<input type="hidden" name="'.$key.'['.$name.']" value="'.$value.'">';
@@ -1274,7 +1531,7 @@ function snmpgeneric_list($object_id) {
                }
                unset($name);
                unset($port);
-               
+
                echo '</table>';
        }
 
@@ -1282,6 +1539,9 @@ function snmpgeneric_list($object_id) {
 
        $ifsnmp = new ifSNMP($snmpdev);
 
+       // needed for shortenIfName()
+       $ifsnmp->object_breed = $object['breed'];
+
        /* ip spaces */
 
        $ipspace = NULL;
@@ -1294,24 +1554,41 @@ function snmpgeneric_list($object_id) {
                        $netid = NULL;
                        $linklocal = FALSE;
 
+                       //echo "<br> - DEBUG: ipspace $ipaddr - $netaddr - $addrtype - $maskbits<br>";
+
                        /* check for ip space */
                        switch($addrtype) {
                                case 'ipv4':
                                case 'ipv4z':
-                                       $netid = getIPv4AddressNetworkId($ipaddr);
+                                       if($maskbits == 32)
+                                               $netid = 'host';
+                                       else
+                                               $netid = getIPv4AddressNetworkId(ip_parse($ipaddr));
                                        break;
-                               
+
                                case 'ipv6':
-                                       /* convert to IPv6Address->parse format */
-                                       $ipaddr =  preg_replace('/((..):(..))/','\\2\\3',$ipaddr);
-                                       $ipaddr =  preg_replace('/%.*$/','',$ipaddr);
-
-                                       $ipv6 = new IPv6Address();
-                                       if($ipv6->parse($ipaddr)) {
-                                               $netid = getIPv6AddressNetworkId($ipv6);
-                                               $netaddr = $ipv6->get_first_subnet_address($maskbits)->format();
-                                               $linklocal = ($ipv6->get_first_subnet_address(10)->format() == 'fe80::'); 
+
+                                       if(ip_checkparse($ipaddr) === false)
+                                       {
+                                               /* format ipaddr for ip6_parse */
+                                               $ipaddr =  preg_replace('/((..):(..))/','\\2\\3',$ipaddr);
+                                               $ipaddr =  preg_replace('/%.*$/','',$ipaddr);
                                        }
+
+                                       if(ip_checkparse($ipaddr) === false)
+                                               continue(2); // 2 because of switch
+
+                                       $ip6_bin = ip6_parse($ipaddr);
+                                       $ip6_addr = ip_format($ip6_bin);
+                                       $netid = getIPv6AddressNetworkId($ip6_bin);
+
+                                       $node = constructIPRange($ip6_bin, $maskbits);
+
+                                       $netaddr = $node['ip'];
+                                       $linklocal = substr($ip6_addr,0,5) == "fe80:";
+
+                                       //echo "<br> - DEBUG: ipspace $ipaddr - $addrtype - $maskbits - $netaddr - >$linklocal<<br>";
+
                                        break;
 
                                case 'ipv6z':
@@ -1320,11 +1597,11 @@ function snmpgeneric_list($object_id) {
                                        break;
                                default:
                        }
-                       
+
                        if(empty($netid) && $netaddr != '::1' && $netaddr != '127.0.0.1' && $netaddr != '127.0.0.0' && $netaddr != '0.0.0.0' && !$linklocal) {
 
                                $netaddr .= "/$maskbits";
-                               $ipspace[$netaddr] = $addrtype;
+                               $ipspace[$netaddr] = array('addrtype' => $addrtype, 'checked' => ($maskbits > 0 ? true : false));
                        }
                }
                unset($ipaddr);
@@ -1339,21 +1616,21 @@ function snmpgeneric_list($object_id) {
                echo '<br><br>Create IP Spaces';
                echo '<table><tr><th><input type="checkbox" id="ipspace" onclick="setchecked(this.id)" checked=\"checked\"></th>';
                echo '<th>Type</th><th>prefix</th><th>name</th><th width=150 title="reserve network and router addresses">reserve network / router addresses</th></tr>';
-       
+
                $i = 1;
-               foreach($ipspace as $prefix => $addrtype) {
-               
+               foreach($ipspace as $prefix => $ipspace) {
+
                        $netcreatecheckbox = '<b style="background-color:#00ff00">'
                                .'<input class="ipspace" style="background-color:#00ff00" type="checkbox" name="netcreate['
-                               .$i.']" value="'.$addrtype.'" checked=\"checked\"></b>';
+                               .$i.']" value="'.$ipspace['addrtype'].'"'.($ipspace['checked'] ? ' checked=\"checked\"' : '').'></b>';
 
                        $netprefixfield = '<input type="text" size=50 name="netprefix['.$i.']" value="'.$prefix.'">';
 
                        $netnamefield = '<input type="text" name="netname['.$i.']">';
 
-                       $netreservecheckbox = '<input type="checkbox" name="netreserve['.$i.']">';
+                       $netreservecheckbox = '<input type="checkbox" name="netreserve['.$i.']" checked="checked">';
 
-                       echo "<tr><td>$netcreatecheckbox</td><td style=\"color:#888888\">$addrtype</td><td>$netprefixfield</td><td>$netnamefield</td><td>$netreservecheckbox</td></tr>";
+                       echo "<tr><td>$netcreatecheckbox</td><td style=\"color:#888888\">${ipspace['addrtype']}</td><td>$netprefixfield</td><td>$netnamefield</td><td>$netreservecheckbox</td></tr>";
 
                        $i++;
                }
@@ -1365,19 +1642,21 @@ function snmpgeneric_list($object_id) {
        }
 
 
-       echo "<br><br>ifNumber: ".$ifsnmp->ifNumber."<br><table><tbody valign=\"top\">";
+       echo "<br><br>ifNumber: ".$ifsnmp->ifNumber."<br>indexcount: ".$ifsnmp->indexcount."<br><table><tbody valign=\"top\">";
 
        $portcompat = getPortInterfaceCompat();
 
        $ipnets = array();
 
-       $ifsnmp->printifInfoTableHeader("<th>add ip</th><th>add port</th><th title=\"update mac\">upd mac</th><th>porttypeid</th><th>comment</th></tr>");
+       $ifsnmp->printifInfoTableHeader("<th>add ip</th><th>add port</th><th>upd label</th><th title=\"update mac\">upd mac</th><td>upd port type</th><th>porttypeid</th><th>comment</th></tr>");
 
        echo '<tr><td colspan="11"></td>
-               <td><input type="checkbox" id="ipaddr" onclick="setchecked(this.id)">IPv4<br>
-               <input type="checkbox" id="ipv6addr" onclick="setchecked(this.id)">IPv6</td>
+               <td><input type="checkbox" id="ipaddr" onclick="setchecked(this.id);" checked="checked">IPv4<br>
+               <input type="checkbox" id="ipv6addr" onclick="setchecked(this.id);" checked="checked">IPv6</td>
                <td><input type="checkbox" id="ports" onclick="setchecked(this.id)"></td>
-               <td><input type="checkbox" id="mac" onclick="setchecked(this.id)" checked="checked"></td></tr>';
+               <td><input type="checkbox" id="label" onclick="setchecked(this.id);" checked="checked"></td>
+               <td><input type="checkbox" id="mac" onclick="setchecked(this.id);" checked="checked"></td>
+               <td><input type="checkbox" id="porttype" onclick="setchecked(this.id);"></td></tr>';
 
        foreach($ifsnmp as $if) {
 
@@ -1385,6 +1664,8 @@ function snmpgeneric_list($object_id) {
                $disableport = FALSE;
                $ignoreport = FALSE;
                $port_info = NULL;
+               $updatelabel = false;
+               $updateporttype = false;
 
                $updatemaccheckbox = '';
 
@@ -1400,6 +1681,11 @@ function snmpgeneric_list($object_id) {
                        if(array_key_exists($ifsnmp->ifName($if),$object['ports'])){
                                $port_info = &$object['ports'][$ifsnmp->ifName($if)];
                                $comment .= "Name exists";
+
+                               /* ifalias change */
+                               if($port_info['label'] != $ifsnmp->ifAlias($if))
+                                       $updatelabel = true;
+
                                $createport = FALSE;
                                $disableport = TRUE;
                        }
@@ -1411,9 +1697,8 @@ function snmpgeneric_list($object_id) {
 
                        $l2port =  sg_checkL2Address($ifPhysAddress);
 
-                       //if(alreadyUsedL2Address($ifPhysAddress, $object_id)) {
-
                        if(!empty($l2port)) {
+
                                $l2object_id = key($l2port);
 
                                $porthref = makeHref(array('page'=>'object', 'tab' => 'ports',
@@ -1427,7 +1712,7 @@ function snmpgeneric_list($object_id) {
                        }
 
                        $disablemac = true;
-                       if($disableport) { 
+                       if($disableport) {
                                if($port_info !== NULL) {
                                        if(str_replace(':','',$port_info['l2address']) != $ifPhysAddress)
                                                $disablemac = false;
@@ -1449,7 +1734,7 @@ function snmpgeneric_list($object_id) {
                                        .($disablemac ? '#ff0000' : '#00ff00').'" type="checkbox" name="updatemac['.$if.']" value="'
                                        .$object['ports'][$ifsnmp->ifName($if)]['id'].'" checked="checked"'
                                        .($disablemac ? ' disabled=\"disabled\"' : '' ).'></b>';
-                                       
+
                }
 
 
@@ -1460,18 +1745,29 @@ function snmpgeneric_list($object_id) {
                        $createport = FALSE;
                        $ignoreport = TRUE;
                }
-               
+               else
+               {
+                       if($port_info)
+                       {
+                               $ptid = $port_info['iif_id']."-".$port_info['oif_id'];
+                               if($porttypeid != $ptid)
+                               {
+                                       $comment .= ", Update Type $ptid -> $porttypeid";
+                                       $updateporttype = true;
+                               }
+                       }
+               }
+
                /* ignore ports without an Connector */
                if(!$sg_create_noconnector_ports && ($ifsnmp->ifConnectorPresent($if) == 2)) {
                        $comment .= ", no Connector";
                        $createport = FALSE;
                }
 
-               
                /* Allocate IPs ipv4 and ipv6 */
 
                $ipaddresses = $ifsnmp->ipaddress($if);
-       
+
                if(!empty($ipaddresses)) {
 
                        $ipaddrcell = '<table>';
@@ -1481,56 +1777,67 @@ function snmpgeneric_list($object_id) {
                                $disableipaddr = FALSE;
                                $ipaddrhref = '';
                                $linklocal = FALSE;
-       
+
                                $addrtype = $value['addrtype'];
                                $maskbits = $value['maskbits'];
                                $bcast = $value['bcast'];
 
+                               //echo "<br> - DEBUG: ip $ipaddr - $addrtype - $maskbits - $bcast<br>";
+
                                switch($addrtype) {
                                        case 'ipv4z':
                                        case 'ipv4':
+                                               if($maskbits == 32)
+                                                       $bcast = "host";
+
                                                $inputname = 'ip';
                                                break;
-                       
+
                                        case 'ipv6z':
                                                $disableipaddr = TRUE;
                                        case 'ipv6':
                                                $inputname = 'ipv6';
 
-                                               /* convert to IPv6Address->parse format */
-                                               $ipaddr =  preg_replace('/((..):(..))/','\\2\\3',$ipaddr);
-                                               $ipaddr =  preg_replace('/%.*$/','',$ipaddr);
-       
-                                               $ipv6 = new IPv6Address();
-                                               if(!$ipv6->parse($ipaddr)) {
-                                                       $disableipaddr = TRUE;
-                                                       $comment .= ' ipv6 parse failed';
-                                               } else {
-                                                       $ipaddr = $ipv6->format();
-                                                       $linklocal = ($ipv6->get_first_subnet_address(10)->format() == 'fe80::'); 
+                                               if(ip_checkparse($ipaddr) === false)
+                                               {
+                                                       /* format ipaddr for ip6_parse */
+                                                       $ipaddr =  preg_replace('/((..):(..))/','\\2\\3',$ipaddr);
+                                                       $ipaddr =  preg_replace('/%.*$/','',$ipaddr);
                                                }
 
+                                               if(ip_checkparse($ipaddr) === false)
+                                                       continue(2); // 2 because of switch
+
+                                               /* ip_parse throws exception on parse errors */
+                                               $ip6_bin = ip_parse($ipaddr);
+                                               $ipaddr = ip_format($ip6_bin);
+
+                                               $node = constructIPRange($ip6_bin, $maskbits);
+
+                                               $linklocal = ($node['ip'] == 'fe80::');
+
                                                $createipaddr = FALSE;
                                                break;
 
-                               }
-                                       
-                               $address = getIPAddress($ipaddr);
+                               } //switch
+
+                               $address = getIPAddress(ip_parse($ipaddr));
 
                                /* only if ip not already allocated */
                                if(empty($address['allocs'])) {
-                                       if(!$ignoreport)
+                                       if(!$ignoreport) {
                                                $createipaddr = TRUE;
+                                       }
                                } else {
                                        $disableipaddr = TRUE;
-       
+
                                        $ipobject_id = $address['allocs'][0]['object_id'];
-       
+
                                        $ipaddrhref = makeHref(array('page'=>'object',
                                                                         'object_id' => $ipobject_id, 'hl_ipv4_addr' => $ipaddr));
-       
+
                                }
-                                               
+
                                /* reserved addresses */
                                if($address['reserved'] == 'yes') {
                                        $comment .= ', '.$address['ip'].' reserved '.$address['name'];
@@ -1549,39 +1856,39 @@ function snmpgeneric_list($object_id) {
                                        $disableipaddr = TRUE;
                                }
 
-
-                       if(!$disableipaddr)
-                               $ipaddrcheckbox = '<b style="background-color:'.($disableipaddr ? '#ff0000' : '#00ff00')
-                                       .'"><input class="'.$inputname.'addr" style="background-color:'
-                                       .($disableipaddr ? '#ff0000' : '#00ff00')
-                                       .'" type="checkbox" name="'.$inputname.'addrcreate['.$ipaddr.']" value="'.$if.'"'
-                                       .($disableipaddr ? ' disabled="disabled"' : '')
-                                       .($createipaddr ? ' checked="checked"' : '').'></b>';
-                       else
-                               $ipaddrcheckbox = '';
+                               if(!$disableipaddr) {
+                                       $ipaddrcheckbox = '<b style="background-color:'.($disableipaddr ? '#ff0000' : '#00ff00')
+                                               .'"><input class="'.$inputname.'addr" style="background-color:'
+                                               .($disableipaddr ? '#ff0000' : '#00ff00')
+                                               .'" type="checkbox" name="'.$inputname.'addrcreate['.$ipaddr.']" value="'.$if.'"'
+                                               .($disableipaddr ? ' disabled="disabled"' : '')
+                                               .($createipaddr ? ' checked="checked"' : '').'></b>';
+                               } else {
+                                       $ipaddrcheckbox = '';
+                               }
 
                                $ipaddrcell .= "<tr><td>$ipaddrcheckbox</td>";
 
-                               if(!empty($ipaddrhref))
+                               if(!empty($ipaddrhref)) {
                                        $ipaddrcell .= "<td><a href=$ipaddrhref>$ipaddr/$maskbits</a></td></tr>";
-                               else
+                               } else {
                                        $ipaddrcell .= "<td>$ipaddr/$maskbits</td></tr>";
+                               }
 
-                       }
+                       } // foreach
                        unset($ipaddr);
                        unset($value);
-               
+
                        $ipaddrcell .= '</table>';
-               
+
+               // if(!empty($ipaddresses))
                 } else {
                        $ipaddrcreatecheckbox = '';
                        $ipaddrcell = '';
-
                }
 
-
                /* checkboxes for add port and add ip */
-               /* FireFox needs <b style=..>, IE and Opera work with <td style=..> */  
+               /* FireFox needs <b style=..>, IE and Opera work with <td style=..> */
                if(!$disableport)
                        $portcreatecheckbox = '<b style="background-color:'.($disableport ? '#ff0000' : '#00ff00')
                                        .'"><input class="ports" style="background-color:'.($disableport ? '#ff0000' : '#00ff00')
@@ -1589,7 +1896,7 @@ function snmpgeneric_list($object_id) {
                                        .($disableport ? ' disabled="disbaled"' : '').($createport ? ' checked="checked"' : '').'></b>';
                else
                        $portcreatecheckbox = '';
-               
+
                /* port type id */
                /* add port type to newporttypeoptions if missing */
                if(strpos(serialize($newporttypeoptions),$porttypeid) === FALSE) {
@@ -1597,19 +1904,33 @@ function snmpgeneric_list($object_id) {
                        $portids = explode('-',$porttypeid);
                        $oif_name = $sg_portoifoptions[$portids[1]];
 
-                       $newporttypeoptions['auto'] = array($porttypeid => "*$oif_name");  
+                       $newporttypeoptions['auto'] = array($porttypeid => "*$oif_name");
                }
 
                $selectoptions = array('name' => "porttypeid[$if]");
 
-               if($disableport)
+               if($disableport && !$updateporttype)
                        $selectoptions['disabled'] = "disabled";
 
+               $updateporttypecheckbox = "";
+
+               if($updateporttype)
+                       $updateporttypecheckbox = '<b style="background-color:#00ff00;">'
+                                       .'<input class="porttype" style="background-color:#00ff00;" type="checkbox" name="updateporttype['.$if.']" value="'
+                                       .$port_info['id'].'"></b>';
+
                $porttypeidselect = getNiftySelect($newporttypeoptions, $selectoptions, $porttypeid);
 
+               $updatelabelcheckbox = "";
+
+               if($updatelabel)
+                       $updatelabelcheckbox = '<b style="background-color:#00ff00;">'
+                                       .'<input class="label" style="background-color:#00ff00;" type="checkbox" name="updatelabel['.$if.']" value="'
+                                       .$port_info['id'].($updatelabel ? '" checked="checked"' : '' ).'></b>';
+
                $comment = trim($comment,', ');
 
-               $ifsnmp->printifInfoTableRow($if,"<td>$ipaddrcell</td><td>$portcreatecheckbox</td><td>$updatemaccheckbox</td><td>$porttypeidselect</td><td nowrap=\"nowrap\">$comment</td>", $hrefs);
+               $ifsnmp->printifInfoTableRow($if,"<td>$ipaddrcell</td><td>$portcreatecheckbox</td><td>$updatelabelcheckbox</td><td>$updatemaccheckbox</td><td>$updateporttypecheckbox</td><td>$porttypeidselect</td><td nowrap=\"nowrap\">$comment</td>", $hrefs);
 
        }
        unset($if);
@@ -1623,7 +1944,7 @@ function snmpgeneric_list($object_id) {
 
        echo '<tr><td colspan=15 align="right"><p><input id="createbutton" type=submit value="Create Ports and IPs" onclick="return confirm(\'Create selected items?\')"></p></td></tr></tbody></table></form>';
 
-}
+} // END function  snmpgeneric_list
 
 /* -------------------------------------------------- */
 function snmpgeneric_opcreate() {
@@ -1657,12 +1978,13 @@ function snmpgeneric_opcreate() {
                        $ifAlias = (isset($_POST['ifAlias'][$if]) ? trim($_POST['ifAlias'][$if]) : '' );
                        $ifDescr = (isset($_POST['ifDescr'][$if]) ? trim($_POST['ifDescr'][$if]) : '' );
 
-                       $visible_label = (empty($ifAlias) ? '' : $ifAlias.'; ').$ifDescr;
+                       //$visible_label = (empty($ifAlias) ? '' : $ifAlias.'; ').$ifDescr;
+                       $visible_label = $ifAlias;
 
                        if(empty($ifName)) {
                                showError('Port without ifName '.$_POST['porttypeid'][$if].', '.$visible_label.', '.$ifPhysAddress);
                        } else {
-                               commitAddPort ($object_id, $ifName, $_POST['porttypeid'][$if], $visible_label, $ifPhysAddress);
+                               commitAddPort ($object_id, $ifName, $_POST['porttypeid'][$if], $visible_label, $ifPhysAddress);
                                showSuccess('Port created '.$ifName.', '.$_POST['porttypeid'][$if].', '.$visible_label.', '.$ifPhysAddress);
                        }
                }
@@ -1693,31 +2015,42 @@ function snmpgeneric_opcreate() {
 
        /* allocate ipv6 adresses */
        if(isset($_POST['ipv6addrcreate'])) {
-               foreach($_POST['ipv6addrcreate'] as $ipaddr => $if) {   
-                       
-                       $ip = new IPv6Address();
-                       if($ip->parse($ipaddr)) { 
-                       
-                               bindIPv6ToObject($ip, $object_id,$_POST['ifName'][$if], 1); /* connected */
-                               showSuccess("$ipaddr allocated"); 
-                       } else
-                               showError("$ipaddr parse failed!"); 
+               foreach($_POST['ipv6addrcreate'] as $ipaddr => $if) {
+
+                       bindIPv6ToObject(ip6_parse($ipaddr), $object_id,$_POST['ifName'][$if], 1); /* connected */
+                       showSuccess("$ipaddr allocated");
                }
                unset($ipaddr);
                unset($if);
        }
        /* allocate ip adresses */
        if(isset($_POST['ipaddrcreate'])) {
-               foreach($_POST['ipaddrcreate'] as $ipaddr => $if) {     
+               foreach($_POST['ipaddrcreate'] as $ipaddr => $if) {
 
-                       bindIpToObject($ipaddr, $object_id,$_POST['ifName'][$if], 1); /* connected */
-                       showSuccess("$ipaddr allocated"); 
+                       bindIPToObject(ip_parse($ipaddr), $object_id,$_POST['ifName'][$if], 1); /* connected */
+                       showSuccess("$ipaddr allocated");
                }
                unset($ipaddr);
                unset($if);
        }
        /* ipaddrecreate */
 
+       /* update label */
+       if(isset($_POST['updatelabel'])) {
+               foreach($_POST['updatelabel'] as $if => $port_id) {
+
+                       $ifAlias = (isset($_POST['ifAlias'][$if]) ? trim($_POST['ifAlias'][$if]) : '' );
+
+                       sg_commitUpdatePortLabel($object_id, $port_id, $ifAlias);
+
+                       $ifName = (isset($_POST['ifName'][$if]) ? trim($_POST['ifName'][$if]) : '' );
+                       showSuccess("label updated on $ifName to $ifAlias");
+               }
+               unset($if);
+               unset($port_id);
+       }
+       /* updatemac */
+
        /* update mac addresses only */
        if(isset($_POST['updatemac'])) {
                foreach($_POST['updatemac'] as $if => $port_id) {
@@ -1734,6 +2067,21 @@ function snmpgeneric_opcreate() {
        }
        /* updatemac */
 
+       /* update port type */
+       if(isset($_POST['updateporttype'])) {
+               foreach($_POST['updateporttype'] as $if => $port_id) {
+
+                       $porttypeid = (isset($_POST['porttypeid'][$if]) ? trim($_POST['porttypeid'][$if]) : '' );
+
+                       sg_commitUpdatePortType($object_id, $port_id, $porttypeid);
+
+                       $ifName = (isset($_POST['ifName'][$if]) ? trim($_POST['ifName'][$if]) : '' );
+                       showSuccess("port type updated on $ifName");
+               }
+               unset($if);
+               unset($port_id);
+       }
+       /* updateporttype */
 } /* snmpgeneric_opcreate */
 
 /* -------------------------------------------------- */
@@ -1755,12 +2103,28 @@ function guessRToif_id($ifType,$ifDescr = NULL) {
                $retval = "1-$retval";
 
        /* no ethernetCsmacd */
-       if($ifType != 6) 
+       if($ifType != 6)
                return $retval;
 
 
        /* try to identify outer and inner interface type from ifDescr */
 
+       switch(true)
+       {
+               case preg_match('/fast.?ethernet/i',$ifDescr,$matches):
+                       // Fast Ethernet
+                       $retval = 19;
+                       break;
+               case preg_match('/10.?gigabit.?ethernet/i',$ifDescr,$matches):
+                       // 10-Gigabit Ethernet
+                       $retval = 1642;
+                       break;
+               case preg_match('/gigabit.?ethernet/i',$ifDescr,$matches):
+                       // Gigabit Ethernet
+                       $retval = 24;
+                       break;
+       }
+
        /**********************
         * ifDescr samples
         *
@@ -1777,11 +2141,11 @@ function guessRToif_id($ifType,$ifDescr = NULL) {
         * Enterasys Networks, Inc. 10GBASE SFP+ 10-Gigabit Ethernet Port; No SFP+ Inserted
         * Enterasys Networks, Inc. 10GBASE-SR SFP+ 10-Gigabit Ethernet Port (850nm Short Wavelength, 33/82m MMF, LC)
         * Enterasys Networks, Inc. 1000BASE Gigabit Ethernet Port; Unknown GBIC/MGBIC Inserted
-        *
+        *
         */
 
        foreach($sg_portiifoptions as $iif_id => $iif_type) {
-               
+
                /* TODO better matching */
 
 
@@ -1811,12 +2175,18 @@ function guessRToif_id($ifType,$ifDescr = NULL) {
                                                        break;
                                                default:
                                                case '1000' :
-                                                       $iif_id = 4;    
+                                                       $iif_id = 4;
                                                        $iif_type = "SFP-1000";
                                                        break;
                                        }
                                }
-                               
+
+                               if(preg_match('/sfp 1000-sx/i',$ifDescr))
+                                       $oif_type = '1000BASE-SX';
+
+                               if(preg_match('/sfp 1000-lx/i',$ifDescr))
+                                       $oif_type = '1000BASE-LX';
+
                        }
 
                        if($no) {
@@ -1879,6 +2249,52 @@ function sg_commitUpdatePortl2address($object_id, $port_id, $port_l2address)
         $dbxlink->exec ('UNLOCK TABLES');
 } /* sg_commitUpdatePortl2address */
 
+/* --------------------------------------------------- */
+
+function sg_commitUpdatePortType($object_id, $port_id, $porttypeid)
+{
+       global $dbxlink;
+
+       list($iif_id, $type) = explode("-",$porttypeid);
+
+        $dbxlink->exec ('LOCK TABLES Port WRITE');
+        usePreparedUpdateBlade
+        (
+                'Port',
+                array
+                (
+                        'iif_id' => ($iif_id === '') ? NULL : $iif_id,
+                       'type' => ($type === '') ? NULL : $type
+                ),
+                array
+                (
+                        'id' => $port_id,
+                        'object_id' => $object_id
+                )
+        );
+        $dbxlink->exec ('UNLOCK TABLES');
+} /* sg_commitUpdatePortType */
+
+function sg_commitUpdatePortLabel($object_id, $port_id, $label)
+{
+       global $dbxlink;
+
+        $dbxlink->exec ('LOCK TABLES Port WRITE');
+        usePreparedUpdateBlade
+        (
+                'Port',
+                array
+                (
+                        'label' => ($label === '') ? NULL : $label
+                ),
+                array
+                (
+                        'id' => $port_id,
+                        'object_id' => $object_id
+                )
+        );
+        $dbxlink->exec ('UNLOCK TABLES');
+} /* sg_commitUpdatePortLabel */
 /* ----------------------------------------------------- */
 
 /* returns object_id and port_id to a given l2address */
@@ -1893,16 +2309,41 @@ function sg_checkL2Address ($address)
         return $row;
 }
 
-/* returns oi_id and name */
-function getPortOIOptions()
+function sg_checkObjectNameUniqueness ($name, $type_id, $object_id = 0)
 {
-        $result = usePreparedSelectBlade
-        (
-               'SELECT dict_key,dict_value from Dictionary where chapter_id = 2',
-                array ()
-        );
-        $row = $result->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_COLUMN);
-        return $row;
+       // Some object types do not need unique names
+       // 1560 - Rack
+       // 1561 - Row
+       $dupes_allowed = array (1560, 1561);
+       if (in_array ($type_id, $dupes_allowed))
+       return;
+
+       $result = usePreparedSelectBlade
+       (
+               'SELECT COUNT(*) FROM Object WHERE name = ? AND id != ?',
+               array ($name, $object_id)
+       );
+       $row = $result->fetch (PDO::FETCH_NUM);
+       if ($row[0] != 0)
+               return false;
+       else
+               return true;
+}
+
+function sg_detectDeviceBreedByObject($object)
+{
+       global $breed_by_swcode, $breed_by_hwcode, $breed_by_mgmtcode;
+
+       foreach ($object['attr'] as $record)
+       {
+               if ($record['id'] == 4 and array_key_exists ($record['key'], $breed_by_swcode))
+                       return $breed_by_swcode[$record['key']];
+               elseif ($record['id'] == 2 and array_key_exists ($record['key'], $breed_by_hwcode))
+                       return $breed_by_hwcode[$record['key']];
+               elseif ($record['id'] == 30 and array_key_exists ($record['key'], $breed_by_mgmtcode))
+                       return $breed_by_mgmtcode[$record['key']];
+       }
+       return '';
 }
 
 /* ------------------------------------------------------- */
@@ -1923,17 +2364,21 @@ class SNMPgeneric {
 //     protected $contextName;
 //     protected $contextEngineID;
 
-       const VERSION_1 = 1;
-       const VERSION_2C = 2;
+       const VERSION_1 = 0;
+       const VERSION_2C = 1;
+       const VERSION_2c = 1;
        const VERSION_3 = 3;
 
        protected $result;
 
        function __construct($version, $host, $community) {
-               
+
                $this->host = $host;
+
                $this->version = $version;
-               $this->community = $community;  
+               $this->community = $community;
+
+               set_error_handler(array($this,'ErrorHandler'), E_WARNING);
        }
 
        function setSecurity($sec_level, $auth_protocol = 'md5', $auth_passphrase = '', $priv_protocol = 'des', $priv_passphrase = '') {
@@ -1942,6 +2387,36 @@ class SNMPgeneric {
                $this->auth_passphrase = $auth_passphrase;
                $this->priv_protocol = $priv_protocol;
                $this->priv_passphrase = $priv_passphrase;
+
+               return true;
+       }
+
+       function __set($name, $value)
+       {
+               switch($name)
+               {
+                       case 'quick_print':
+                               snmp_set_quick_print($value);
+                               break;
+                       case 'oid_output_format':
+                               /* needs php >= 5.2.0 */
+                               snmp_set_oid_output_format($value);
+                               break;
+                       case 'enum_print':
+                               snmp_set_enum_print($value);
+                               break;
+                       case 'valueretrieval':
+                               snmp_set_valueretrieval($value);
+                               break;
+                       default:
+                               $trace = debug_backtrace();
+                               trigger_error(
+                                       'Undefined property via __set(): ' . $name .
+                                       ' in ' . $trace[0]['file'] .
+                                       ' on line ' . $trace[0]['line'],
+                                       E_USER_NOTICE);
+                               return null;
+               }
        }
 
        function walk( $oid, $suffix_as_key = FALSE) {
@@ -1956,6 +2431,7 @@ class SNMPgeneric {
                                break;
 
                        case self::VERSION_2C:
+                       case self::VERSION_2c:
                                if($suffix_as_key){
                                        $this->result = snmp2_walk($this->host,$this->community,$oid);
                                } else {
@@ -1979,13 +2455,14 @@ class SNMPgeneric {
        private function __snmpget($object_id) {
 
                $retval = FALSE;
-               
+
                switch($this->version) {
                        case self::VERSION_1:
                                $retval = snmpget($this->host,$this->community,$object_id);
                                break;
 
                        case self::VERSION_2C:
+                       case self::VERSION_2c:
                                $retval = snmp2_get($this->host,$this->community,$object_id);
                                break;
 
@@ -2018,7 +2495,7 @@ class SNMPgeneric {
                }
 
                return $this->result;
-               
+
        }
 
        function close() {
@@ -2032,15 +2509,27 @@ class SNMPgeneric {
                $var = error_get_last();
                return $var['message'];
        }
+
+       function Errorhandler($errno, $errstr, $errfile, $errline) {
+               switch(TRUE) {
+                       case (False !== strpos($errstr,'No Such Object available on this agent at this OID')):
+                                       /* no further error processing */
+                                       return true;
+                               break;
+               }
+
+               /* proceed with default error handling */
+               return false;
+       }
 } /* SNMPgeneric */
 
 /* ------------------------------------------------------- */
 /*
- * SNMP with system OIDs 
+ * SNMP with system OIDs
  */
 class mySNMP extends SNMPgeneric implements Iterator {
 
-       const SNMP_VERSION = SNMPgeneric::VERSION_2C;
+       const SNMP_VERSION = parent::VERSION_2C;
        const SNMP_COMMUNITY = 'public';
 
        public $lastgetoid;
@@ -2052,21 +2541,34 @@ class mySNMP extends SNMPgeneric implements Iterator {
        private $systemerror = TRUE;
 
        function __construct($version, $host, $community) {
-               parent::__construct($version, $host, $community);
 
-               //snmp_set_valueretrieval(SNMP_VALUE_LIBRARY);
+               switch($version)
+               {
+                       case '1':
+                       case 'v1':
+                               $version = parent::VERSION_1;
+                               break;
+                       case '2':
+                       case 'v2C':
+                       case 'v2c':
+                               $version = parent::VERSION_2c;
+                               break;
+                       case '3':
+                       case 'v3':
+                               $version = parent::VERSION_3;
+                               break;
+               };
+
+               parent::__construct($version, $host, $community);
 
                /* Return values without SNMP type hint */
-               snmp_set_valueretrieval(SNMP_VALUE_PLAIN);
-
-               /* needs php >= 5.2.0 */
-       //      snmp_set_oid_output_format(SNMP_OID_OUTPUT_FULL);
-               
-       //      snmp_set_quick_print(1);
+               $this->valueretrieval = SNMP_VALUE_PLAIN;
 
        } /* __construct */
 
        function init() {
+
+               $this->oid_output_format = SNMP_OID_OUTPUT_FULL;
                /* .iso.org.dod.internet.mgmt.mib-2.system */
                $this->system = $this->walk(".1.3.6.1.2.1.1");
 
@@ -2154,17 +2656,17 @@ class mySNMP extends SNMPgeneric implements Iterator {
                if($this->systemerror) {
                        return;
                }
-               
+
                $retval = $this->_getvalue($name);
 
                if($retval === NULL) {
 
                        $trace = debug_backtrace();
-                       trigger_error(
-                               'Undefinierte Eigenschaft für __call(): ' . $name .
-                               ' in ' . $trace[0]['file'] .
-                               ' Zeile ' . $trace[0]['line'],
-                               E_USER_NOTICE);
+                       trigger_error(
+                                       'Undefinierte Eigenschaft fuer __call(): ' . $name .
+                                       ' in ' . $trace[0]['file'] .
+                                       ' Zeile ' . $trace[0]['line'],
+                                       E_USER_NOTICE);
                }
 
                return $retval;
@@ -2212,47 +2714,34 @@ class mySNMP extends SNMPgeneric implements Iterator {
 class ifSNMP implements Iterator {
        private $snmpdevice;
        private $ifNumber = 0;
+       private $indexcount = 0;
        private $ifTable;
 
        private $interfaceserror = TRUE;
 
-       function __construct(&$snmpdevice) {
-               $this->snmpdevice = $snmpdevice;        
+       public $object_breed = NULL;
 
-               $this->interfaceserror = $this->snmpdevice->getErrno();
+       function __construct(&$snmpdevice) {
+               $this->snmpdevice = $snmpdevice;
 
-               if($this->interfaceserror) {
-                       return;
-               }
-               
                $this->ifNumber = intval($this->snmpdevice->get('ifNumber.0'));
-               
+
                $this->interfaceserror = $this->snmpdevice->getErrno();
 
                if(!$this->interfaceserror) {
-                       
                        $this->getifTable();
                }
-               
-       }
-function mask2maskbits($mask){
-   $long = ip2long($mask);
-   $base = ip2long('255.255.255.255');
-   return 32-log(($long ^ $base)+1,2);
-
-   /* xor-ing will give you the inverse mask,
-       log base 2 of that +1 will return the number
-       of bits that are off in the mask and subtracting
-       from 32 gets you the maskbits notation */
-         
-}
+       }
 
        function getifTable() {
                $this->ifTable['ifIndex'] = $this->snmpdevice->walk('ifIndex',TRUE);
+
+               $this->indexcount = count($this->ifTable['ifIndex']);
+
                $this->ifTable['ifDescr'] = $this->snmpdevice->walk('ifDescr',TRUE);
                $this->ifTable['ifAlias'] = $this->snmpdevice->walk('ifAlias',TRUE);
                $this->ifTable['ifName'] =  $this->snmpdevice->walk('ifName',TRUE);
-               
+
                $this->ifTable['ifType'] =  $this->snmpdevice->walk('ifType',TRUE);
 
                $this->ifTable['ifSpeed'] =  $this->snmpdevice->walk('ifSpeed',TRUE);
@@ -2284,19 +2773,21 @@ function mask2maskbits($mask){
                                next($ipAdEntNetMask);
 
                                $ipaddr = preg_replace('/.*\.([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$/','$1',$oid);
-       
+
                                $ifindex =  array_search($value,$this->ifTable['ifIndex']);
 
-                               $maskbits = 32-log((ip2long($netmask) ^ 0xffffffff)+1,2);
-                               $net = ip2long($ipaddr) & ip2long($netmask);
-                               $bcast = $net | ( ip2long($netmask) ^ 0xffffffff);
+                               if($netmask != '0.0.0.0') {
+                                       $maskbits = 32-log((ip2long($netmask) ^ 0xffffffff)+1,2);
+                                       $net = ip2long($ipaddr) & ip2long($netmask);
+                                       $bcast = $net | ( ip2long($netmask) ^ 0xffffffff);
 
-                               $this->ifTable['ipaddress'][$ifindex][$ipaddr] = array(
+                                       $this->ifTable['ipaddress'][$ifindex][$ipaddr] = array(
                                                                                'addrtype' => 'ipv4',
-                                                                               'maskbits' => (int)$maskbits,
+                                                                               'maskbits' => $maskbits,
                                                                                'net' => long2ip($net),
-                                                                               'bcast' => long2ip($bcast) 
+                                                                               'bcast' => long2ip($bcast)
                                                                                );
+                               }
 
                        }
                        unset($oid);
@@ -2321,7 +2812,7 @@ function mask2maskbits($mask){
 
                                $prefix = current($ipAddressPrefix);
                                next($ipAddressPrefix);
-                       
+
                                $type = current($ipAddressType);
                                next($ipAddressType);
 
@@ -2352,8 +2843,8 @@ function mask2maskbits($mask){
 
                                $this->ifTable['ipaddress'][$ifindex][$matches[2]] = array(
                                                                                'addrtype' => $matches[1],
-                                                                               'maskbits' => $maskbits,
-                                                                               'net' => $net,
+                                                                               'maskbits' => $maskbits,
+                                                                               'net' => $net,
                                                                                'bcast' => $bcast
                                                                                );
                        }
@@ -2364,6 +2855,59 @@ function mask2maskbits($mask){
        //              sg_var_dump_html($ipAddressPrefix);
                } /* ipaddressifindex */
 
+               /* ipv6 MIB  */
+               /* overwrites ipv6 from ipaddresstable */
+               $ipv6interfaces = $this->snmpdevice->get('ipv6Interfaces.0');
+
+               if($ipv6interfaces)
+               {
+                       echo"Found $ipv6interfaces ipv6 interfaces<br>";
+
+                       $ipv6addraddress =  $this->snmpdevice->walk('ipv6AddrAddress');
+
+                       if(!empty($ipv6addraddress)) {
+                               $ipv6addrpfxlength =  $this->snmpdevice->walk('ipv6AddrPfxLength');
+                       //      $ipv6addrtype =  $this->snmpdevice->walk('ipv6AddrType'); /* 1 stateless, 2 stateful, 3 unknown */
+
+                               reset($ipv6addrpfxlength);
+                               //reset($ipv6addrtype);
+
+                               foreach($ipv6addraddress as $oid => $addr_bin) {
+
+                                       $addr = ip_format($addr_bin);
+
+                                       //$type = current($ipv6addrtype);
+                                       //next($ipv6addrtype);
+
+                                       if(!preg_match('/.*(ipv6).*\.([0-9]+)\..*$/',$oid, $matches))
+                                               continue;
+
+                                       $ifindex =  array_search($matches[2],$this->ifTable['ifIndex']);
+
+                                       if($ifindex === false)
+                                               continue;
+
+                                       $maskbits = current($ipv6addrpfxlength);
+                                       next($ipv6addrpfxlength);
+
+                                       $range = constructIPRange($addr_bin, $maskbits);
+
+                                       $net = ip_format($range['ip_bin']);
+                                       $bcast = NULL;
+
+                                       $this->ifTable['ipaddress'][$ifindex][$addr] = array(
+                                                                               'addrtype' => $matches[1],
+                                                                               'maskbits' => $maskbits,
+                                                                               'net' => $net,
+                                                                               'bcast' => $bcast,
+                                                                       //      'type' => ($type == 1 ? "stateless" : $type == 2 ? "statefull" : "unknown" )
+                                                                               );
+                               }
+                               unset($oid);
+                               unset($value);
+
+                       } /* ipv6addraddress */
+               } /* ipv6interfaces */
        }
 
        function printifInfoTableHeader($suffix = "") {
@@ -2373,7 +2917,7 @@ function mask2maskbits($mask){
 
                echo "<tr>";
                foreach ($this->ifTable as $key => $value) {
-                       
+
                        switch($key) {
                                case 'ifOperStatus':
                                        $displayvalue = 'if Oper Status';
@@ -2421,8 +2965,8 @@ function mask2maskbits($mask){
                                $fieldvalue = $this->{$key}($ifIndex);
 
                                if(!empty($fieldvalue)) {
-                                       if($key == 'ifDescr' || $key == 'ifAlias') {    
-                                               $formfield = '<input readonly="readonly" type="text" size="15" name="'.$key.'['.$ifIndex.']" value="'
+                                       if($key == 'ifDescr' || $key == 'ifAlias') {
+                                               $formfield = '<input readonly="readonly" type="text" size="15" name="'.$key.'['.$ifIndex.']" value="'
                                                                .$this->$key($ifIndex).'">';
                                                $textfield = TRUE;
                                        } else {
@@ -2432,15 +2976,15 @@ function mask2maskbits($mask){
                                } else {
                                        if($key == 'ifName') {
                                                /* create textfield set to ifDescr */
-                                               $formfield = '<input type="text" size="8" name="'.$key.'['.$ifIndex.']" value="'
-                                                               .$this->ifDescr($ifIndex).'">';
+                                               $formfield = '<input type="text" size="8" name="'.$key.'['.$ifIndex.']" value="'
+                                                               .strtolower(shortenIfName($this->ifDescr($ifIndex), $this->object_breed)).'">';
                                                $textfield = TRUE;
                                        }
 
                                }
 
                        }
-               
+
 
                        if($textfield)
                                $displayvalue=$formfield;
@@ -2451,7 +2995,7 @@ function mask2maskbits($mask){
                                        $displayvalue = "<a href=".$hrefs[$key].">$displayvalue</a>";
                                }
                        }
-                       
+
                        echo "<td nowrap=\"nowrap\">$displayvalue</td>";
                }
                unset($key);
@@ -2491,50 +3035,59 @@ function mask2maskbits($mask){
                }
 
        }
-               
+
+       function ifName($index) {
+               if(isset($this->ifTable['ifName'][$index-1])) {
+                       return strtolower(shortenIfName($this->ifTable['ifName'][$index-1], $this->object_breed));
+               }
+
+       }
        function &__get($name) {
 
                switch($name) {
-                       case 'ifNumber': 
+                       case 'ifNumber':
+                       case 'indexcount':
                                return $this->{$name};
                                break;
                        case 'ipaddress':
                                return $this->ifTable['ipaddress'];
                                break;
                }
-       
+
                $trace = debug_backtrace();
-               trigger_error(
-                       'Undefinierte Eigenschaft für __get(): ' . $name .
-                       ' in ' . $trace[0]['file'] .
-                       ' Zeile ' . $trace[0]['line'],
-                       E_USER_NOTICE);
 
-                       return NULL;
+               trigger_error(
+                       'Undefinierte Eigenschaft fuer __get(): ' . $name .
+                       ' in ' . $trace[0]['file'] .
+                       ' Zeile ' . $trace[0]['line'],
+                       E_USER_NOTICE);
+
+               return NULL;
        }
 
        /* $obj->ifDescr(3) = $ifTable[$name][$arg]*/
        function __call($name,$args) {
-               
+
                if($this->interfaceserror)
                        return;
-       
+
                if(isset($this->ifTable[$name])) {
                        if(isset($this->ifTable[$name][$args[0]-1])) {
                                return $this->ifTable[$name][$args[0]-1];
                        }
                } else {
-       
+
                        /* for debug */
                        $trace = debug_backtrace();
-                       trigger_error(
-                               'Undefinierte Methode für __call(): ' . $name .
-                               ' in ' . $trace[0]['file'] .
-                               ' Zeile ' . $trace[0]['line'],
-                               E_USER_NOTICE);
+
+                       trigger_error(
+                               'Undefinierte Methode für __call(): ' . $name .
+                               ' in ' . $trace[0]['file'] .
+                               ' Zeile ' . $trace[0]['line'],
+                               E_USER_NOTICE);
                }
 
-               return NULL;
+       return NULL;
 
        } /* __call */
 
@@ -2554,7 +3107,7 @@ function mask2maskbits($mask){
        }
 
        function valid() {
-               return ($this->IteratorIndex<=$this->ifNumber);
+               return ($this->IteratorIndex<=$this->indexcount);
        }
 
        function rewind() {
@@ -2568,9 +3121,8 @@ function mask2maskbits($mask){
 /* ------------------------------------------------------- */
 /* for debugging */
 function sg_var_dump_html(&$var, $text = '') {
-       
+
        echo "<pre>------------------Start Var Dump - $text -----------------------\n";
        var_dump($var);
        echo "\n---------------------END Var Dump - $text -----------------------</pre>";
 }
-?>