Created
April 22, 2020 21:26
-
-
Save sitchi/380e2ae64a6d0f09feaaf1a29bf8d0ae to your computer and use it in GitHub Desktop.
telnet gets the MAC address and interface name from OLT - GPON/EPON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
ini_set('max_execution_time', 0); | |
require_once 'telnetclass.php'; | |
#$preg_onu_information = '/((EPON0\/[\d]{1,2}:[\d]{1,2})\s*(([A-Za-z]{3,4})\s*([0-9a-zA-Z]{3,4})){0,1}\s*([a-f0-9]{4}.[a-f0-9]{4}.[a-f0-9]{4})[\w\W]*(deregistered|auto_configured|auto-configured|lost)[\w\W]*(N\/A|power\soff|power-off|wire\sdown|unknow))+/iU'; | |
#$preg_epon_optical_from_onu = '/((EPON0\/[\d]{1,2}:[\d]{1,2})\s*(-\d{1,2}\.\d))+/iU'; | |
$preg_mac_address_table = '(([a-f0-9]{4}.[a-f0-9]{4}.[a-f0-9]{4})\s*(STATIC|DYNAMIC)[\w\W]\s*([g/e]?pon0(.*))\s)'; | |
$ip = '192.168.1.10'; | |
$user = 'admin'; | |
$password = 'admin'; | |
try { | |
$tn = new Telnet($ip, 23, '3', 'User Access Verification'); | |
$tn->login($user, $password); | |
$tn->setPrompt('#'); | |
$tn->exec('enable'); | |
$tn->exec('terminal width 200'); | |
$tn->exec('terminal length 512'); | |
preg_match_all($preg_mac_address_table, $tn->exec('show mac address-table'), $result); | |
foreach ($result[0] as $i => $value) { | |
$mac = strtoupper(preg_replace('~..(?!$)~', '\0:', str_replace(".", "", $result[1][$i]))); | |
$interface = strtoupper(preg_replace("/[\n\r]/", "", $result[3][$i])); | |
} | |
} catch (Exception $e) { | |
continue; | |
$tn->disconnect(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Telnet class | |
* | |
* Used to execute remote commands via telnet connection | |
* Usess sockets functions and fgetc() to process result | |
* | |
* All methods throw Exceptions on error | |
* | |
* Written by Dalibor Andzakovic <[email protected]> | |
* Based on the code originally written by Marc Ennaji and extended by | |
* Matthias Blaser <[email protected]> | |
* | |
* Extended by Christian Hammers <[email protected]> | |
* | |
*/ | |
class Telnet | |
{ | |
private $host; | |
private $port; | |
private $timeout; | |
private $socket = NULL; | |
private $buffer = NULL; | |
private $prompt; | |
private $errno; | |
private $errstr; | |
private $NULL; | |
private $DC1; | |
private $WILL; | |
private $WONT; | |
private $DO; | |
private $DONT; | |
private $IAC; | |
private $global_buffer = ''; | |
const TELNET_ERROR = FALSE; | |
const TELNET_OK = TRUE; | |
/** | |
* Constructor. Initialises host, port and timeout parameters | |
* defaults to localhost port 23 (standard telnet port) | |
* | |
* @param string $host Host name or IP addres | |
* @param int $port TCP port number | |
* @param int $timeout Connection timeout in seconds | |
* @return void | |
*/ | |
public function __construct($host = '192.168.0.2', $port = '23', $timeout = 3, $prompt = '#') | |
{ | |
$this->host = $host; | |
$this->port = $port; | |
$this->timeout = $timeout; | |
$this->prompt = $prompt; | |
// set some telnet special characters | |
$this->NULL = chr(0); | |
$this->DC1 = chr(17); | |
$this->WILL = chr(251); | |
$this->WONT = chr(252); | |
$this->DO = chr(253); | |
//$this->DONT = chr(32); | |
$this->DONT = chr(254); | |
$this->IAC = chr(255); | |
$this->RQMORE = chr(63); | |
$this->SPACE = chr(32); | |
$this->connect(); | |
} | |
/** | |
* Destructor. Cleans up socket connection and command buffer | |
* | |
* @return void | |
*/ | |
public function __destruct() | |
{ | |
// cleanup resources | |
$this->disconnect(); | |
$this->buffer = NULL; | |
$this->global_buffer = NULL; | |
} | |
/** | |
* Attempts connection to remote host. Returns TRUE if sucessful. | |
* | |
* @return boolean | |
*/ | |
public function connect() | |
{ | |
// check if we need to convert host to IP | |
if (!preg_match('/([0-9]{1,3}\\.){3,3}[0-9]{1,3}/', $this->host)) { | |
$ip = gethostbyname($this->host); | |
if ($this->host == $ip) { | |
throw new Exception("Cannot resolve $this->host"); | |
} else { | |
$this->host = $ip; | |
} | |
} | |
// attempt connection | |
$this->socket = fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout); | |
if (!$this->socket) { | |
throw new Exception("Cannot connect to $this->host on port $this->port"); | |
} | |
$this->waitPrompt(); | |
return self::TELNET_OK; | |
} | |
/** | |
* Closes IP socket | |
* | |
* @return boolean | |
*/ | |
public function disconnect() | |
{ | |
if ($this->socket) { | |
if (!fclose($this->socket)) { | |
throw new Exception("Error while closing telnet socket"); | |
} | |
$this->socket = NULL; | |
} | |
return self::TELNET_OK; | |
} | |
/** | |
* Executes command and returns a string with result. | |
* This method is a wrapper for lower level private methods | |
* | |
* @param string $command Command to execute | |
* @return string Command result | |
*/ | |
public function exec($command) | |
{ | |
$this->write($command); | |
$this->waitPrompt($command); | |
return $this->getBuffer(); | |
} | |
/** | |
* Attempts login to remote host. | |
* This method is a wrapper for lower level private methods and should be | |
* modified to reflect telnet implementation details like login/password | |
* and line prompts. Defaults to standard unix non-root prompts | |
* | |
* @param string $username Username | |
* @param string $password Password | |
* @return boolean | |
*/ | |
public function login($username, $password) | |
{ | |
try { | |
$this->setPrompt('Username:'); | |
$this->waitPrompt(); | |
$this->write($username); | |
$this->setPrompt('Password:'); | |
$this->waitPrompt(); | |
$this->write($password); | |
$this->setPrompt(); | |
$this->waitPrompt(); | |
} catch (Exception $e) { | |
throw new Exception("Login failed."); | |
} | |
return self::TELNET_OK; | |
} | |
/** | |
* Sets the string of characters to respond to. | |
* This should be set to the last character of the command line prompt | |
* | |
* @param string $s String to respond to | |
* @return boolean | |
*/ | |
public function setPrompt($s = '>') | |
{ | |
$this->prompt = $s; | |
return self::TELNET_OK; | |
} | |
/** | |
* Gets character from the socket | |
* | |
* @return void | |
*/ | |
protected function getc() | |
{ | |
$c = fgetc($this->socket); | |
$this->global_buffer .= $c; | |
return $c; | |
} | |
/** | |
* Clears internal command buffer | |
* | |
* @return void | |
*/ | |
public function clearBuffer() | |
{ | |
$this->buffer = ''; | |
} | |
/** | |
* Reads characters from the socket and adds them to command buffer. | |
* Handles telnet control characters. Stops when prompt is ecountered. | |
* | |
* @param string $prompt | |
* @return boolean | |
*/ | |
protected function readTo($prompt, $command = false) | |
{ | |
$log_add = false; | |
if (!$this->socket) { | |
throw new Exception("Telnet connection closed"); | |
} | |
// clear the buffer | |
$this->clearBuffer(); | |
$until_t = time() + $this->timeout; | |
do { | |
// time's up (loop can be exited at end or through continue!) | |
if (time() > $until_t) { | |
throw new Exception("Couldn't find the requested : '$prompt' within {$this->timeout} seconds"); | |
} | |
$c = $this->getc(); | |
if ($c === false) { | |
throw new Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server: " . $this->buffer); | |
} | |
if (substr($this->buffer, strlen($this->buffer) - strlen('--More--')) == '--More--') { | |
fwrite($this->socket, $this->SPACE); | |
$this->buffer = substr($this->buffer, 0, - strlen('--More--')); | |
} | |
// Interpreted As Command | |
if ($c == $this->IAC) { | |
if ($this->negotiateTelnetOptions()) { | |
continue; | |
} | |
} | |
// append current char to global buffer | |
if ($c !== chr(8)) { | |
$this->buffer .= $c; | |
} | |
// we've encountered the prompt. Break out of the loop | |
if ((substr($this->buffer, strlen($this->buffer) - strlen($prompt))) == $prompt) { | |
return self::TELNET_OK; | |
} | |
} while ($c != $this->NULL || $c != $this->DC1); | |
} | |
/** | |
* Write command to a socket | |
* | |
* @param string $buffer Stuff to write to socket | |
* @param boolean $addNewLine Default true, adds newline to the command | |
* @return boolean | |
*/ | |
protected function write($buffer, $addNewLine = true) | |
{ | |
if (!$this->socket) { | |
throw new Exception("Telnet connection closed"); | |
} | |
// clear buffer from last command | |
$this->clearBuffer(); | |
if ($addNewLine == true) { | |
$buffer .= "\n"; | |
} | |
$this->global_buffer .= $buffer; | |
if (!fwrite($this->socket, $buffer) < 0) { | |
throw new Exception("Error writing to socket"); | |
} | |
return self::TELNET_OK; | |
} | |
/** | |
* Returns the content of the command buffer | |
* | |
* @return string Content of the command buffer | |
*/ | |
protected function getBuffer() | |
{ | |
// cut last line (is always prompt) | |
$buf = explode("\n", $this->buffer); | |
unset($buf[count($buf) - 1]); | |
$buf = implode("\n", $buf); | |
return trim($buf); | |
} | |
/** | |
* Returns the content of the global command buffer | |
* | |
* @return string Content of the global command buffer | |
*/ | |
public function getGlobalBuffer() | |
{ | |
return $this->global_buffer; | |
} | |
/** | |
* Telnet control character magic | |
* | |
* @param string $command Character to check | |
* @return boolean | |
*/ | |
protected function negotiateTelnetOptions() | |
{ | |
$c = $this->getc(); | |
if ($c != $this->IAC) { | |
if (false) { | |
fwrite($this->socket, $this->SPACE); | |
} else if (($c == $this->DO) || ($c == $this->DONT)) { | |
$opt = $this->getc(); | |
fwrite($this->socket, $this->IAC . $this->WONT . $opt); | |
} else if (($c == $this->WILL) || ($c == $this->WONT)) { | |
$opt = $this->getc(); | |
fwrite($this->socket, $this->IAC . $this->DONT . $opt); | |
} else { | |
throw new Exception('Error: unknown control character ' . ord($c)); | |
} | |
} else { | |
throw new Exception('Error: Something Wicked Happened'); | |
} | |
return self::TELNET_OK; | |
} | |
/** | |
* Reads socket until prompt is encountered | |
*/ | |
protected function waitPrompt($command = false) | |
{ | |
return $this->readTo($this->prompt, $command); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment