INDEX | About Me | Private Projects | Hobbies/Science-Toys | From my keyboard / IT
[Go to Articles Index] | [Go to IT Articles INDEX]

How to connect Cisco Router with PHP Script:

           I used to explain a Perl version of these scripts in page "How to Connect Cisco Router with Perl Scripts ". And now, I'm talking about the Php version. Because, Php is known to be easier than Perl by the most of the people. You may want to implement these samples in your existing projects. Essentially, we are establishing a telnet session between our script and a Cisco router. It's only a telnet connection. There are a lot of telnet-scripts for php in the internet. You can use them but we are talking about a specific situation. Let's write it from scratch.
           I prepare to write those scripts as much as parametric, that is, I will avoid writing all of staff hard-coded. "$argv" variable is a predefined array in Php and it is able to capture the given parameters as well as in the console. For example,

<?php
#!/usr/bin/php
$if(isset($argv[2])) {
print "The first parameter is:".$argv[1]."\n";
print "The second parameter is:".$argv[2]."\n";
} else {
print "usage: ./sample.php parameter1 parameter2 \n";
print "or \n";
print "usage: php sample.php parameter1 parameter2 \n";
}

?>

           You can execute the script by typing "./sample.php" or "php sample.php" directly in your console. If you want to execute it as "./sample.php", you have to add the line (#!/usr/bin/php) on the top of your script and you have to give executive permissions to sample.php. (chmod +x sample.php). If you want to execute with the syntax "php sample.php", you don't need to add the line and give those rights. Because, the executing rights are already given for "php" part.

The sample.php script is capturing your parameters using the array variable $argv. You can see all of the $argv content using the line "print_r($argv);" in your Php script. So we will use the $argv array to take ip_address, username and password values from the user. I used fsockopen, fput and fgets commands to establish connections, to send commands and to get the output from the router, respectively.
           If the cisco router output is very long for one page, it returns a " -- More -- " statement in the last line. If we press the space button on the keyboard when we see this statement, the router will send next page. If we press the enter key on the keyboard when we see this statement, router will send the next line. So we have to control the content and if there is a " -- More -- " statement in the content, we have to send a space character to get next part of the router output. We will control the " -- More -- " statement with an "ereg" function of php.

The php script for connecting to the Cisco router (telnetCisco.php):
#!/usr/bin/php
<?php
if(!isset($argv[2])) {
die ("usage: ./scriptName router_ip username password\n");
}
$port = 23;
$timeout = 10;
$router_ip = $argv[1];
$username = $argv[2];
$password = $argv[3];

$connection = fsockopen($router_ip, $port, $errno, $errstr, $timeout);

if(!$connection){
echo "Connection failed\n";
exit();
} else {
echo "Connected\n";
fputs($connection, "$username\r\n");
fputs($connection, "$password\r\n");
fputs($connection, "show run\r\n");
fputs($connection, " ");

$j = 0;
while ($j < 16) {
fgets($connection, 128);
$j++;
}
stream_set_timeout($connection, 2);
$timeoutCount = 0;
while (!feof($connection)){
$content = fgets($connection, 128);
$content = str_replace("\r", '', $content);
$content = str_replace("\n", "", $content);
print $content."\n";

# If the router say "press space for more", send space char:
if (ereg('--More--', $content) ){ // IF current line contain --More-- expression,
fputs ($connection, " "); // sending space char for next part of output.
} # The "more" controlling part complated.

$info = stream_get_meta_data($connection);
if ($info['timed_out']) { // If timeout of connection info has got a value, the router not returning a output.
$timeoutCount++; // We want to count, how many times repeating.
}
if ($timeoutCount >2){ // If repeating more than 2 times,
break; // the connection terminating..
}
}
}
echo "End.\r\n";
?>

           "stream_get_meta_data" function is the most critical one in this article. Because, I used the stream_get_meta_data to check the status of connection. Following output shows the "stream_get_meta_data" content with print_r function to see "how to recognize end of the output". (The last three loop)

....
...
Array
(
[stream_type] => tcp_socket
[mode] => r+
[unread_bytes] => 0
[seekable] =>
[timed_out] => 1
[blocked] => 1
[eof] =>
)
Array
(
[stream_type] => tcp_socket
[mode] => r+
[unread_bytes] => 0
[seekable] =>
[timed_out] => 1
[blocked] => 1
[eof] =>
)
Array
(
[stream_type] => tcp_socket
[mode] => r+
[unread_bytes] => 0
[seekable] =>
[timed_out] => 1
[blocked] => 1
[eof] =>
)

           The time_out values are "1" in the last two loops. The $timeoutCount value is counting that "1"s in the telnetCisco.php and if it gets "1" more than two times, it stops reading the output with a "break;" line.

One of the copies of this article located here: Practical Code Solutions: How to Connect Cisco Router with PHP Scripts
My Personal Web Page - ReNewing period...