views:

2051

answers:

5

Is there a clean and OS independent way to determine the local machine's IP addresses from Perl?

So far I have found the following solutions:

  • parse the output of ifconfig and ipconfig (hard, different windows versions have different ipconfig outputs)

  • establish a network connection to a well-known IP and examine the socket's local IP address (won't work if I can't establish a connection and will determine only one IP address)

Any better suggestion?

A: 

Hi,

various methods to retrieve the host's IP address:

http://www.geekuprising.com/get_your_ip_address_with_perl

0xA3
Neither of these methods work when:- you don't know the machine's hostname- /etc/hosts or its equivalent is misconfigured- DNS resolving is not working- network cable is unpuggedI need a better soltuion if possible.
Zizzencs
Zizzencs, if your network cable is unplugged, you have practically no IP address and no way of determining if a given IP address might be already in use or not.
kixx
A: 

use WMI?

Example of extracting IP addresses (in Powershell, but it's pretty clear what's happening)

Example of accessing WMI from Perl (not the same WMI functions, but again the process is reasonably clear)

EDIT: after a search on Google codesearch for Networkadapterconfiguration and language "perl":

Example looks like pretty much what you need

EDIT2: In fact the OCS code seems to contain code for most platforms to do this, so while there may be no one set of code that does this, you may be able to re-use their ideas. It's GPL'd, though.

For example, here's the Solaris code. Other bits cover BSD, Linux, MacOS...

Paul
Looks promising, but afaik WMI is not available on most linux systems. Sure you can use OpenPegasus, but that would be a little bit too big for this problem.
Zizzencs
No, WMI wouldn't be. Looks like you may need to switch on OS type and have different code.
Paul
I will do that if nothing else helps. Thank you for your answer.
Zizzencs
+4  A: 

You also have some other options, including your solution to "establish a network connection to a well-known IP and examine the socket's local IP address".

In that case (establishing network connection) however, that article points out that:

there is no such thing as a host's IP address.
Network interfaces have IP addresses, not hosts, and a single network interface can have many (virtual) IP addresses. The operating system's routing subsystem decides which network interface and IP address to use to connect to a remote machine.

If your machine only has one external network interface, and this interface only has one IP address then this IP address is commonly called the machine's address, but that is inaccurate.
For example, if the machine is connected to a VPN via a virtual interface it will use this interface's IP address to connect to another machine on the VPN, not the external IP address

Amongst the other solutions: uses "Sys::Hostname"
(Works if Sys::Hostname comes up with a resolvable hostname)

use Sys::Hostname;
use Socket;
my($addr)=inet_ntoa((gethostbyname(hostname))[4]);
print "$addr\n";
VonC
These too are nice solutions that won't work in all cases. I will create a custom solution combining these if there's not a better solution. Thanks.
Zizzencs
+7  A: 

Net::Address::IP::Local looks promising.

use Net::Address::IP::Local;

# Get the local system's IP address that is "en route" to "the internet":
my $address      = Net::Address::IP::Local->public;
Leon Timmermans
+1  A: 

I've had good success with IO::Interface on Linux and Solaris, and I think it even worked on AIX but I can't recall for sure. Poking around on search.cpan.org, rt.cpan.org and ActiveState's various sites, it looks like IO::Interface may be experiencing build problems on Windows. I guess the only way to know if it's available is to search for io-interface in PPM.

converter42