ActivePerl error message? Router script. Please help.Newbie

W

wrreisen2

Hi, Thanks again for all your help.

My router has ip 10.0.0.2

I press start, run then type telnet.
At the telnet prompt I type "open 10.0.0.2"
Connecting To 10.0.0.2...Could not open connection to the host, on port
23: Connect failed

I tried pinging 10.0.0.2 from the command prompt and it comes back
fine:

Reply from 10.0.0.2: bytes=32 time<1ms TTL=64
Reply from 10.0.0.2: bytes=32 time<1ms TTL=64
Reply from 10.0.0.2: bytes=32 time<1ms TTL=64
Reply from 10.0.0.2: bytes=32 time<1ms TTL=64

Ping statistics for 10.0.0.2:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

I have now commented out where there are alternatives as kindly
described by Alan J Wylie.
When I connect to my router through internet explorer I have to type in
both username and password.
So I've left in line 66:
$t->login("admin", "epicrouter" ) or die "login failed";
and commented out lines 70-72
# $t->waitfor("/Password:/" ) or die "login waitfor 1 failed";
# $t->print("fr0gR0utr" ) or die "login print failed";
# $t->waitfor("/> /" ) or die "login waitfor 2 failed";

I've left in line 74:
@lines = $t->cmd("adsl status");
because in the manual
http://www.edimax.nl/download/manual/AR-7024_M.zip it has a section on
a

configuration html page called ADSL STATUS (doesn't mention telnet
commands anywhere though. It

doesn't mention "adsl info" anywhere in the manual so I have commented
out line 76:
# @lines = $t->cmd("adsl info");

AFAIK I don't see a way of finding out which commands the router may
respond to and which it doesn't

except by trial and error. The router manual doesn' mention the terms
"system reboot" or "sys

reboot". So I've just left in line 78:
$t->print("system reboot");
and commented out line 80:
$t->print("sys reboot");

I've called this perl script router.pl. so at the dos command prompt in
XP I type
c:\perl router.pl
and press enter. It takes about 10seconds then the command prompt comes
back up again.
c:\


I presume as I've commented out all the logging and mailing functions
in this script there's no way

of knowing what its doing without altering it and perhaps adding in the
Win32-eventlog. When the

command prompt pops back again I presume it stops working?

With ppm I searched for Win32-eventlog it found "Win32-eventlog-carp"
so I installed this with ppm:

Extracting 5/5: blib/arch/auto/Win32/EventLog/Carp/.exists
Installing C:\Perl\html\site\lib\Win32\EventLog\Carp.html
Installing C:\Perl\site\lib\Win32\EventLog\Carp.pm
Successfully installed win32-eventlog-carp version 1.21 in ActivePerl
5.8.8.817.

To use this event log should I put:
"Use Win32::eventlog::carp" at the beginning

Would line 40 be okay to uncomment to work with this
win32-eventlog-carp?
# openlog( "routerping", "", "user" );
Would line 51 change from:
# syslog( 'debug', "can't ping %s", $ip );
to:
eventlog( 'debug', "can't ping %s", $ip );

Would line 57 change from:
# syslog( 'debug', "%s", "rebooting router" );
to:
eventlog( 'debug', "%s", "rebooting router" );

Would line 65 stay the same?
$t->input_log( "/var/log/router.log" );


As mentioned by Len I tried adding the print "Content-type:
text/html\n\n"; at line 23 so its shifted

the lines of code down 2 lines.
When run in InternetExplorer you don't get this part of the error
message anymore:

CGI Error
The specified CGI application misbehaved by not returning a complete
set of HTTP headers. The headers

it did return are:
Error message.


As kindly recommended by Len I've tried changing line 59 from
system( "ip route add " . $localip . "/32 dev eth1" );
to
system( "route add " . $localip . "/32 dev eth1" );

instead of the previous error:

'ip' is not recognized as an internal or external command, operable
program or batch file. problem

connecting to "10.0.0.2", port 23: Unknown error at
c:\inetpub\wwwroot\perl\router_01.pl line 63

I get this error:

route: bad destination address 10.0.0.2/32
problem connecting to "10.0.0.2", port 23: Unknown error at
c:\inetpub\wwwroot\perl\router_01.pl line

63


Line 63 is:
$t = Net::Telnet->new( Timeout => 10, Prompt => '/> /', Host =>
$localip );


I'm happy running this script at the command prompt if that can work
reliably I was just trying it

internet explorer just because the active perl manual suggested running
its examples from

http://localhost/perl/ so under windows xp it seemed the logical choice
to try it in Internet

Explorer. The end result I would like is something that will run
continually all the time under

windows XP whenever the computer is switched on. Could you run this as
a service in someway or is

there a better way?

Thanks for all your help.


The Script now reads:
#! /usr/bin/perl -w

use strict;

use Net::Telnet;
use Net::ping;
# use Sys::Syslog;
#use Mail::Mailer;

# RFC1918 IP address of your router
my $localip = "10.0.0.2";

# a list of IP addresses to ping that are 1) few hops away, and 2)
# likely to be stable

# cheapest first
# next IP upstream 0.0.0.0 (from a traceroute) [I'm on a dynamic ip so
1st upstream ip changes from day to
# day so have put in 4.68.116.98 from further up the traceroute

# Your ISP's DNS servers: 212.159.13.49 & 212.159.13.50
# Your ISP's web server: 84.92.4.90
# i.root-servers.net: 192.36.148.17
# and any others you can think of

print "Content-type: text/html\n\n";

my @netips = ("194.166.128.72", "212.159.13.49", "212.159.13.50",
"84.92.4.90", "192.36.148.17" );
my $ip;
my $ok = 0;
my $mailer;

my $t; # telnet socket
my $p; # ping

my @lines;
my $i;
my $tmp;

$p = Net::ping->new("icmp");

# log to syslog
# openlog( "routerping", "", "user" );

foreach $ip (@netips)
{
if ( $p->ping($ip) )
{
$ok = 1;
last;
}
else
{
# syslog( 'debug', "can't ping %s", $ip );
}
}

if ( ! $ok )
{
# syslog( 'debug', "%s", "rebooting router" );

# make sure that there is a route to the ADSL router's local
# IP address
system( "route add " . $localip . "/32 dev eth1" );

$t = Net::Telnet->new( Timeout => 10, Prompt => '/> /', Host =>
$localip );

$t->input_log( "/var/log/router.log" );

# if your router asks for a username and password, use this:
$t->login("admin", "epicrouter" ) or die "login failed";

# else if it just prompts for a password use this:

# $t->waitfor("/Password:/" ) or die "login waitfor 1 failed";
# $t->print("fr0gR0utr" ) or die "login print failed";
# $t->waitfor("/> /" ) or die "login waitfor 2 failed";

@lines = $t->cmd("adsl status");
# or perhaps
# @lines = $t->cmd("adsl info");

$t->print("system reboot");
# or perhaps
# $t->print("sys reboot");

$t->close;

# $mailer = Mail::Mailer->new("smtp", Server => "localhost") || die
"can't new mail";
#
# $mailer->open({ From => 'root',
# To => 'root',
# Subject=> "router reboot",
# }) or die "can't open mail";
#
# print $mailer "router reboot";
#
# $mailer->close() || die "can't close mail";
}
 
L

l v

Hi, Thanks again for all your help.

My router has ip 10.0.0.2

I press start, run then type telnet.
At the telnet prompt I type "open 10.0.0.2"
Connecting To 10.0.0.2...Could not open connection to the host, on port
23: Connect failed

Telnet is either not enabled or not avaiable on your router.
I tried pinging 10.0.0.2 from the command prompt and it comes back
fine:

Reply from 10.0.0.2: bytes=32 time<1ms TTL=64
Reply from 10.0.0.2: bytes=32 time<1ms TTL=64
Reply from 10.0.0.2: bytes=32 time<1ms TTL=64
Reply from 10.0.0.2: bytes=32 time<1ms TTL=64

Ping statistics for 10.0.0.2:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

I have now commented out where there are alternatives as kindly
described by Alan J Wylie.
When I connect to my router through internet explorer I have to type in
both username and password.

Since you can connect via a web browser and not via telnet you will need
to rewrite the script to use the LWP module.
 
N

Nick

Hi, Thanks again for all your help.

My router has ip 10.0.0.2

I press start, run then type telnet.
At the telnet prompt I type "open 10.0.0.2"
Connecting To 10.0.0.2...Could not open connection to the host, on port
23: Connect failed

Router doesn't support the Telnet protocol - so you use HTTP instead.

This is easy enough: you're using a generic conexant, and the web
interface is quite easy to understand. All you need to do is request
whatever URL the "Submit" button of the "Reboot without saving" menu
option (you can see a picture of the screen in section 3.3.13 of the
manual) is sending.

If you right-click on that frame in the web browser, and select "View
Source" (IE) or "View Page Source" (FireFox), you need to find a section
that looks *SOMETHING LIKE* this:-

<form action="x" method="y">
<input type="submit" name="submit" value="submit" />
</form>

This is just the code for showing the "Submit" button, and we're
interested in the values of action (x) and method (y). There will
definitely be at least one <input> tag (for the submit button), and
quite possibly more than one, e.g. there might be something like <input
type="hidden" name="save" value="false" />

x is the URL that you need to request in order to get the router to
reboot. y has two possible values - "GET" or "POST" - which tell you how
to pass any required data (that is, any <input> tags) to that URL.

So if we say that, as an example, your router has all four lines I've
given above, and uses GET as it's data-passing method, the script you'd
want would look like this:-
+-+-+-+-+-+-+-+-+
#! /usr/bin/perl -w

use strict;

use Net::ping;
use Net::HTTP;

# RFC1918 IP address of your router
my $localip = "10.0.0.2";

#Easily pingable IP addresses
# Nearest stable upstream: 4.68.116.98
# Your ISP's DNS servers: 212.159.13.49 & 212.159.13.50
# Your ISP's web server: 84.92.4.90
# i.root-servers.net: 192.36.148.17
# These are in the @netips array (below)

print "Content-type: text/html\n\n";

my @netips = ("4.68.116.98", "212.159.13.49", "212.159.13.50",
"84.92.4.90", "192.36.148.17" );
my $ip;
my $ok = 0;

my $http; # HTTP socket
my $p; # ping

# Change this to the correct URL, found in <form action=
my $reset_url = "/";

$p = Net::ping->new("icmp");

foreach $ip (@netips)
{
if ( $p->ping($ip) )
{
$ok = 1;
last;
}
else
{
print "DEBUG: IP " . $ip . " cannot be pinged";
}
}

if ( ! $ok )
{
# Note: Route command wouldn't have worked because
# it was for linux version of program. Feel free
# to add it if you can work out the syntax!

# Changed to send HTTP request for that page
# Don't forget to change "x" to the right URL
# You might be able to switch GET to POST if needed
# without any problems
$http = Net::HTTP->new(Host => $localip) || die $@;
$http->write_request(GET => $reset_url, 'save' => "false", 'submit'
=> "Submit");

# Don't need to bother reading the headers unless we want to
# tell if it failed or not... and sleep(1) followed by ping
# would probably be simpler, easier and faster than parsing the
# HTML. So just close.
$http->close;
}


}
+-+-+-+-+-+-+-+-+

It's easy enough to modify if you need to get rid of the save input tag,
or rename it, or add extra ones. Note that I haven't tested it - not
having Perl on my current PC - so good luck :). It *should* work, but
I've never used Net::HTTP before :D. The syntax for the
$http->write_request() function may also be a bit off, but I've got to
go to work in exactly 3 minutes, so can't check.

xF,

....Nick
 
B

Ben Morrow

Quoth l v said:
Since you can connect via a web browser and not via telnet you will need
to rewrite the script to use the LWP module.

Or, easier, the WWW::Mechanize module.

Ben
 
W

wrreisen2

Thanks Nick & Len for your efforts.

The reboot page on my routers html interface is:
**************************
<HTML>
<script language="javascript">
function dosave()
{
document.location="dosave.htm"
return
}
function doreboot()
{
document.location="doreboot.htm"
return
}

</script>
<BODY BGCOLOR=WHITE background="/images/back.gif">
<FORM action=save.htm method=get>

<CENTER>
<p style="margin-bottom: 15px">
<FONT SIZE=4 COLOR=#000080 face="Times New Roman"><b>Save and
Reboot</b></FONT></p>


<TABLE CELLPADDING=5 cellspacing="0" bgcolor="#F6F6F6" width="520"
border="1">
<TR>
<TD align="center"><font face="Arial" size="2">Save settings and reboot
the
modem.</font></TD>
<TD>
<p align="center">
<INPUT type="button" value="Save & Reboot" onclick="dosave()"
style="font-family: Arial;

background-color: #CCCCCC"><TR>
<TD align="center"><font face="Arial" size="2">Reboot modem without
saving settings.</font></TD>
<TD>
<p align="center">
<INPUT type="button" value=" Reboot Only " onclick="doreboot()"
style="font-family: Arial;

background-color: #CCCCCC"></TD>
</TR>
</TABLE>
</CENTER>
</FORM>
</BODY>
</HTML>

*****************
The above page is the one on the router that reset it. Its aat
http://10.0.0.2/doc/save-1.htm
The page that reboots it is: http://10.0.0.2/doc/doreboot.htm
So I'm taking this as "x" and the "y" is "Get".


When I run this in internet explorer it comes back:

