new breeds for HP Procurve and ios15; unit tests for HP Procurve breed 225/head
authorVasilii Shashkov <igloo777@gmail.com>
Mon, 13 Aug 2018 12:34:11 +0000 (19:34 +0700)
committerDenis Ovsienko <denis@ovsienko.info>
Wed, 17 Oct 2018 22:41:35 +0000 (23:41 +0100)
tests/BreedHPprocurveN1178PureProvider.php [new file with mode: 0644]
tests/PureFunctionTest.php
wwwroot/inc/breed-hpprocurveN1178.php [new file with mode: 0644]
wwwroot/inc/breed-ios15.php [new file with mode: 0644]
wwwroot/inc/deviceconfig.php
wwwroot/inc/dictionary.php
wwwroot/inc/functions.php
wwwroot/inc/remote.php

diff --git a/tests/BreedHPprocurveN1178PureProvider.php b/tests/BreedHPprocurveN1178PureProvider.php
new file mode 100644 (file)
index 0000000..d0e081a
--- /dev/null
@@ -0,0 +1,682 @@
+<?php
+
+require_once '../wwwroot/inc/deviceconfig.php';
+
+// Data samples for unary equals test method
+function breedHPprocurveN1178UnaryEquals ()
+{
+       return array (
+       // - parse interface brief
+       array (
+               "hpprocurveN1178Read8021QConfig",
+               " Status and Counters - VLAN Information - for ports 1
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 2
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 3
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Tagged 
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 4
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 5
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  201     VLAN201              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 6
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  202     VLAN202              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 7
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 8
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Tagged 
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 9
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 10
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 11
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 12
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 13
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 14
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 15
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 16
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 17
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 18
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 19
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 20
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  202     VLAN202              Port-based   No    Untagged
+ Status and Counters - VLAN Information - for ports 21
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Untagged
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 22
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  201     VLAN201              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 23
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Tagged 
+  201     VLAN201              Port-based   No    Tagged 
+  202     VLAN202              Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 24
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Tagged 
+
+ Status and Counters - VLAN Information - for ports 47
+
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Tagged 
+  201     VLAN201              Port-based   No    Tagged 
+  202     VLAN202              Port-based   No    Tagged 
+  777     MGMT                 Port-based   No    Tagged 
+ Status and Counters - VLAN Information - for ports 48
+
+  Port name: trunk
+  VLAN ID Name                 Status       Jumbo Mode   
+  ------- -------------------- ------------ ----- --------
+  200     VLAN200              Port-based   No    Tagged 
+  201     VLAN201              Port-based   No    Tagged 
+  202     VLAN202              Port-based   No    Tagged 
+  777     MGMT                 Port-based   No    Tagged",
+               array(
+                       'vlanlist' => array (0 => 1, 1 => 200, 2 => 201, 3 => 202, 4 => 777, ),
+                       'portdata' => array (
+                               1 =>  array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               2 =>  array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201,),              'native' => 200,),
+                               3 =>  array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201,),              'native' => 0,),
+                               4 =>  array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               5 =>  array ('mode' => 'access', 'allowed' => array (0 => 201,),                        'native' => 201,),
+                               6 =>  array ('mode' => 'access', 'allowed' => array (0 => 202,),                        'native' => 202,),
+                               7 =>  array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201,),              'native' => 200,),
+                               8 =>  array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201,),              'native' => 0,),
+                               9 =>  array ('mode' => 'trunk',  'allowed' => array (0 => 201,),                        'native' => 0,),
+                               10 => array ('mode' => 'trunk',  'allowed' => array (0 => 200,1 => 201,),               'native' => 200,),
+                               11 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               12 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               13 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               14 => array ('mode' => 'access', 'allowed' => array (0=> 200,),                         'native' => 200,),
+                               15 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               16 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               17 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               18 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               19 => array ('mode' => 'access', 'allowed' => array (0 => 200,),                        'native' => 200,),
+                               20 => array ('mode' => 'access', 'allowed' => array (0 => 202,),                        'native' => 202,),
+                               21 => array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201,),              'native' => 200,),
+                               22 => array ('mode' => 'trunk',  'allowed' => array (0 => 201,),                        'native' => 0,),
+                               23 => array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201, 2 => 202,),    'native' => 0,),
+                               24 => array ('mode' => 'trunk',  'allowed' => array (0 => 200,),                        'native' => 0,),
+                               47 => array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201, 2 => 202, 3 => 777,), 'native' => 0,),
+                               48 => array ('mode' => 'trunk',  'allowed' => array (0 => 200, 1 => 201, 2 => 202, 3 => 777,), 'native' => 0,),
+                       ),
+                       'portconfig' => array (
+                               1 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 1',),),
+                               2 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 2',),),
+                               3 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 3',),),
+                               4 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 4',),),
+                               5 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 5',),),
+                               6 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 6',),),
+                               7 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 7',),),
+                               8 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 8',),),
+                               9 =>  array (0 => array ('type' => 'line-header', 'line' => 'interface 9',),),
+                               10 => array (0 => array ('type' => 'line-header', 'line' => 'interface 10',),),
+                               11 => array (0 => array ('type' => 'line-header', 'line' => 'interface 11',),),
+                               12 => array (0 => array ('type' => 'line-header', 'line' => 'interface 12',),),
+                               13 => array (0 => array ('type' => 'line-header', 'line' => 'interface 13',),),
+                               14 => array (0 => array ('type' => 'line-header', 'line' => 'interface 14',),),
+                               15 => array (0 => array ('type' => 'line-header', 'line' => 'interface 15',),),
+                               16 => array (0 => array ('type' => 'line-header', 'line' => 'interface 16',),),
+                               17 => array (0 => array ('type' => 'line-header', 'line' => 'interface 17',),),
+                               18 => array (0 => array ('type' => 'line-header', 'line' => 'interface 18',),),
+                               19 => array (0 => array ('type' => 'line-header', 'line' => 'interface 19',),),
+                               20 => array (0 => array ('type' => 'line-header', 'line' => 'interface 20',),),
+                               21 => array (0 => array ('type' => 'line-header', 'line' => 'interface 21',),),
+                               22 => array (0 => array ('type' => 'line-header', 'line' => 'interface 22',),),
+                               23 => array (0 => array ('type' => 'line-header', 'line' => 'interface 23',),),
+                               24 => array (0 => array ('type' => 'line-header', 'line' => 'interface 24',),),
+                               47 => array (0 => array ('type' => 'line-header', 'line' => 'interface 47',),),
+                               48 => array (0 => array ('type' => 'line-header', 'line' => 'interface 48',),1 => array ('type' => 'line-other', 'line' => 'name trunk',),),
+                       ),
+                       'vlannames' => array (),
+               ),
+       ),
+
+       // - parse LLDP data
+       array(
+               "hpprocurveN1178ReadLLDPStatus",
+               " LLDP Remote Device Information Detail
+
+  Local Port   : 7
+  ChassisType  : mac-address        
+  ChassisId    : 28 f1 0e 1a 03 7a       
+  PortType     : mac-address
+  PortId       : 28 f1 0e 1a 03 7a       
+  SysName      :                              
+  System Descr :                                                            
+  PortDescr    :                                                            
+
+  System Capabilities Supported  :
+  System Capabilities Enabled    :
+
+  Remote Management Address
+
+------------------------------------------------------------------------------
+  Local Port   : 7
+  ChassisType  : network-address    
+  ChassisId    : 0.0.0.0                 
+  PortType     : mac-address
+  PortId       : 00 0b 82 a9 56 6d       
+  SysName      : GXP1615_00:0b:82:a9:56:6d    
+  System Descr : GXP1615 1.0.4.67                                           
+  PortDescr    : eth0                                                       
+
+  System Capabilities Supported  : bridge, telephone
+  System Capabilities Enabled    : bridge, telephone
+
+  Remote Management Address
+
+------------------------------------------------------------------------------
+  Local Port   : 9
+  ChassisType  : mac-address        
+  ChassisId    : f8 ca b8 36 d8 4f       
+  PortType     : mac-address
+  PortId       : f8 ca b8 36 d8 4f       
+  SysName      : IT-PC                        
+  System Descr : Ubuntu 18.04 LTS Linux 4.15.0-20-generic #21-Ubuntu SMP T...
+  PortDescr    : enp2s0                                                     
+
+  System Capabilities Supported  : bridge, wlan-access-point, router
+  System Capabilities Enabled    : wlan-access-point
+
+  Remote Management Address
+     Type    : ipv4
+     Address : 10.0.12.155
+     Type    : ipv6
+     Address : fe 80 00 00 00 00 00 00 f6 86 71 4f d8 f1 6b 5a
+
+------------------------------------------------------------------------------
+  Local Port   : 11
+  ChassisType  : mac-address        
+  ChassisId    : c8 5b 76 53 1a 6e       
+  PortType     : mac-address
+  PortId       : c8 5b 76 53 1a 6e       
+  SysName      :                              
+  System Descr :                                                            
+  PortDescr    :                                                            
+
+  System Capabilities Supported  :
+  System Capabilities Enabled    :
+
+  Remote Management Address
+
+------------------------------------------------------------------------------
+  Local Port   : 48
+  ChassisType  : mac-address        
+  ChassisId    : 58 97 1e 74 64 00       
+  PortType     : interface-name
+  PortId       : Gi1/0/45                
+  SysName      : sw1o-1204-2.office   
+  System Descr : Cisco IOS Software, C2960S Software (C2960S-UNIVERSALK9-M...
+  PortDescr    : sw3o_Gi48                                                  
+
+  System Capabilities Supported  : bridge, router
+  System Capabilities Enabled    : bridge
+
+  Remote Management Address
+     Type    : ipv4
+     Address : 10.0.100.101",
+               array(
+                       7 => array (0 => array ('device' => 'GXP1615_00:0b:82:a9:56:6d', 'port' => 'eth0',),),
+                       9 => array (0 => array ('device' => 'IT-PC','port' => 'enp2s0',),),
+                       48 => array (0 => array ('device' => 'sw1o-1204-2.office', 'port' => 'Gi1/0/45',),),
+               ),
+       ),
+
+       // - parser for mac address list
+       array(
+               "hpprocurveN1178ReadMacList",
+               " Status and Counters - Port Address Table
+
+  MAC Address   Located on Port
+  ------------- ---------------
+  002590-4a1faa 48            
+  002590-4a22bb 48            
+  58971e-7464cc 48            
+  d48564-d3c4dd 48            
+  f02929-cb03ee 48",
+               array(
+                       48 => array (
+                               0 => array ('mac' => '00:25:90:4a:1f:aa', 'vid' => '',),
+                               1 => array ('mac' => '00:25:90:4a:22:bb', 'vid' => '',),
+                               2 => array ('mac' => '58:97:1e:74:64:cc', 'vid' => '',),
+                               3 => array ('mac' => 'd4:85:64:d3:c4:dd', 'vid' => '',),
+                               4 => array ('mac' => 'f0:29:29:cb:03:ee', 'vid' => '',),
+                       ),
+               ),
+       ),
+
+       // - parser for mac addresses on port
+       array(
+               "hpprocurveN1178ReadMacList",
+               " Status and Counters - Port Address Table - 48
+
+  MAC Address 
+  -------------
+  002590-4a1f14
+  002590-4a22da
+  58971e-746424
+  f02929-cb0330",
+               array(
+                       48 => array (
+                               0 => array ('mac' => '00:25:90:4a:1f:14', 'vid' => '',),
+                               1 => array ('mac' => '00:25:90:4a:22:da', 'vid' => '',),
+                               2 => array ('mac' => '58:97:1e:74:64:24', 'vid' => '',),
+                               3 => array ('mac' => 'f0:29:29:cb:03:30', 'vid' => '',),
+                       ),
+               ),
+       ),
+
+
+       // - interface status parser
+       array(
+               "hpprocurveN1178ReadInterfaceStatus",
+               " Status and Counters - Port Status
+
+                  | Intrusion                           MDI   Flow  Bcast
+  Port  Type      | Alert     Enabled Status Mode       Mode  Ctrl  Limit
+  ----- --------- + --------- ------- ------ ---------- ----- ----- ------
+  1     100/1000T | No        Yes     Down   1000FDx    MDIX  off   0     
+  47    100/1000T | No        Yes     Down   1000FDx    MDI   off   0     
+  48    100/1000T | No        Yes     Up     1000FDx    MDIX  off   0",
+               array(
+                       1 => array ('status' => 'down', 'speed' => '1000', 'duplex' => 'FDx',),
+                       47 => array ('status' => 'down', 'speed' => '1000', 'duplex' => 'FDx',),
+                       48 => array ('status' => 'up', 'speed' => '1000', 'duplex' => 'FDx',),
+               ),
+       ),
+
+
+       );
+};
+
+
+
+
+
+// Data samples for ternary equals test method
+function breedHPprocurveN1178TernaryEquals ()
+{
+       return array (
+       // Data for hpprocurveN1178TranslatePushQueue function
+       // Case1: access -> access: port 1 vlan 200 -> 201
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 => array ('opcode' => 'begin configuration', ), 1 => array ('opcode' => 'unset access', 'arg1' => 1, 'arg2' => 200,), 2 => array ('opcode' => 'create VLAN','arg1' => '201',),3 => array('opcode' => 'set access', 'arg1' => 1, 'arg2' => '201',), 4 => array('opcode' => 'add allowed', 'port' => 47, 'vlans' => array (       1 => '201',     ),   ),   5 =>   array (     'opcode' => 'add allowed',     'port' => 48,     'vlans' =>     array (       1 => '201',     ),   ),   6 =>   array (     'opcode' => 'end configuration',   ), ),
+               array (),
+               "configure
+no vlan 200 untagged 1
+vlan 201
+exit
+vlan 201 untagged 1
+vlan 201 tagged 47
+vlan 201 tagged 48
+end
+",
+       ),
+       // Case2: access -> trunk (+native): port 2 vlan 200 -> T200+201
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset access',     'arg1' => 2,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'set mode',     'arg1' => 2,     'arg2' => 'trunk',   ),   3 =>   array (     'opcode' => 'add allowed',     'port' => 2,     'vlans' =>     array (       0 => '200',       1 => '201',     ),   ),   4 =>   array (     'opcode' => 'set native',     'arg1' => 2,     'arg2' => '200',   ),   5 =>   array (     'opcode' => 'end configuration',   ), ),
+               array (),
+               "configure
+no vlan 200 untagged 2
+vlan 200 tagged 2
+vlan 201 tagged 2
+no vlan 200 untagged 2
+vlan 200 untagged 2
+no vlan 200 tagged 2
+end
+",
+       ),
+       // Case3: access -> trunk (-native): port 3 vlan 200 -> T+200,201
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset access',     'arg1' => 3,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'set mode',     'arg1' => 3,     'arg2' => 'trunk',   ),   3 =>   array (     'opcode' => 'add allowed',     'port' => 3,     'vlans' =>     array (       0 => '200',       1 => '201',     ),   ),   4 =>   array (     'opcode' => 'end configuration',   ), ),
+               array (),
+               "configure
+no vlan 200 untagged 3
+vlan 200 tagged 3
+vlan 201 tagged 3
+no vlan 200 untagged 3
+end
+",
+       ),
+       // Case4: trunk (+native) -> access: port 4 T200+201 -> access 200 (old native VID)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset native',     'arg1' => 4,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'rem allowed',     'port' => 4,     'vlans' =>     array (       0 => 200,       1 => 201,     ),   ),   3 =>   array (     'opcode' => 'set mode',     'arg1' => 4,     'arg2' => 'access',   ),   4 =>   array (     'opcode' => 'set access',     'arg1' => 4,     'arg2' => '200',   ),   5 =>   array (     'opcode' => 'end configuration',   ), ),
+               array (),
+               "configure
+no vlan 200 untagged 4
+vlan 200 tagged 4
+no vlan 200 tagged 4
+no vlan 201 tagged 4
+vlan 200 untagged 4
+no vlan 200 tagged 4
+no vlan 201 tagged 4
+end
+",
+       ),
+       // Case5: trunk (+native) -> access: port 5 T200+201 -> access 201 (old tagged VID)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset native',     'arg1' => 5,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'rem allowed',     'port' => 5,     'vlans' =>     array (       0 => 200,       1 => 201,     ),   ),   3 =>   array (     'opcode' => 'set mode',     'arg1' => 5,     'arg2' => 'access',   ),   4 =>   array (     'opcode' => 'set access',     'arg1' => 5,     'arg2' => '201',   ),   5 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 untagged 5
+vlan 200 tagged 5
+no vlan 200 tagged 5
+no vlan 201 tagged 5
+vlan 201 untagged 5
+no vlan 200 tagged 5
+no vlan 201 tagged 5
+end
+",
+       ),
+       // Case6: trunk (+native) -> access: port 6 T200+201 -> access 202 (new VID)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset native',     'arg1' => 6,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'rem allowed',     'port' => 6,     'vlans' =>     array (       0 => 200,       1 => 201,     ),   ),   3 =>   array (     'opcode' => 'create VLAN',     'arg1' => '202',   ),   4 =>   array (     'opcode' => 'set mode',     'arg1' => 6,     'arg2' => 'access',   ),   5 =>   array (     'opcode' => 'set access',     'arg1' => 6,     'arg2' => '202',   ),   6 =>   array (     'opcode' => 'add allowed',     'port' => 47,     'vlans' =>     array (       2 => '202',     ),   ),   7 =>   array (     'opcode' => 'add allowed',     'port' => 48,     'vlans' =>     array (       2 => '202',     ),   ),   8 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 untagged 6
+vlan 200 tagged 6
+no vlan 200 tagged 6
+no vlan 201 tagged 6
+vlan 202
+exit
+vlan 202 untagged 6
+no vlan 200 tagged 6
+no vlan 201 tagged 6
+vlan 202 tagged 47
+vlan 202 tagged 48
+end
+",
+       ),
+       // Case7: trunk (+native) -> trunk (+native): port 7 T200+201 -> T200+201-202 (add tagged vlan 202)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'add allowed',     'port' => 7,     'vlans' =>     array (       2 => '202',     ),   ),   2 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+vlan 202 tagged 7
+end
+",
+       ),
+       // Case8: trunk (+native) -> trunk (+native): port 7 T200+201-202 -> T200+201 (remove tagged vlan 202)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'rem allowed',     'port' => 7,     'vlans' =>     array (       2 => 202,     ),   ),   2 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 202 tagged 7
+end
+",
+       ),
+       // Case9: trunk (+native) -> trunk (-native): port 8 T200+201 -> T+200-201 (keep old native 200 as tagged)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset native',     'arg1' => 8,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 untagged 8
+vlan 200 tagged 8
+end
+",
+       ),
+       // Case10: trunk (+native) -> trunk (-native): port 9 T200+201 -> T+201 (remove old native 200 totally)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'unset native',     'arg1' => 9,     'arg2' => 200,   ),   2 =>   array (     'opcode' => 'rem allowed',     'port' => 9,     'vlans' =>     array (       0 => 200,     ),   ),   3 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 untagged 9
+vlan 200 tagged 9
+no vlan 200 tagged 9
+end
+",
+       ),
+       // Case11: trunk (+native) -> trunk (+native): port 10 T200+201 -> T200+202 (change tagged vlan to 202)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'rem allowed',     'port' => 10,     'vlans' =>     array (       1 => 201,     ),   ),   2 =>   array (     'opcode' => 'add allowed',     'port' => 10,     'vlans' =>     array (       1 => '202',     ),   ),   3 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 201 tagged 10
+vlan 202 tagged 10
+no vlan 201 tagged 10
+end
+",
+       ),
+       // Case12: trunk (-native) -> access: port 20 T+200-201 -> A202
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'rem allowed',     'port' => 20,     'vlans' =>     array (       0 => 200,       1 => 201,     ),   ),   2 =>   array (     'opcode' => 'set mode',     'arg1' => 20,     'arg2' => 'access',   ),   3 =>   array (     'opcode' => 'set access',     'arg1' => 20,     'arg2' => '202',   ),   4 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 tagged 20
+no vlan 201 tagged 20
+vlan 202 untagged 20
+no vlan 200 tagged 20
+no vlan 201 tagged 20
+end
+",
+       ),
+       // Case13: trunk (-native) -> trunk (+native): port 21 T+200-201 -> T200+201 (add native vlan 200)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'set native',     'arg1' => 21,     'arg2' => '200',   ),   2 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+vlan 200 untagged 21
+no vlan 200 tagged 21
+end
+",
+       ),
+       // Case14: trunk (-native) -> trunk (-native): port 22 T+200-201 -> T+201 (remove tagged vlan 200)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'rem allowed',     'port' => 22,     'vlans' =>     array (       0 => 200,     ),   ),   2 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 tagged 22
+end
+",
+       ),
+       // Case15: trunk (-native) -> trunk (-native): port 23 T+200-201 -> T+200-202 (add tagged vlan 202)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'add allowed',     'port' => 23,     'vlans' =>     array (       2 => '202',     ),   ),   2 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+vlan 202 tagged 23
+end
+",
+       ),
+       // Case16: trunk (-native) -> trunk (-native): port 24 T+200-201 -> T+202 (change all vlans to new tagged VID)
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'begin configuration',   ),   1 =>   array (     'opcode' => 'rem allowed',     'port' => 24,     'vlans' =>     array (       0 => 200,       1 => 201,     ),   ),   2 =>   array (     'opcode' => 'add allowed',     'port' => 24,     'vlans' =>     array (       0 => '202',     ),   ),   3 =>   array (     'opcode' => 'end configuration',   ),),
+               array (),
+               "configure
+no vlan 200 tagged 24
+no vlan 201 tagged 24
+vlan 202 tagged 24
+no vlan 200 tagged 24
+no vlan 201 tagged 24
+end
+",
+       ),
+       // Case17: get8021q
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'get8021q',   ),),
+               NULL,
+               "show vlans ports ethernet all detail
+",
+       ),
+       // Case18: getlldpstatus
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'getlldpstatus',   ),),
+               NULL,
+               "show lldp info remote-device all
+",
+       ),
+       // Case19: getportstatus
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'getportstatus',   ),),
+               NULL,
+               "show int brief
+",
+       ),
+       // Case20: getmaclist
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'getmaclist',   ),),
+               NULL,
+               "show mac-address
+",
+       ),
+       // Case21: getportmaclist
+       array(
+               "hpprocurveN1178TranslatePushQueue",
+               '534',
+               array (0 =>   array (     'opcode' => 'getportmaclist',     'arg1' => '48',   ),),
+               NULL,
+               "show mac-address ethernet 48
+",
+       ),
+       );
+}
\ No newline at end of file
index 730b2a2..1c51d22 100644 (file)
@@ -13,6 +13,10 @@ identical (assertSame) to the expected return value.
 
 require_once '../wwwroot/inc/popup.php';
 
