By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,866 Members | 1,704 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,866 IT Pros & Developers. It's quick & easy.

Getting external IP address

P: n/a
I have a PC behind a firewall, and I'm trying to programmatically
determine the IP address visible from outside the firewall.

If I do this:
>>import socket
socket.gethostbyname(socket.gethostname())
'127.0.0.1'
>>socket.gethostbyname_ex(socket.gethostname())
('localhost.localdomain', ['localhost'], ['127.0.0.1'])

I get my internal IP address, which is not what I want.

Other tricks, like parsing the output of os.system('/sbin/ifconfig eth0')
also give me my internal IP address.

I found this post on comp.lang.python a few years ago:

http://mail.python.org/pipermail/pyt...ch/192495.html

which seems like it _should_ do what I want, but it doesn't: I get an
exception.
>>from httplib import HTTPConnection
from xml.dom.ext.reader.Sax import FromXmlStream
conn = HTTPConnection('xml.showmyip.com')
conn.request('GET', '/')
doc = FromXmlStream(conn.getresponse())
print doc.getElementsByTagName('ip')[0].firstChild.data
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/python2.4/UserList.py", line 28, in __getitem__
def __getitem__(self, i): return self.data[i]
IndexError: list index out of range
>>conn.close()
I don't know how to fix it so that it works.

Can anyone help me fix that code snippet, or suggest another (better) way
to get the externally visible IP address?
--
Steven D'Aprano

Mar 5 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Steven D'Aprano <st***@REMOVEME.cybersource.com.auwrote:
>
>>>from httplib import HTTPConnection
from xml.dom.ext.reader.Sax import FromXmlStream
conn = HTTPConnection('xml.showmyip.com')
conn.request('GET', '/')
doc = FromXmlStream(conn.getresponse())
print doc.getElementsByTagName('ip')[0].firstChild.data
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/python2.4/UserList.py", line 28, in __getitem__
def __getitem__(self, i): return self.data[i]
IndexError: list index out of range
>>>conn.close()

I don't know how to fix it so that it works.

Can anyone help me fix that code snippet, or suggest another (better)
way
to get the externally visible IP address?
Try running it interactively and looking at the data you receive:
>>conn = HTTPConnection('xml.showmyip.com')
conn.request('GET', '/')
>>resp = conn.getresponse()
print resp
<httplib.HTTPResponse instance at 0x00C58350>
>>data = resp.read()
print data
<html><head><title>Object moved</title></head><body>

<h2>Object moved to <a href="http://www.showmyip.com/xml/">here</a>.
</h2>

</body></html>
If you try connecting to 'www.showmyip.com' and requesting '/xml/' it
should work.
Mar 5 '07 #2

P: n/a
Duncan Booth <du**********@invalid.invalidwrites:
If you try connecting to 'www.showmyip.com' and requesting '/xml/' it
should work.
If the firewall is really obnoxious, it can bounce consecutive queries
around between multiple originating IP addresses. That is uncommon
but it's been done from time to time.
Mar 5 '07 #3

P: n/a
Paul Rubin <http://ph****@NOSPAM.invalidwrote:
Duncan Booth <du**********@invalid.invalidwrites:
>If you try connecting to 'www.showmyip.com' and requesting '/xml/' it
should work.

If the firewall is really obnoxious, it can bounce consecutive queries
around between multiple originating IP addresses. That is uncommon
but it's been done from time to time.
Yes, each connection through the firewall needs to have a unique
originating ip and port number. If there are too many machines inside the
firewall then you may need to allocate multiple ip addresses on the
outside. I would hope that in general a single internal IP should map to
one external IP at a time (otherwise you would have problems with ip based
session persistence connecting to load balanced systems), but you might
expect to bounce round different IPs after periods of inactivity.

Also you could have multiple levels of NAT in which case the question
becomes whether Steven wants the IP as seen from outside the immediate
firewall or outside the final one. Maybe he should be using IPv6 to avoid
all this?
Mar 5 '07 #4

P: n/a
On Mon, 05 Mar 2007 09:02:44 +0000, Duncan Booth wrote:
Try running it interactively and looking at the data you receive:
>>>conn = HTTPConnection('xml.showmyip.com')
conn.request('GET', '/')
>>>resp = conn.getresponse()
print resp
<httplib.HTTPResponse instance at 0x00C58350>
>>>data = resp.read()
print data
<html><head><title>Object moved</title></head><body>

<h2>Object moved to <a href="http://www.showmyip.com/xml/">here</a>.
</h2>

</body></html>
Ah! That's the clue I needed -- thanks.
If you try connecting to 'www.showmyip.com' and requesting '/xml/' it
should work.
Thank you muchly! That seems to do the trick.
--
Steven.

Mar 6 '07 #5

P: n/a
Steven D'Aprano <st***@REMOVEME.cybersource.com.auwrote:
>I have a PC behind a firewall, and I'm trying to programmatically
determine the IP address visible from outside the firewall.
[ ... ]
Can anyone help me fix that code snippet, or suggest another (better) way
to get the externally visible IP address?
Depending on your circumstances, it may be possible to just ask the
firewall. You'll probably need some kind of administrator login, and
may well have to parse HTML if it's only got a web interface, but it
does mean that you don't have to connect to anything in the outside
world.

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump
Mar 6 '07 #6

P: n/a
I have a PC behind a firewall, and I'm trying to programmatically
determine the IP address visible from outside the firewall.
....
Steven ....

Following is another alternative that might at least
be worth consideration ....

I use the lynx command shown as a command-line alias
under Debian linux ....
>>>
import os

pipe_in = os.popen( 'lynx --dump http://checkip.dyndns.org' )

ip_addr = pipe_in.readlines()

for this in ip_addr :
.... print this
....
Current IP Address: 65.39.92.38
--
Stanley C. Kitching
Human Being
Phoenix, Arizona
----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Mar 6 '07 #7

P: n/a
The above suggestions seem nice, but I find this one easier:

import urllib2
ext_ip = urllib2.urlopen('http://whatismyip.org/').read()
print ext_ip

The nice thing about the above code is that http://whatismyip.org/
only contains exactly what you want (the ip, nothing more, nothing
less), so no parsing is necessary

Best,
Sergio

On 3/6/07, Cousin Stanley <co***********@hotmail.comwrote:
>
I have a PC behind a firewall, and I'm trying to programmatically
determine the IP address visible from outside the firewall.
....

Steven ....

Following is another alternative that might at least
be worth consideration ....

I use the lynx command shown as a command-line alias
under Debian linux ....
>>
import os

pipe_in = os.popen( 'lynx --dump http://checkip.dyndns.org' )

ip_addr = pipe_in.readlines()

for this in ip_addr :
... print this
...
Current IP Address: 65.39.92.38
--
Stanley C. Kitching
Human Being
Phoenix, Arizona
----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
--
http://mail.python.org/mailman/listinfo/python-list
Mar 6 '07 #8

P: n/a
On Tue, 06 Mar 2007 14:40:37 -0500, Sergio Correia wrote:
The above suggestions seem nice, but I find this one easier:
[snip]
Thanks to everybody who replied, that's great.
--
Steven.

Mar 6 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.