DEBUG: IP 4.68.116.98 cannot be pingedDEBUG: IP 212.159.13.49 cannot be
pingedDEBUG: IP 212.159.13.50

cannot be pingedDEBUG: IP 84.92.4.90 cannot be pingedDEBUG: IP
192.36.148.17 cannot be pinged

I trying pinging each of these from the command line and they ping
healthily.

ping 4.68.116.98

Pinging 4.68.116.98 with 32 bytes of data:

Reply from 4.68.116.98: bytes=32 time=20ms TTL=60
Reply from 4.68.116.98: bytes=32 time=21ms TTL=60
Reply from 4.68.116.98: bytes=32 time=27ms TTL=60
Reply from 4.68.116.98: bytes=32 time=20ms TTL=60

Ping statistics for 4.68.116.98:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 20ms, Maximum = 27ms, Average = 22ms

I check my windows firewall and IE has an exception that says that any
computer on the internet can

access it.

I've called the perl script "http_router.pl" I try running this from
the command prompt and this is all that happens:

C:\Inetpub\wwwroot\perl>perl http_router.pl
Content-type: text/html


C:\Inetpub\wwwroot\perl>


When accessing the router interface normally I have to login with
username="admin" and password="epicrouter". Should this be in the
script somewhere.

This is the script that I've tried. Thanks again.:
*****************************************
#! /usr/bin/perl -w


use strict;


use Net::ping;
use Net::HTTP;


# RFC1918 IP address of your router
my $localip = "10.0.0.2";


#Easily pingable IP addresses
# Nearest stable upstream: 4.68.116.98
# Your ISP's DNS servers: 212.159.13.49 & 212.159.13.50
# Your ISP's web server: 84.92.4.90
# i.root-servers.net: 192.36.148.17
# These are in the @netips array (below)


print "Content-type: text/html\n\n";


my @netips = ("4.68.116.98", "212.159.13.49", "212.159.13.50",
"84.92.4.90", "192.36.148.17" );
my $ip;
my $ok = 0;


my $http; # HTTP socket
my $p; # ping


# Change this to the correct URL, found in <form action=
my $reset_url = "http://10.0.0.2/doc/doreboot.htm";


$p = Net::ping->new("icmp");


foreach $ip (@netips)
{
if ( $p->ping($ip) )
{
$ok = 1;
last;
}
else
{
print "DEBUG: IP " . $ip . " cannot be pinged";
}

}


if ( ! $ok )
{
# Note: Route command wouldn't have worked because
# it was for linux version of program. Feel free
# to add it if you can work out the syntax!

# Changed to send HTTP request for that page
# Don't forget to change "x" to the right URL
# You might be able to switch GET to POST if needed
# without any problems
$http = Net::HTTP->new(Host => $localip) || die $@;
$http->write_request(GET => $reset_url, 'save' => "false", 'submit'

=> "Submit");
 
W

wrreisen2

Hi also tried it in Firefox and it gives the same message:
DEBUG: IP 4.68.116.98 cannot be pingedDEBUG: IP 212.159.13.49 cannot be
pingedDEBUG: IP 212.159.13.50 cannot be pingedDEBUG: IP 84.92.4.90
cannot be pingedDEBUG: IP 192.36.148.17 cannot be pinged
 
H

harryfmudd [AT] comcast [DOT] net

Hi also tried it in Firefox and it gives the same message:
DEBUG: IP 4.68.116.98 cannot be pingedDEBUG: IP 212.159.13.49 cannot be
pingedDEBUG: IP 212.159.13.50 cannot be pingedDEBUG: IP 84.92.4.90
cannot be pingedDEBUG: IP 192.36.148.17 cannot be pinged

If you are running your Perl script as a CGI script, the browser
shouldn't make any difference.

HOWEVER - some OSes restrict the use of ICMP. What happens when you run
the script interactively from an account with administrative privilege?

If you need to run the script under a privileged account, you can do
this through the IIS control panel. Be careful about protection of the
script if you do this. Of course, you should be careful anyway, if you
don't want J. Random User rebooting things for you.

Tom Wyant
 
N

Nicholas Thomas

harryfmudd said:
If you are running your Perl script as a CGI script, the browser
shouldn't make any difference.

HOWEVER - some OSes restrict the use of ICMP. What happens when you run
the script interactively from an account with administrative privilege?

If you need to run the script under a privileged account, you can do
this through the IIS control panel. Be careful about protection of the
script if you do this. Of course, you should be careful anyway, if you
don't want J. Random User rebooting things for you.

Tom Wyant

Given that when run from command-line, the script manages to ping the IP
addresses quite healthily, it must be that - or something similar. I've
never used Net::ping, so can't comment :)

wrreisen: thanks for posting the page. You're right in your assumptions
of x & y.

The username & password does need to be integrated - well spotted. This
is easy enough: we just add an Authorization header to the HTTP request.
Like this:-

-----------------
#! /usr/bin/perl -w

use strict;
use Net::ping;
use Net::HTTP;

# Note the new addition :)
use MIME::Base64::perl;

# RFC1918 IP address of your router
my $localip = "10.0.0.2";

my @netips = ("4.68.116.98", "212.159.13.49", "212.159.13.50",
"84.92.4.90", "192.36.148.17" );
my $ip;
my $ok = 0;
my $encoded;
my $reset_url = "http://10.0.0.2/doc/doreboot.htm";
my $user="admin";
my $pass="epicrouter";

my $http; # HTTP socket
my $p; # ping socket

print "Content-type: text/html\n\n";

$p = Net::ping->new("icmp");

foreach $ip (@netips)
{
if ( $p->ping($ip) )
{
$ok = 1;
last;
}
else
{ print "DEBUG: IP " . $ip . " cannot be pinged<br>"; }
}

$p->close;

if ( ! $ok )
{
$encoded = encode_base64("$user:$pass");

$http = Net::HTTP->new(Host => $localip) || die $@;
$http->write_request(GET => $reset_url,
'Authorization' => $encoded);
$http->close;
}
----------------------

The best way to test this (to make sure that it will reboot your router)
is to comment out the line reading "if ( ! $ok )" (so add a # to the
beginning). That'll make everything within { } be executed, regardless
of whether the ping succeeded or not.

If it doesn't work as-in, then I'd imagine that we'll have to add a bit
of code to read the response from the server. But that's for another day :)

xF,

....Nick
 
W

wrreisen2

Thanks Nick and Harry,
I installed the MIME::Base64::perl module
I call the script http_pass.pl
I try running from the command line the script with the line "if ( !
$ok )" with a # in front of it.


