gpt4 book ai didi

php - 使用 php Telnet 到 cisco 交换机

转载 作者:行者123 更新时间:2023-12-04 18:21:11 27 4
gpt4 key购买 nike

我需要使用 php 远程登录到 cisco 交换机并执行 show interface status命令并获得结果。我尝试了一些在互联网上找到的 php 类,但它们都无法连接到设备。所以我尝试自己编写脚本,但我有同样的问题,我无法连接到设备。

主持人向我发送横幅消息,然后用 username: 换行.
我用 \r\n 发送我的用户名,等待一段时间并尝试读取数据,但在我看来主机只是忽略了我的换行符。这是我得到的回复(explode('\n') on response):

Array
(
[0] => %
[1] => User Access Verification
[2] => Username: timeout expired!
)

为什么我没有提示输入密码?我尝试发送 telnet header ,没有,没有变化。谁能帮帮我吗?

这是我的代码
<?
$host = "switchName";
$name = "name";
$pass = "pass";
$port = 23;
$timeOut = 15;
$connected = false;
$skipNullLines = true;
$timeout = 125000;


$header1=chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x41).chr(0x4E).chr(0x53).chr(0x49).chr(0xFF).chr(0xF0);
$header2=chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21);


function read_string()
{
global $fw,$host,$skipNullLines;
$string = "";

while( !feof($fw) )
{
$read = fgets($fw);

$string .= $read;

// Probably prompt, stop reading
if( strpos($read, ':') !== FALSE || strpos($read, '> (enable)') !== FALSE || strpos($read, $host.'#') !== FALSE)
{ break; }
}

$string = explode("\n", $string);

// Get rid of null lines
$ret = array();
for($i = 0; $i<count($string); $i++)
{
if( trim($string[$i]) == '' && $skipNullLines ) continue;

$ret[] = $string[$i];
}

return $ret;
}

function send_string($string, $force=false)
{
GLOBAL $timeout,$fw;
$string = trim($string);

// execute only strings that are preceded by "show" (if not forced)
if(!$force && strpos($string, 'show ') !== 0)
{
return 1;
}

fputs($fw, $string."\r\n");
echo("SEND:".$string."\r\n");
usleep($timeout);
}


$fw = fsockopen($host, $port, $errno, $errorstr, $timeOut);
if($fw == false)
{
echo("Cant connect");
}
else
{
echo("Connected<br>");
$connected = true;

stream_set_timeout($fw, $timeout);

// fputs($fw, $header1);
// usleep($timeout);
// fputs($fw, $header2);
// usleep($timeout);
print_r(read_string());
send_string("test", true);
print_r(read_string());
}

fclose($fw);
?>

更新
如果我首先发送用户名,然后我阅读,我会收到密码提示。我不明白,为什么我不能先阅读主机的消息然后发送我的回复。现在它对我的工作方式(发送回复然后阅读提示)是没有意义的! (而且我仍然收到“% Authentication failed.” 带有正确密码/名称的消息事件)。
...
$connected = true;
stream_set_timeout($fw, $timeout);
send_string("name", true);
send_string("password", true);
print_r(read_string());
...

最佳答案

好的,所以我不知道问题出在哪里,但是经过“几次”测试后,我能够编写适合我的类(class)。我不知道为什么其他 telnet 类不工作,尽管它们几乎相同。所以如果有人会有类似的问题,你可以试试这个:

