<?php
require_once('Net/Socket.php');
require_once('libs/class.debug.php');
require_once('engines/abstract.class.base_switch_engine.php');
require_once('engines/interface.class.engine_interface.php');
class cisco extends base_switch_engine implements engine_interface {
/*
base_switch_engine methods.
*/
public function __construct($options) {
$this->options = $options;
debug::output("Initiallizing engine",@(bool)$options['debug'],true);
}
public function connect() {
//Because I'm too lazy to change the variables.
$options = $this->options;
$options['switch'] = (!isset($options['switch'])) ? 'localhost' : $options['switch'] ;
$options['port'] = (!isset($options['port'])) ? 23 : $options['port'] ;
$options['password'] = (!isset($options['password'])) ? '' : $options['password'] ;
$options['enablepassword'] = (!isset($options['enablepassword'])) ? '' : $options['enablepassword'] ;
$this->socket = new Net_Socket();
@debug::output("Connecting: {$options['switch']}:{$options['port']}",$this->debug,true);
$this->socket->connect($options['switch'],$options['port'],null,4);
return;
}
public function disconnect() {
$options = $this->options;
@debug::output("Disconnecting: {$options['switch']}:{$options['port']}",$this->debug,true);
$this->socket->disconnect();
return;
}
public function logon() {
debug::output("Sending: password",$this->debug,true);
$this->read("Password:");
$this->send($this->options['password']);
$this->read(">");
//To get the switch name.
//preg_match_all("/\r\n([^>]*)/i",$line,$mat);
//self::$name = $mat[1][0];
//$tmp = explode("\r\n",$mat[1][0]);
//self::$name = $tmp[count($tmp)-1];
debug::output("Sending: enable password",$this->debug,true);
$this->send("enable");
$this->read("Password: ");
/*
$line = '';
while(($res = substr(($line.=self::$tc->read(1)), (strlen($line)-10),10))!= "Password: ") {
//echo ((int) $t)."|".$line;
}*/
if(is_array($this->options['enablepassword'])) {
$this->options['enablepassword'] = $this->options['password'];
}
$this->send($this->options['enablepassword']);
$this->read();
/*
$line = '';
while(($res = substr(($line.=self::$tc->read(1)), (strlen($line)-1),1))!= "#") {
}*/
debug::output("Sending: terminal length 0",$this->debug,true);
$this->send('terminal length 0');
$this->read();
debug::output("End Login",$this->debug,true);
return;
}
public function send($cmd) {
debug::output("Sending: ".$cmd,$this->debug,true);
$this->socket->write($cmd.chr(13));
return;
}
public function read($escape = '#') {
debug::output("Waiting for response...",$this->debug,true);
$line = '';
$el = strlen($escape);
/*
Notes on making a better error trap.
$line = '';
while(is_string($pear=$this->socket->read(1))) {
if(($res = substr(($line.=($pear)), (strlen($line)-10),10))!= "Password: ") { break; } else { var_dump($pear); break; }
//echo ((int) $t)."|".$line;
//debug_echo($pear,self::$debug);
}
var_dump($pear);
*/
//while(($res = substr(($line.=($err[]=$this->socket->read(1))), (strlen($line)-$el))) != $escape) {
while(is_string($t = $this->socket->read(1)) and ($res = substr(($line.=$t), (strlen($line)-$el),$el))!= $escape) {
}
//var_dump($t);
debug::output("Data received...processing...",$this->debug,true);
$t = explode("\r\n",$line);
array_shift($t); //first
array_pop($t); //last
return $t;
}
/*
engine_interface methods.
*/
public function _getMacPortTable() {
$this->send('show mac-address-table');
$list = $this->read();
$macs = array();
foreach($list as $k => $v) {
preg_match_all('/ ([^ ]*)( {2,})([a-fA-F0-9\.]{14})( {2,})([^ ]{1,})( {2,})(.{2,})/si',$v,$mat);
@$m = strtolower(str_replace('.','',$mat[3][0]));
if(@$mat[1][0] === null && strlen($m) == 0 && @$mat[7][0] === null) { continue; }
$macs[] = array('vlan' => $mat[1][0], 'mac' => $m , 'interface' => $mat[7][0]);
}
return $macs;
}
public function _getArpTable() {
$this->send('show arp');
$list = $this->read();
$arp = array();
foreach($list as $k => $v) {
preg_match_all('/([0-9\.]{7,15})( {2,})([\-0-9]{1,3})( {2,})([a-fA-F0-9\.]{14})( {2,})([^ ]*)( {2,})(.*)/si',$v,$mat);
@$m = strtolower(str_replace('.','',$mat[5][0]));
if(strlen($m) == 0 && @$mat[1][0] === null) { continue; }
$arp[] = array('mac' => $m, 'ip' => $mat[1][0], 'interface' => null);
}
$this->arp = $arp;
return $arp;
}
public function _getInterfaceSettings() {
/*
show run | include interface | channel-group
*/
$this->send('show run | include interface | switchport mode | switchport trunk | switchport access vlan');
$list = $this->read();
$interface = null;
/*
array(2) {
[0]=>
string(28) "interface GigabitEthernet0/3"
[1]=>
string(18) "GigabitEthernet0/3"
}
*/
$rtn = array();
$cur = array('interface' =>null,'mode'=>null, 'vlan' => null);
for($i = 0; $i < count($list); $i++) {
$cur = array('interface' =>null,'mode'=>null, 'vlan' => null);
//echo $i."\r\n";
if(preg_match('/interface ([a-zA-Z]*[0-9](\/[0-9]{1,})|)/i',$list[$i],$mat)) {
//switchport mode trunk
$cur['interface'] = $mat[1];
//var_dump($mat);
//echo $i."-".$cur['interface']."\r\n";
//echo $i.": ".$list[$i]."\r\n";
for(true; (isset( $list[$i+1]) and !(bool)preg_match('/interface ([a-zA-Z]*[0-9](\/[0-9]{1,})|)/i',$list[$i+1]) and $i < count($list)); $i++) {
$line = $list[$i+1];
//echo "\t".($i+1).": ".$list[$i+1]."\r\n";
//if((bool)preg_match('/interface (.*[0-9]\/[0-9]{1,})/i',$line)) { continue; }
if(preg_match('/switchport mode (trunk|access|dot1q-tunnel|dynamic|private-vlan)/i',$line,$mat)) {
$cur['mode'] = $mat[1];
}
if(preg_match('/switchport trunk allowed vlan ([0-9\,-]*)/i',$line,$mat)) {
$cur['vlan'] = $mat[1];
}
if(preg_match('/switchport access vlan ([0-9]*)/i',$line,$mat)) {
$cur['vlan'] = $mat[1];
}
}
//var_dump($cur);
$rtn[] = array('interface' => $cur['interface'], 'mode' => (($cur['mode']===null)?'access':$cur['mode']), 'vlan' => (($cur['vlan']===null)?'1':$cur['vlan']));
}
}
//var_dump($rtn);
return $rtn;
//var_dump($list);
}
}
?>