Discussion:
get external ip from D-Link router
bob ackerman
2002-06-10 17:35:59 UTC
Permalink
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
is any module designed to find your external ip when you are on a lan?
router is admined from a web page, so i guess it is possible to using LWP
(or some other module?) to retrieve the info from the web page.
Kevin Meltzer
2002-06-10 18:18:19 UTC
Permalink
At home I do this with LWP on my Lynksys. Look at LWP::UserAgent and
LWP::Simple for the fetching, and HTML::Parser for the HTML parsing (or
just use a regular expression if you can).

Cheers,
Kevin
Post by bob ackerman
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
is any module designed to find your external ip when you are on a lan?
router is admined from a web page, so i guess it is possible to using LWP
(or some other module?) to retrieve the info from the web page.
--
[Writing CGI Applications with Perl - http://perlcgi-book.com]
Share the groove.
-- Phish (Weekapaug Groove)
drieux
2002-06-10 17:49:00 UTC
Permalink
Post by bob ackerman
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
I presume that your 'internal network' is an RFC1918 configuration?
All of whom are routing to the LAN side address of your Router???

{ are expecting your ISP to actually be handing you a 'real'
IP address that it is not itself NATing for you???? }
Post by bob ackerman
is any module designed to find your external ip when you are on a lan?
a part of the problem is getting a good definition of what 'external'
would mean here...
Post by bob ackerman
router is admined from a web page, so i guess it is possible to using LWP
(or some other module?) to retrieve the info from the web page.
I would recommend that you go at this from the webPage side on your LAN.
Since that would probably be simpler and easier to develop and maintain.

since if they have exposed their API it's reasonably simple - if they
have not, it would be reasonably simple to play around that with your
browser in one place, and your perl code in another window....



ciao
drieux

---
bob ackerman
2002-06-10 19:02:11 UTC
Permalink
Post by drieux
Post by bob ackerman
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
I presume that your 'internal network' is an RFC1918 configuration?
All of whom are routing to the LAN side address of your Router???
sounds right.
Post by drieux
{ are expecting your ISP to actually be handing you a 'real'
IP address that it is not itself NATing for you???? }
yes. it gives a real ip to the router. one that other's on the net can use
to access my box.
Post by drieux
Post by bob ackerman
is any module designed to find your external ip when you are on a lan?
a part of the problem is getting a good definition of what 'external'
would mean here...
again, i mean the real ip my isp gives to the router.
Post by drieux
Post by bob ackerman
router is admined from a web page, so i guess it is possible to using
LWP (or some other module?) to retrieve the info from the web page.
I would recommend that you go at this from the webPage side on your LAN.
Since that would probably be simpler and easier to develop and maintain.
other response suggested using LWP.
Post by drieux
since if they have exposed their API it's reasonably simple - if they
have not, it would be reasonably simple to play around that with your
browser in one place, and your perl code in another window....
perhaps the api is available. i have downloaded a python script
(ipcheck.py from source forge) that seems able to grovel the ip. i will
look into the script way and the LWP way and report back.
Post by drieux
ciao
drieux
adieu, drieux (now that's felicitous)
Geoffrey F. Green
2002-06-10 20:08:22 UTC
Permalink
Post by bob ackerman
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
is any module designed to find your external ip when you are on a lan?
router is admined from a web page, so i guess it is possible to using LWP
(or some other module?) to retrieve the info from the web page.
LWP's a good thought. A fellow named Jerry LeVan posted a script he used to
get the IP address from a Linksys router; I modified it somewhat to get the
IP address from my Macsense router. You can probably easily adapt it to
your own needs. Here's the relevant portion of the script:

#!/usr/bin/perl -w

use strict;
use LWP::UserAgent;

my $pattern = '<b>Public IP Address</td><td bgcolor=c3c3c3><font
face=verdana size=-1><b>(\d+\.\d+\.\d+\.\d+)</td>';

# Fetch the page

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.1.1/Status.htm');
$req->authorization_basic('admin', 'admin');
my $thePage = $ua->send_request($req);

if ($thePage->content =~ m|$pattern|os)
{ ## Do whatever you want with $1
}
else {
## Whoops!
}
Todd Wade
2002-06-11 00:26:41 UTC
Permalink
Post by bob ackerman
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
is any module designed to find your external ip when you are on a lan?
router is admined from a web page, so i guess it is possible to using LWP
(or some other module?) to retrieve the info from the web page.
I run a cron job on my internal network that sends a request every 10
minutes to a cgi program that sits on my public web server. The cgi program
does some authenticication, and then sticks the value of $ENV{REMOTE_HOST}
in a DB_File. This works because the router makes the request, so
$ENV{REMOTE_HOST} is populated with my router's dynamically assigned ip
address.

I then have a redirector cgi program that sits on my public web server that
redirects to my router. So http://my.public.site.com/redirector.cgi
redirects my browser to the router, which handles the port forwarding.

This way, I always have access to my current dynamic ip address. Unless, of
course, it changes and the cron job hasnt run ret, which has happened.

The other suggestions are just as good, but as always TMTOWTDI.

Todd W.
bob ackerman
2002-06-11 00:55:34 UTC
Permalink
Post by Todd Wade
Post by bob ackerman
my box is behind a D-Link router 704.
The router gets its ip from my isp using dhcp.
anyone know how to get that external ip from the router?
is any module designed to find your external ip when you are on a lan?
router is admined from a web page, so i guess it is possible to using LWP
(or some other module?) to retrieve the info from the web page.
I run a cron job on my internal network that sends a request every 10
minutes to a cgi program that sits on my public web server. The cgi program
does some authenticication, and then sticks the value of $ENV{REMOTE_HOST}
in a DB_File. This works because the router makes the request, so
$ENV{REMOTE_HOST} is populated with my router's dynamically assigned ip
address.
I then have a redirector cgi program that sits on my public web server that
redirects to my router. So http://my.public.site.com/redirector.cgi
redirects my browser to the router, which handles the port forwarding.
This way, I always have access to my current dynamic ip address. Unless, of
course, it changes and the cron job hasnt run ret, which has happened.
The other suggestions are just as good, but as always TMTOWTDI.
indeed. that is muy cleverly.
i may just try that.
i found ipcheck.py on source forge which works doing like so in python:
params = urllib.urlencode({'RC': '@D', 'ACCT' : "root", 'PSWD' : "71:29:
26", 'URL': 'admin' })
ipurl = "http://" + iphost + "/cgi-bin/logi"
urlfp = urllib.urlopen(ipurl, params)

i can't quite figure out how to do this in perl. i have:
use LWP::UserAgent;

# Fetch the page
$admin = ARGV[0]; #password
print $admin,"\n";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
$req->authorization_basic('', $admin); #not working
my $thePage = $ua->send_request($req);

but it doesn't seem to authenticate. i have tried various usernames: 'root'
, 'admin'. my logged in user name.
doesn't help.

so i will ask on python group what those params might mean.
Post by Todd Wade
Todd W.
drieux
2002-06-11 01:24:38 UTC
Permalink
Post by Geoffrey F. Green
HTTP::Request
# Fetch the page
$admin = ARGV[0]; #password
print $admin,"\n";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
$req->authorization_basic('', $admin); #not working
my $thePage = $ua->send_request($req);
but it doesn't seem to authenticate. i have tried various usernames: 'root'
, 'admin'. my logged in user name.
doesn't help.
that
authorization_basic($uname,$passwd)

I think will need to get a username stuffed into it,
and the passwd....

now the way i got around that was with the simple, to start with
case of running my 'own' little authenticator - see below for it

and nested that in the $ua

$ua->credentials($uri->host_port, $realm, $user, $pword)

and skipped the $req->auth... stuff...

So the solution is for you to resolve how you login to your
router - since that is the Username and Passwd that it is
going to be expecting to see...

I did this stuff in the function

dtk_cmd_page_parser

in

http://www.wetware.com/drieux/src/unix/perl/UglyCode.txt

ciao
drieux

---

this is how I did the basic authentication for myself at
the command line...

#-------------------------
# OK - so the perldoc says rip this off and use it
# so I did - it will get me the dope I need - you will need to
# have the libwww-perl release to have the specific piece of code
# but this is way cool. Clearly I should have implemented the GetOpt
# solution that would be cooler.

sub gbc {

my($realm, $uri) = @_;
# if ($main::options{'C'}) {
# return split(':', $main::options{'C'}, 2);
# } elsif (-t) {
if(-t) { # are we attached to a tty???
my $netloc = $uri->host_port;
print "Enter username for $realm at $netloc: ";
my $user = <STDIN>;
chomp($user);
return (undef, undef) unless length $user;
print "Password: ";
system("stty -echo");
my $password = <STDIN>;
system("stty echo");
print "\n"; # because we disabled echo
chomp($password);
return ($user, $password);
} else {
return (undef, undef)
}

} # end gbc - the get_basic_credentials
Geoffrey F. Green
2002-06-11 01:30:47 UTC
Permalink
Post by Geoffrey F. Green
# Fetch the page
$admin = ARGV[0]; #password
print $admin,"\n";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
$req->authorization_basic('', $admin); #not working
my $thePage = $ua->send_request($req);
but it doesn't seem to authenticate. i have tried various usernames: 'root'
, 'admin'. my logged in user name.
doesn't help.
Couple of things:

1) Are you sure the URI is correct?

2) When you log into the router administration page manually, using your web
browser, do you have to enter a username or password? Those should be the
values that you should enter using the script. If you don't need a username
or password, maybe the problem is that you're passing a password, and that's
screwing it up somehow.

3) FYI, the script I posted -- which seems to be what you modelled yours
after -- assumes that you're getting at the router from behind the router.
Stupid point, yes, and I'm sure you already know that, but I've gotten
tripped up making enough moronic mistakes that I feel obliged to point them
out.

- geoff
bob ackerman
2002-06-11 02:27:31 UTC
Permalink
Post by Geoffrey F. Green
Post by Geoffrey F. Green
# Fetch the page
$admin = ARGV[0]; #password
print $admin,"\n";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
$req->authorization_basic('', $admin); #not working
my $thePage = $ua->send_request($req);
but it doesn't seem to authenticate. i have tried various usernames: 'root'
, 'admin'. my logged in user name.
doesn't help.
1) Are you sure the URI is correct?
that's the problem. i don't know about the username. i login on the
webpage at 192.168.0.1
but there is no user name involved. just the password which i am using.
i do get a response, but not the status info:
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html;
charset=iso-8859-1"><SCRIPT LANGUAGE=JavaScript><!--
function GURL(x){var t=new Date(); location=x+'&ZT='+t.getTime();}
function makesure(p,l){if (confirm(p)) GURL(l);}
//--></SCRIPT></HEAD><BODY TEXT=#000000 BGCOLOR=#FFFFFF LINK=#006693 VLINK=
#006693 ALINK=#006693><SCRIPT LANGUAGE=JavaScript><!--
parent.menu.reload();
//--></SCRIPT></BODY></HTML>

the python code gets the info.
Post by Geoffrey F. Green
2) When you log into the router administration page manually, using your web
browser, do you have to enter a username or password? Those should be the
values that you should enter using the script. If you don't need a username
or password, maybe the problem is that you're passing a password, and that's
screwing it up somehow.
no username, but i do need a password which i am using.
and the python code seems to be sending a user name and password -
although what the password is i can't grok.
Post by Geoffrey F. Green
3) FYI, the script I posted -- which seems to be what you modelled yours
after -- assumes that you're getting at the router from behind the router.
Stupid point, yes, and I'm sure you already know that, but I've gotten
tripped up making enough moronic mistakes that I feel obliged to point them
out.
yes. i am behind the router.
Post by Geoffrey F. Green
- geoff
Todd Wade
2002-06-11 04:48:13 UTC
Permalink
Post by Geoffrey F. Green
use LWP::UserAgent;
# Fetch the page
$admin = ARGV[0]; #password
print $admin,"\n";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
The line above will work to fetch a document from a linksys BEFSR41 and the
like. Are you sure thats right for a D-Link router?

Todd W
bob ackerman
2002-06-11 02:29:40 UTC
Permalink
Post by Todd Wade
Post by Geoffrey F. Green
use LWP::UserAgent;
# Fetch the page
$admin = ARGV[0]; #password
print $admin,"\n";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
The line above will work to fetch a document from a linksys BEFSR41 and the
like. Are you sure thats right for a D-Link router?
note the ip was slightly different for linksys. it was 192.168.1.1.
above is the ip i use to manually login. the html file is what the python
code names to get the data correctly.
Post by Todd Wade
Todd W
drieux
2002-06-11 04:02:38 UTC
Permalink
Post by bob ackerman
note the ip was slightly different for linksys. it was 192.168.1.1.
above is the ip i use to manually login. the html file is what the python
code names to get the data correctly.
Silly question here - but could it be the case,
as with things like the sonic firewall - that one
actually needs to be doing HTTPS at the LAN side
IP address - so that one can pass the authentication
that way???? hence one needs to have taken the side
adventure into the underlying

IO::SOCKET::SSL

as is referenced in the libwww-perl-5.65 out as of may 31st, 2002 ???



ciao
drieux

---
bob ackerman
2002-06-11 06:26:34 UTC
Permalink
Post by drieux
Post by bob ackerman
note the ip was slightly different for linksys. it was 192.168.1.1.
above is the ip i use to manually login. the html file is what the
python code names to get the data correctly.
Silly question here - but could it be the case,
as with things like the sonic firewall - that one
actually needs to be doing HTTPS at the LAN side
IP address - so that one can pass the authentication
that way???? hence one needs to have taken the side
adventure into the underlying
IO::SOCKET::SSL
as is referenced in the libwww-perl-5.65 out as of may 31st, 2002 ???
nah. the python code works without it. none of the routers that ipcheck.py
handles needs ssl.
i certainly am not behind a firewall with respect to the router.
Post by drieux
ciao
drieux
Todd Wade
2002-06-12 05:55:24 UTC
Permalink
Post by bob ackerman
Post by Todd Wade
Post by bob ackerman
my $req = HTTP::Request->new(GET => 'http://192.168.0.1/status.htm');
The line above will work to fetch a document from a linksys BEFSR41 and the
like. Are you sure thats right for a D-Link router?
note the ip was slightly different for linksys. it was 192.168.1.1.
above is the ip i use to manually login. the html file is what the python
code names to get the data correctly.
Right, but is the document you are trying to get the ip from called
status.htm?