class TELNET
{
private $host;
private $name;
private $pass;
private $port;
private $connected;
private $connect_timeout;
private $stream_timetout;

private $socket;

public function TELNET()
{
$this->port = 23;
$this->connected = false; // connected?
$this->connect_timeout = 10; // timeout while asking for connection
$this->stream_timeout = 380000; // timeout between I/O operations
}

public function __destruct()
{
if($this->connected) { fclose($this->socket); }
}

// Connects to host
// @$_host - addres (or hostname) of host
// @$_user - name of user to log in as
// $@_pass - password of user
//
// Return: TRUE on success, other way function will return error string got by fsockopen()
public function Connect($_host, $_user, $_pass)
{
// If connected successfully
if( ($this->socket = @fsockopen($_host, $this->port, $errno, $errorstr, $this->connect_timeout)) !== FALSE )
{
$this->host = $_host;
$this->user = $_user;
$this->pass = $_pass;

$this->connected = true;

stream_set_timeout($this->socket, 0, 380000);
stream_set_blocking($this->socket, 1);

return true;
}
// else if coulnt connect
else return $errorstr;
}


// LogIn to host
//
// RETURN: will return true on success, other way returns false
public function LogIn()
{
if(!$this->connected) return false;

// Send name and password
$this->SendString($this->user, true);
$this->SendString($this->pass, true);

// read answer
$data = $this->ReadTo(array('#'));

// did we get the prompt from host?
if( strtolower(trim($data[count($data)-1])) == strtolower($this->host).'#' ) return true;
else return false;
}


// Function will execute command on host and returns output
//
// @$_command - command to be executed, only commands beginning with "show " can be executed, you can change this by adding
// "true" (bool type) as the second argument for function SendString($command) inside this function (3rd line)
//
function GetOutputOf($_command)
{
if(!$this->connected) return false;

$this->SendString($_command);

$output = array();
$work = true;

//
// Read whole output
//
// read_to( array( STRINGS ) ), STRINGS are meant as possible endings of outputs
while( $work && $data = $this->ReadTo( array("--More--","#") ) )
{
// CHeck wheter we actually did read any data
$null_data = true;
foreach($data as $line)
{
if(trim($line) != "") {$null_data = false;break;}
}
if($null_data) { break;}

// if device is paging output, send space to get rest
if( trim($data[count($data)-1]) == '--More--')
{
// delete line with prompt (or "--More--")
unset($data[count($data)-1]);

// if second line is blank, delete it
if( trim($data[1]) == '' ) unset($data[1]);
// If first line contains send command, delete it
if( strpos($data[0], $_command)!==FALSE ) unset($data[0]);

// send space
fputs($this->socket, " ");
}

// ak ma vystup max dva riadky
// alebo sme uz nacitali prompt
// IF we got prompt (line ending with #)
// OR string that we've read has only one line
// THEN we reached end of data and stop reading
if( strpos($data[count($data)-1], '#')!==FALSE /* || (count($data) == 1 && $data[0] == "")*/ )
{
// delete line with prompt
unset($data[count($data)-1]);

// if second line is blank, delete it
if( trim($data[1]) == '' ) unset($data[1]);
// If first line contains send command, delete it
if( strpos($data[0], $_command)!==FALSE ) unset($data[0]);

// stop while cyclus
$work = false;
}

// get rid of empty lines at the end
for($i = count($data)-1; $i>0; $i--)
{
if(trim($data[$i]) == "") unset($data[$i]);
else break;
}

// add new data to $output
foreach($data as $v)
{ $output[] = $v; }
}

// return output
return $output;
}


// Read from host until occurence of any index from $array_of_stops
// @array_of_stops - array that contains strings of texts that may be at the end of output
// RETURNS: output of command as array of lines
function ReadTo($array_of_stops)
{
$ret = array();
$max_empty_lines = 3;
$count_empty_lines = 0;

while( !feof($this->socket) )
{
$read = fgets($this->socket);
$ret[] = $read;

//
// Stop reading after (int)"$max_empty_lines" empty lines
//
if(trim($read) == "")
{
if($count_empty_lines++ > $max_empty_lines) break;
}
else $count_empty_lines = 0;

//
// Does last line of readed data contain any of "Stop" strings ??
$found = false;
foreach($array_of_stops AS $stop)
{
if( strpos($read, $stop) !== FALSE ) { $found = true; break; }
}
// If so, stop reading
if($found) break;
}

return $ret;
}



// Send string to host
// If force is set to false (default), function sends to host only strings that begins with "show "
//
// @$string - command to be executed
// @$force - force command? Execute if not preceeded by "show " ?
// @$newLine - append character of new line at the end of command?
function SendString($string, $force=false, $newLine=true)
{
$t1 = microtime(true);
$string = trim($string);

// execute only strings that are preceded by "show"
// and execute only one command (no new line characters) !
if(!$force && strpos($string, 'show ') !== 0 && count(explode("\n", $string)) == 1)
{
return 1;
}


if($newLine) $string .= "\n";
fputs($this->socket, $string);

$t2 = microtime(true);
}

}


// EXAMPLE
$host = "hostname";
$name = "username";
$pass = "password";


$t = new TELNET();
echo("CONNECT:".$t->Connect($host, $name, $pass)."<br>");
echo("LOGIN:".(int)$t->LogIn());
echo("<br>OUTPUT:<br>");
print_r($t->GetOutputOf("show snmp"));
print_r($t->GetOutputOf("show users"));
print_r($t->GetOutputOf("show interface status"));

PS:我的设备提示是“主机名#”,因此您可能需要编辑登录功能以使此代码与您的设备提示一起使用(因此您可能需要在 GetOutputOf() 中)

关于php - 使用 php Telnet 到 cisco 交换机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10650037/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com