C:\Inetpub\wwwroot\perl>perl http_pass.pl
Content-type: text/html

It comes back with command line.
I stare at the router lights whilst running the script and the RX Wan
light flashes on once. As it does that the Lan 1 light flashes off once
its on all the rest of the time The Power light stays on. Ready just
keeps on flashing all the time.

When I go in internet explorer to the router's interface and press
reboot router only. The router's WAN ADSL light goes out. Ready goes
out then ADSL and Ready start flashing together then the ADSL light
comes on all the time.

I guess that its not being rebooted with the script? When I try it in
IE it doesn't effect the lights on the router at all.
When I try it Firefox just the RX light flashes I think due to this
action.

I try unplugging the telephone cable from the router then running the
script:

C:\Inetpub\wwwroot\perl>perl http_pass.pl
Content-type: text/html

DEBUG: IP 4.68.116.98 cannot be pinged<br>DEBUG: IP 212.159.13.49
cannot be ping
ed<br>DEBUG: IP 212.159.13.50 cannot be pinged<br>DEBUG: IP 84.92.4.90
cannot be
pinged<br>DEBUG: IP 192.36.148.17 cannot be pinged<br>
C:\Inetpub\wwwroot\perl>perl http_pass.pl
Content-type: text/html

The script with the # infront of "if ( ! $ok )"

************************
#! /usr/bin/perl -w


use strict;
use Net::ping;
use Net::HTTP;


# Note the new addition :)
use MIME::Base64::perl;


# RFC1918 IP address of your router
my $localip = "10.0.0.2";


my @netips = ("4.68.116.98", "212.159.13.49", "212.159.13.50",
"84.92.4.90", "192.36.148.17" );
my $ip;
my $ok = 0;
my $encoded;
my $reset_url = "http://10.0.0.2/doc/doreboot.htm";
my $user="admin";
my $pass="epicrouter";


my $http; # HTTP socket
my $p; # ping socket


print "Content-type: text/html\n\n";


$p = Net::ping->new("icmp");


foreach $ip (@netips)
{
if ( $p->ping($ip) )
{
$ok = 1;
last;
}
else
{ print "DEBUG: IP " . $ip . " cannot be pinged<br>"; }



}


$p->close;

#if ( ! $ok )
{
$encoded = encode_base64("$user:$pass");


$http = Net::HTTP->new(Host => $localip) || die $@;
$http->write_request(GET => $reset_url,
'Authorization' => $encoded);
$http->close;


}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,734
Latest member
manin

Latest Threads

Top