+// Breed hpprocurveN1178
+require ('BreedHPprocurveN1178PureProvider.php');
+// any other breed-specific files
+
 class PureFunctionTest extends RTTestCase
 {
        /**
@@ -124,6 +128,14 @@ class PureFunctionTest extends RTTestCase
        }
 
        public function providerUnaryEquals ()
+       {
+               $ret = self::baseUnaryEquals();
+               $ret = array_merge ($ret, breedHPprocurveN1178UnaryEquals());
+               // any other breed-specific Unary additions
+               return $ret;
+       }
+
+       private static function baseUnaryEquals ()
        {
                return array
                (
@@ -1481,6 +1493,14 @@ class PureFunctionTest extends RTTestCase
        }
 
        public function providerTernaryEquals ()
+       {
+               $ret = self::baseTernaryEquals();
+               $ret = array_merge ($ret, breedHPprocurveN1178TernaryEquals());
+               // any other breed-specific Ternary additions
+               return $ret;
+       }
+
+       private static function baseTernaryEquals ()
        {
                return array
                (
diff --git a/wwwroot/inc/breed-hpprocurveN1178.php b/wwwroot/inc/breed-hpprocurveN1178.php
new file mode 100644 (file)
index 0000000..d40328d
--- /dev/null
@@ -0,0 +1,440 @@
+<?php
+
+// Functions for HP Procurve switches 
+
+function hpprocurveN1178ReadLLDPStatus ($input)
+{
+       $ret = array();
+       foreach (explode ("\n", $input) as $line)
+       {
+               $matches = array();
+               switch (TRUE)
+               {
+               case preg_match ('/^  Local Port.+:(.+)$/', $line, $matches):
+                       if (empty(trim($matches[1])))
+                               {
+                                       $ret['current']['local_port'] = 'NULL';
+                                       break;
+                               }
+                       else
+                               {
+                                       $ret['current']['local_port'] = shortenIfName (trim($matches[1]));
+                                       break;
+                               }
+               case preg_match ('/^  PortId.+:(.+)$/', $line, $matches):
+                       if (empty(trim($matches[1])))
+                               {
+                                       $ret['current']['remote_port'] = 'NULL';
+                                       break;
+                               }
+                       else
+                               {
+                                       $ret['current']['remote_port'] = trim($matches[1]);
+                                       break;
+                               }
+               case preg_match ('/^  SysName\s+:(.+)?$/', $line, $matches):
+                       if (empty(trim($matches[1])))
+                               {
+                                       $ret['current']['sys_name'] = 'NULL';
+                                       break;
+                               }
+                       else
+                               {
+                                       $ret['current']['sys_name'] = trim($matches[1]);
+                                       break;
+                               }
+               case preg_match ('/^  PortDescr\s+:(.+)?$/', $line, $matches):
+                       if (empty(trim($matches[1])))
+                               {
+                                       $ret['current']['sys_name'] = 'NULL';
+                                       break;
+                               }
+                       else
+                               {
+                                       $ret['current']['port_descr'] = trim($matches[1]);
+                               }
+                       if
+                               (
+                                       array_key_exists ('current', $ret) &&
+                                       array_key_exists ('local_port', $ret['current']) &&
+                                       array_key_exists ('port_descr', $ret['current']) &&
+                                       array_key_exists ('sys_name', $ret['current']) &&
+                                       array_key_exists ('remote_port', $ret['current'])
+                               )
+                               {
+                                       $port = NULL;
+                                       if (preg_match ('/^[a-f0-9]{2} [a-f0-9]{2} [a-f0-9]{2} [a-f0-9]{2} [a-f0-9]{2} [a-f0-9]{2}$/',$ret['current']['remote_port']))
+                                               $port = $ret['current']['port_descr'];
+                                       else
+                                               $port = $ret['current']['remote_port'];
+                                       if (isset ($port))
+                                               {
+                                                       $ret[$ret['current']['local_port']][] = array
+                                                       (
+                                                               'device' => $ret['current']['sys_name'],
+                                                               'port' => $port,
+                                                       );
+                                               }
+                               }
+                               unset ($ret['current']);
+               default:
+               }
+       }
+       unset ($ret['current']);
+       return $ret;
+}
+
+
+function hpprocurveN1178ReadInterfaceStatus ($text)
+{
+       $result = array();
+       $state = 'headerSearch';
+       foreach (explode ("\n", $text) as $line)
+               {
+                       switch ($state)
+                       {
+                               case 'headerSearch':
+                                       if (preg_match('/\s?Port\s+Type\s+/', $line))
+                                       {
+                                               $name_field_borders = getColumnCoordinates($line, 'Port');
+                                               if (isset ($name_field_borders['from']))
+                                                       $state = 'readPort';
+                                       }
+                                       break;
+                               case 'readPort':
+                                       if ( preg_match('/^[0-9]+/', trim (substr ($line, 0, $name_field_borders['length'])), $matches) )
+                                               $portname = $matches[0];
+                                               if (!isset($portname))
+                                                       $portname = NULL;
+                                       if ( preg_match('/^[0-9]+.+/', trim (substr ($line, $name_field_borders['from'] + $name_field_borders['length'] + 1)), $matches) )
+                                               $rest = $matches[0];
+                                               if (!isset($rest))
+                                                       $rest = NULL;
+
+                                       $field_list = preg_split('/\s+/', $rest);
+                                       if (count ($field_list) < 4)
+                                               break;
+                                       list ($type, $delim, $alert, $adm_status, $status_raw, $mode) = $field_list;
+                                               if ($status_raw == 'Up')
+                                                       $status = 'up';
+                                               elseif ($status_raw == 'Down')
+                                                       $status = 'down';
+                                               elseif ($adm_status == 'No')
+                                                       $status = 'disabled';
+                                       if ( preg_match('/([01]+)/', $mode, $matches) )
+                                               $speed = $matches[0];
+                                       if ( preg_match('/([a-zA-Z]+)/', $mode, $matches) )
+                                               $duplex = $matches[0];
+                                       $result[$portname] = array
+                                               (
+                                                       'status' => $status,
+                                                       'speed' => $speed,
+                                                       'duplex' => $duplex,
+                                               );
+                                       break;
+                       }
+               }
+       return $result;
+}
+
+
+function hpprocurveN1178ReadMacList ($text)
+{
+       $result = array();
+       $state = 'headerSearch';
+       foreach (explode ("\n", $text) as $line)
+               {
+               switch ($state)
+                       {
+                       case 'headerSearch':
+                               if (preg_match('/\s?MAC Address\s+Located on Port\s?/', $line))
+                                       {
+                                       $state = 'readPort_all';
+                                       break;
+                                       }
+                               elseif (preg_match('/^\s*Status and Counters -\s*Port Address Table -\s*([0-9]+)$/', $line, $portdata))
+                                       {
+                                       $state = 'readPort_single';
+                                       $portname = $portdata[1];
+                                       break;
+                                       }
+                       case 'readPort_all':
+                               if (! preg_match ('/^\s*([a-f0-9]{6}\-[a-f0-9]{6})\s*(\S+)$/', trim ($line), $matches))
+                                       break;
+                               $portname = shortenIfName ($matches[2]);
+                               $vid = NULL;
+                               $result[$portname][] = array
+                                       (
+                                               'mac' => implode (":", str_split(str_replace ('-', '', $matches[1]), 2)),
+                                               'vid' => '',
+                                       );
+                               break;
+                       case 'readPort_single':
+                               if (! preg_match ('/^\s*([a-f0-9]{6}\-[a-f0-9]{6})\s*$/', trim ($line), $matches))
+                                       break;
+                               $vid = NULL;
+                               $result[$portname][] = array
+                                       (
+                                               'mac' => implode (":", str_split(str_replace ('-', '', $matches[1]), 2)),
+                                               'vid' => '',
+                                       );
+                               break;
+
+                       }
+               }
+       foreach ($result as $portname => &$maclist)
+               sort ($maclist);
+       return $result;
+}
+
+
+function hpprocurveN1178Read8021QConfig ($input)
+{
+       $ret = constructRunning8021QConfig();
+       $ret['vlanlist'][] = VLAN_DFL_ID; // HP hides VLAN1 from config text
+       $matches = array();
+       $vlanlist = array();
+       $rawdata = explode ("Status and Counters - VLAN Information - for ports", $input);
+       array_shift($rawdata); 
+
+       foreach ($rawdata as $line)
+               {
+               $port = array(
+                       'port_id' => '',
+                       'port_name' => '',
+                       'vlan_data' => array(),
+                       'port_mode' => FALSE,
+               );
+               $port_mode = '';
+               foreach (explode ("\n", $line) as $vlans)
+                       {
+                       if (preg_match('/^ VLAN ID Name |^\s*-------/', $vlans))
+                               {
+                               continue;
+                               }
+                       if (preg_match('/^([0-9]+)$/', trim($vlans), $matches))
+                               {
+                               $port['port_id'] = $matches[1];
+                               continue;
+                               }
+                       if (preg_match('/^\s+Port name: (.+)$/', $vlans, $matches))
+                               {
+                               $port['port_name'] = $matches[1];
+                               continue;
+                               }
+                       if (preg_match ('/^\S*\s*(\d+)\s+(\S+)\s+\S+\s+\S+\s+([T]agged|[U]ntagged).*$/', $vlans, $matches))
+                               {
+                               $port['vlan_data'][$matches[1]]['vlan_name'] = $matches[2];
+                               $port['vlan_data'][$matches[1]]['vlan_mode'] = $matches[3];
+                               $vlanlist[] = $matches[1];
+                               }
+                       }
+               // Here we add parsed data into $ret array
+               $port_id = $port['port_id'];
+               $port_name = $port['port_name'];
+
+               // Port config
+               $ret['portconfig'][$port_id][] = array ('type' => 'line-header', 'line' => 'interface ' . $port_id);
+               if (!empty($port_name))
+                       {
+                       $ret['portconfig'][$port_id][] = array ('type' => 'line-other', 'line' => 'name ' . $port_name);
+                       }
+
+               // Port data
+               $allowed_vlans = array();
+               if (array_search('Tagged', array_column($port['vlan_data'], 'vlan_mode')) === FALSE)
+                       {
+                       $port_mode = 'access';
+                       foreach ($port['vlan_data'] as $vid=>$value)
+                               {
+                               $allowed_vlans[] = $vid;
+                               $native = $vid;
+                               }
+                       }
+               else
+                       {
+                       $port_mode = 'trunk';
+                       foreach ($port['vlan_data'] as $vid=>$value)
+                               {
+                               if (preg_match('/\d+/', $vid))
+                                       {
+                                       $allowed_vlans[] = $vid;
+                                       }
+                               }
+                       foreach ($port['vlan_data'] as $vid=>$value)
+                               {
+                               if (preg_match('/\d+/', $vid) && $value['vlan_mode'] === "Untagged")
+                                       {
+                                       $native = $vid;
+                                       break;
+                                       }
+                               else
+                                       {
+                                       $native = 0;
+                                       }
+                               }
+                       }
+               $ret['portdata'][$port_id] = array ('mode' => $port_mode, 'allowed' => $allowed_vlans, 'native' => $native);
+
+               unset($port);
+               unset($allowed_vlans);
+       }
+       // Return de-duplicated and sorted list of vlans
+       $ret['vlanlist'] = array_merge($ret['vlanlist'], array_keys(array_flip($vlanlist)));
+       sort($ret['vlanlist']);
+       unset($vlanlist);
+       unset($matches);
+       unset($rawdata);
+       return $ret;
+}
+
+
+function hpprocurveN1178TranslatePushQueue ($dummy_object_id, $queue, $dummy_vlan_names)
+{
+       $ret = '';
+       $rem_allowed_data = array();
+       $rem_tagged_data = array();
+       $unset_access_data = array();
+
+       foreach ($queue as $cmd)
+       switch ($cmd['opcode'])
+       {
+       case 'create VLAN':
+               $ret .= "vlan ${cmd['arg1']}\nexit\n";
+               break;
+       case 'destroy VLAN':
+               $ret .= "no vlan ${cmd['arg1']}\n";
+               break;
+       case 'add allowed':
+               foreach ($cmd['vlans'] as $vlan_id)
+               {
+                       $ret .= "vlan ${vlan_id} tagged ${cmd['port']}\n";
+               }
+               ///////////////////////////////////////////////////////////////////////////////////////
+               // Here is a workaround: remove untagged port for case access->trunk(non-native)
+               if
+               (
+                       array_key_exists('port_id', $unset_access_data) &&
+                       array_key_exists('vlan_id', $unset_access_data) &&
+                       $unset_access_data['port_id'] === $cmd['port']
+               )
+               {
+                       $ret .= "no vlan ${unset_access_data['vlan_id']} untagged ${unset_access_data['port_id']}\n";
+                       unset($unset_access_data);
+               }
+               ///////////////////////////////////////////////////////////////////////////////////////
+               // Here is a workaround: remove port tagged from vlans again for case trunk(non-native)->trunk(non-native)
+               if ( $rem_tagged_data )
+               {
+                       foreach ($rem_tagged_data as $port_id=>$vlan_list)
+                       {
+                               if ( !empty($port_id) && $port_id === $cmd['port'] )
+                               {
+                                       foreach ($vlan_list as $key=>$vlan_id)
+                                       {
+                                       if ( isset($vlan_id) )
+                                       $ret .= "no vlan ${vlan_id} tagged ${port_id}\n";
+                                       }
+                               }
+                       }
+               }
+               $rem_tagged_data = array();
+               break;
+       case 'rem allowed':
+               foreach ($cmd['vlans'] as $vlan_id)
+               {
+                       $ret .= "no vlan ${vlan_id} tagged ${cmd['port']}\n";
+                       ///////////////////////////////////////////////////////////////////////////////////////
+                       // Here is a workaround: we should remove untagged port before 
+                       // add it as tagged for case access->trunk(non-native)
+                       // HP L2 switches doesn't allow "orphaned" ports (without tags)
+                       $rem_allowed_data[$cmd['port']][] = $vlan_id;
+                       $rem_tagged_data[$cmd['port']][] = $vlan_id;
+               }
+               break;
+       case 'set access':
+               $ret .= "vlan ${cmd['arg2']} untagged ${cmd['arg1']}\n";
+               ///////////////////////////////////////////////////////////////////////////////////////
+               // Now remove tagged port for case trunk(non-native)->access
+               //file_put_contents ('/var/log/racktables.log', var_export($rem_allowed_data, true), FILE_APPEND | LOCK_EX);
+               foreach ($rem_allowed_data as $port_id=>$vlan_list)
+               {
+                       if ( !empty($port_id) && $port_id === $cmd['arg1'] )
+                       {
+                       foreach ($vlan_list as $key=>$vlan_id)
+                               {
+                               if ( isset($vlan_id) )
+                                       $ret .= "no vlan ${vlan_id} tagged ${cmd['arg1']}\n";
+                               }
+                       }
+               }
+               $rem_allowed_data = array();
+               break;
+       case 'unset access':
+               ///////////////////////////////////////////////////////////////////////////////////////
+               // Here is a workaround: we should remove untagged port before we
+               // add it as tagged, for case access->trunk(non-native)
+               // HP L2 switches doesn't allow "orphaned" ports (without tags)
+               $unset_access_data['port_id'] = $cmd['arg1'];
+               $unset_access_data['vlan_id'] = $cmd['arg2'];
+               $ret .= "no vlan ${cmd['arg2']} untagged ${cmd['arg1']}\n";
+               break;
+       case 'set native':
+               $ret .= "vlan ${cmd['arg2']} untagged ${cmd['arg1']}\n";
+               ///////////////////////////////////////////////////////////////////////////////////////
+               // Here is a workaround: we should add tagged port again for case
+               // when we remove native but keep it as tagged
+               $ret .= "no vlan ${cmd['arg2']} tagged ${cmd['arg1']}\n";
+               break;
+       case 'unset native': // NOP
+               $ret .= "no vlan ${cmd['arg2']} untagged ${cmd['arg1']}\n";
+               $ret .= "vlan ${cmd['arg2']} tagged ${cmd['arg1']}\n";
+               break;
+       case 'set mode': // NOP
+               break;
+       case 'begin configuration':
+               $ret .= "configure\n";
+               break;
+       case 'end configuration':
+               $ret .= "end\n";
+               break;
+       case 'save configuration':
+               $ret .= "write memory\n";
+               break;
+       case 'cite':
+               $ret .= $cmd['arg1'];
+               break;
+       // query list
+       case 'get8021q':
+               $ret .= "show vlans ports ethernet all detail\n";
+               break;
+       case 'getlldpstatus':
+               $ret .= "show lldp info remote-device all\n";
+               break;
+       case 'getallconf':
+               $ret .= "show running-config\n";
+               break;
+       case 'getportstatus':
+               $ret .= "show int brief\n";
+               break;
+       case 'getmaclist':
+               $ret .= "show mac-address\n";
+               break;
+       case 'getportmaclist':
+               $ret .= "show mac-address ethernet {$cmd['arg1']}\n";
+               break;
+       default:
+               throw new InvalidArgException ('opcode', $cmd['opcode']);
+       }
+       return $ret;
+}
+
+function hpprocurveN1178SpotConfigText ($input)
+{
+       return $input;
+}
+
+
+
+
+?>
\ No newline at end of file
diff --git a/wwwroot/inc/breed-ios15.php b/wwwroot/inc/breed-ios15.php
new file mode 100644 (file)
index 0000000..2413ab7
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+function ios15ReadLLDPStatus ($input)
+{
+       $ret = array();
+       foreach (explode ("\n", $input) as $line)
+       {
+               $matches = array();
+               switch (TRUE)
+               {
+               case preg_match ('/^Local Intf: (.+)$/', $line, $matches):
+                       $ret['current']['local_port'] = shortenIfName ($matches[1]);
+                       break;
+               case preg_match ('/^[Pp]ort [Ii][Dd]: (.+)$/', $line, $matches):
+                       $ret['current']['remote_port'] = $matches[1];
+                       break;
+               case preg_match ('/^[Pp]ort [Dd]escription: (.+)$/', $line, $matches):
+                       $ret['current']['port_descr'] = $matches[1];
+                       break;
+               case preg_match ('/^[Ss]ystem [Nn]ame: (.+)$/', $line, $matches):
+                       $ret['current']['sys_name'] = $matches[1];
+                       if
+                       (
+                               array_key_exists ('current', $ret) &&
+                               array_key_exists ('local_port', $ret['current']) &&
+                               array_key_exists ('port_descr', $ret['current']) &&
+                               array_key_exists ('sys_name', $ret['current']) &&
+                               array_key_exists ('remote_port', $ret['current'])
+                       )
+                       {
+                               $port = NULL;
+                               if (preg_match ('/^[a-f0-9]{4}.[a-f0-9]{4}.[a-f0-9]{4}$/',$ret['current']['remote_port'], $matches))
+                                       $port = $ret['current']['port_descr'];
+                               else
+                                       $port = $ret['current']['remote_port'];
+                               if (isset ($port))
+                                       $ret[$ret['current']['local_port']][] = array
+                                       (
+                                               'device' => $ret['current']['sys_name'],
+                                               'port' => $port,
+                                       );
+                       }
+                       unset ($ret['current']);
+               default:
+               }
+       }
+       unset ($ret['current']);
+       return $ret;
+}
+
+// most of the commands are compatible with IOS12, so are generated by ios12TranslatePushQueue
+// Only ios15-specific commands are generated here (eg., lldp)
+function ios15TranslatePushQueue ($dummy_object_id, $queue, $dummy_vlan_names)
+{
+       $ret = '';
+       foreach ($queue as $cmd)
+               switch ($cmd['opcode'])
+               {
+               case 'getlldpstatus':
+                       $ret .= "show lldp neighbors detail | i Local Intf:|Chassis id:|Port id:|Port Description:|System Name:\n";
+                       break;
+                       // fall-through
+               default:
+                       $ret .= ios12TranslatePushQueue ($dummy_object_id, array ($cmd), $dummy_vlan_names);
+                       break;
+               }
+       return $ret;
+}
index 67d14a1..dce8606 100644 (file)
@@ -4,6 +4,11 @@
 # framework. See accompanying file "COPYING" for the full copyright and
 # licensing information.
 
+// functions for HP Procurve switches (N.11 OS)
+require_once 'breed-hpprocurveN1178.php';
+// functions for Cisco IOS 15 switches
+require_once 'breed-ios15.php';
+
 // Read provided output of "show cdp neighbors detail" command and
 // return a list of records with (translated) local port name,
 // remote device name and (translated) remote port name.
index 0a68cfb..52abb83 100644 (file)
@@ -3614,6 +3614,7 @@ $dictionary = array
        3717 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R320'),
        3718 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R330'),
        3719 => array ('chapter_id' => 11, 'dict_value' => 'Dell PowerEdge%GPASS%R740xd'),
+       3720 => array ('chapter_id' => 14, 'dict_value' => 'HP Procurve OS N.11.78'),
 
 # Any new "default" dictionary records must go above this line (i.e., with
 # dict_key code less than 50000). This is necessary to keep AUTO_INCREMENT
index d849d2f..f3f1b42 100644 (file)
@@ -38,6 +38,7 @@ define ('CHAP_OBJTYPE', 1);
 define ('RE_L2_IFCFG', '/^[0-9A-F]{2}(:[0-9A-F]{2}){5}$/'); // most ifconfigs
 define ('RE_L2_IFCFG_SUNOS', '/^[0-9A-F]{1,2}(:[0-9A-F]{1,2}){5}$/'); // SunOS ifconfig
 define ('RE_L2_CISCO', '/^[0-9A-F]{4}(\.[0-9A-F]{4}){2}$/');
+define ('RE_L2_HP', '/^[0-9A-F]{6}-[0-9A-F]{6}$/');
 define ('RE_L2_HUAWEI', '/^[0-9A-F]{4}(-[0-9A-F]{4}){2}$/');
 define ('RE_L2_SOLID', '/^[0-9A-F]{12}$/i');
 define ('RE_L2_IPCFG', '/^[0-9A-F]{2}(-[0-9A-F]{2}){5}$/');
@@ -1042,6 +1043,9 @@ function l2addressForDatabase ($string)
                case preg_match (RE_L2_CISCO, $string):
                        $ret = str_replace ('.', '', $string);
                        break;
+               case preg_match (RE_L2_HP, $string):
+                       $ret = str_replace ('-', '', $string);
+                       break;
                case preg_match (RE_L2_HUAWEI, $string):
                        $ret = str_replace ('-', '', $string);
                        break;
index d74b79c..5fda594 100644 (file)
@@ -118,6 +118,25 @@ $breedfunc = array
        'iosxr4-getportstatus-main'=> 'iosxr4ReadInterfaceStatus',
        'ucs-xlatepushq-main'      => 'ucsTranslatePushQueue',
        'ucs-getinventory-main'    => 'ucsReadInventory',
+       'hpprocurveN1178-getlldpstatus-main' => 'hpprocurveN1178ReadLLDPStatus',
+       'hpprocurveN1178-get8021q-main'      => 'hpprocurveN1178Read8021QConfig',
+       'hpprocurveN1178-getportstatus-main' => 'hpprocurveN1178ReadInterfaceStatus',
+       'hpprocurveN1178-getmaclist-main'    => 'hpprocurveN1178ReadMacList',
+       'hpprocurveN1178-getportmaclist-main'=> 'hpprocurveN1178ReadMacList',
+       'hpprocurveN1178-xlatepushq-main'    => 'hpprocurveN1178TranslatePushQueue',
+       'hpprocurveN1178-getallconf-main'    => 'hpprocurveN1178SpotConfigText',
+       'ios15-getcdpstatus-main'  => 'ios12ReadCDPStatus',
+       'ios15-getlldpstatus-main' => 'ios15ReadLLDPStatus',
+       'ios15-get8021q-main'      => 'ios12ReadVLANConfig',
+       'ios15-get8021q-swports'   => 'ios12ReadSwitchPortList',
+       'ios15-get8021q-top'       => 'ios12ScanTopLevel',
+       'ios15-get8021q-readport'  => 'ios12PickSwitchportCommand',
+       'ios15-get8021q-readvlan'  => 'ios12PickVLANCommand',
+       'ios15-getportstatus-main' => 'ciscoReadInterfaceStatus',
+       'ios15-getmaclist-main'    => 'ios12ReadMacList',
+       'ios15-getportmaclist-main'=> 'ios12ReadMacList',
+       'ios15-xlatepushq-main'    => 'ios15TranslatePushQueue',
+       'ios15-getallconf-main'    => 'ios12SpotConfigText',
 );
 
 define ('MAX_GW_LOGSIZE', 1024*1024); // do not store more than 1 MB of log data
@@ -134,7 +153,7 @@ $breed_by_swcode = array
        258  => 'ios12', // IOS 12.4 (router OS)
        1901 => 'ios12', // IOS 15.0 (switch)
        2082 => 'ios12', // IOS 15.1 (switch)
-       2142 => 'ios12', // IOS 15.2 (switch)
+       2142 => 'ios15', // IOS 15.2 (switch)
        2667 => 'ios12', // IOS 15.0 (router OS)
        1963 => 'ios12', // IOS 15.1 (router OS)
        2668 => 'ios12', // IOS 15.2 (router OS)
@@ -176,7 +195,7 @@ $breed_by_swcode = array
        1675 => 'eos4',  // Arista EOS 4
        1759 => 'iosxr4', // Cisco IOS XR 4.2
        1786 => 'ros11', // Marvell ROS 1.1
-
+       3720 => 'hpprocurveN1178', // HP Procurve 11
        //... linux items added by the loop below
 );
 
@@ -188,7 +207,6 @@ $shorten_by_breed = array (
        'vrp85' => 'vrp85ShortenIfName',
        'iosxr4' => 'iosxr4ShortenIfName',
 );
-
 $breed_by_hwcode = array (
        1362 => 'fdry5', // Brocade FastIron CX648
        //... dlink items added by the loop below
@@ -521,6 +539,15 @@ function queryTerminal ($object_id, $commands, $tolerate_remote_errors = TRUE)
                        $protocol = 'netcat';
                        $commands = "disable clipaging\n" . $commands;
                        break;
+               case 'hpprocurveN1178':
+                       $protocol = 'sshnokey';
+                       $prompt = '(Login|[Uu]sername|[Pp]assword): $|Press any key to continue(\e\[\??\d+(;\d+)*[A-Za-z])*$|[#>].*$';
+                       # Console emulator should be set to 'none' to avoid special characters to be sent by stupid default VT100!!!
+                       $commands = "configure\nconsole local-terminal none\nexit\nno page\n" . $commands . "configure\nconsole local-terminal vt100\nend\nexit\nexit\ny\n";
+                       break;
+               case 'ios15':
+                       $commands = "terminal length 0\nno terminal monitor\n" . $commands;
+                       break;
        }
        if (! isset ($protocol))
                $protocol = 'netcat';