In another of your posts, you put:

params = urllib.urlencode({'RC': '@D','ACCT' : "root",'PSWD' :
"71:29:26",'URL': 'admin'})
ipurl = "http://" + iphost + "/cgi-bin/logi"
urlfp = urllib.urlopen(ipurl, params)

which looks like to me you are getting the ip address out of a document
called:

http://192.168.0.1/cgi-bin/logi

???

Todd W.
bob ackerman
2002-06-12 03:40:39 UTC
Permalink
Post by Todd Wade
Right, but is the document you are trying to get the ip from called
status.htm?
i have changed my strategy since then. the python posted to the /cgi-
bin/logi file first to login.
then called the status.htm to get data. again, i say, it works in python.
so i am trying to do the POST to login first, and it is failing. i'm
pretty sure i can get the data if i can login successfully.
Post by Todd Wade
"71:29:26",'URL': 'admin'})
ipurl = "http://" + iphost + "/cgi-bin/logi"
urlfp = urllib.urlopen(ipurl, params)
which looks like to me you are getting the ip address out of a document
http://192.168.0.1/cgi-bin/logi
no. that is the login file i am now trying to POST to:
use LWP::UserAgent;

my $ua = new LWP::UserAgent;
my $req = HTTP::Request->new(POST => 'http://192.168.0.1/cgi-bin/logi',
HTTP::Headers->new(), [RC => '@D', ACCT => 'root', PSWD => '71:29:26', URL
=>'admin']);
$r = $ua->request($req);
$r->is_success() ? print $r->content(),"\n" : print "Failed to login\n";

this is what is failing.
when i try this POST from the shell command line, i get:
echo 'RC=@D&ACCT="root"&PSWD="71:29:26"&URL="admin"' | POST -u -U -s -S -e
-x 'http://192.168.0.1/cgi-bin/logi'
LWP::UserAgent::new: ()
LWP::UserAgent::request: ()
LWP::UserAgent::send_request: POST http://192.168.0.1/cgi-bin/logi
LWP::UserAgent::_need_proxy: Not proxied
LWP::Protocol::http::request: ()
admin
LWP::UserAgent::request: Simple response: Internal Server Error
POST http://192.168.0.1/cgi-bin/logi
User-Agent: lwp-request/2.01
Content-Length: 46
Content-Type: application/x-www-form-urlencoded

POST http://192.168.0.1/cgi-bin/logi --> 500 EOF instead of reponse status
line
Post by Todd Wade
Todd W.
rda
drieux
2002-06-12 13:36:30 UTC
Permalink
On Tuesday, June 11, 2002, at 08:40 , bob ackerman wrote:
[..]
Post by bob ackerman
this is what is failing.
-e -x 'http://192.168.0.1/cgi-bin/logi'
[..]
Post by bob ackerman
LWP::UserAgent::request: Simple response: Internal Server Error
POST http://192.168.0.1/cgi-bin/logi
User-Agent: lwp-request/2.01
Content-Length: 46
Content-Type: application/x-www-form-urlencoded
POST http://192.168.0.1/cgi-bin/logi --> 500 EOF instead of reponse
status line
Woo Hoo!!!!

You force it to give up an internal server bug...

This you can actually send to the vendor and say,

"Uh, like Dude, I was trying to automate
around your web interface, and Like,
uh, why does your cgi-bin code here hurl a 500
error out???"

and pad a bit with the 'is this a security risk'...

be polite.

There could be the need to triple guard that @D
thingie with

'RC="\@D"....'

this way we make sure it got into the game safely


ciao
drieux

---

Loading...