perl networking

¿Cómo puedo determinar las direcciones IP de la máquina local desde Perl?



networking (11)

¿Existe una forma limpia y de OS independiente para determinar las direcciones IP de la máquina local de Perl?

Hasta ahora he encontrado las siguientes soluciones:

  • analizar la salida de ifconfig e ipconfig (duro, las diferentes versiones de Windows tienen diferentes salidas de ipconfig)

  • establecer una conexión de red a un IP conocido y examinar la dirección IP local del socket (no funcionará si no puedo establecer una conexión y determinaré solo una dirección IP)

¿Alguna mejor sugerencia?


En mi caso, necesito una solución sin dependencias no esenciales. Se me ocurrió esto después de estudiar el código en Net :: Address :: IP :: Local:

#!/usr/bin/env perl use strict; use warnings; use IO::Socket::INET; my $local_ip_address = get_local_ip_address(); print "$local_ip_address/n"; # This idea was stolen from Net::Address::IP::Local::connected_to() sub get_local_ip_address { my $socket = IO::Socket::INET->new( Proto => ''udp'', PeerAddr => ''198.41.0.4'', # a.root-servers.net PeerPort => ''53'', # DNS ); # A side-effect of making a socket connection is that our IP address # is available from the ''sockhost'' method my $local_ip_address = $socket->sockhost; return $local_ip_address; }

get_local_ip_address() debería devolver la misma cadena que Net::Address::IP::Local->public_ipv4 .

Si lo desea, puede cambiar el atributo PeerAddr (en los argumentos del constructor para IO :: Socket :: INET) a un servidor DNS local.


Net :: Address :: IP :: Local funciona bien, pero como el cartel original pide todas las direcciones locales, creo que esta es mejor:

http://www.perlmonks.org/?node_id=166951

Funcionó bien para mí con ActivePerl para Windows XP.


He tenido éxito con IO :: Interface en Linux y Solaris, y creo que incluso funcionó en AIX, pero no puedo recordarlo con certeza. Al buscar en los sitios search.cpan.org, rt.cpan.org y ActiveState, parece que IO :: Interface puede estar experimentando problemas de compilación en Windows. Supongo que la única forma de saber si está disponible es buscar io-interface en PPM.


También tiene otras opciones , incluida la solución para "establecer una conexión de red a una IP conocida y examinar la dirección IP local del zócalo".

En ese caso (establecer conexión de red) sin embargo, ese artículo señala que:

no existe la dirección IP del host.
Las interfaces de red tienen direcciones IP, no hosts, y una única interfaz de red puede tener muchas direcciones IP (virtuales). El subsistema de enrutamiento del sistema operativo decide qué interfaz de red y dirección IP usar para conectarse a una máquina remota.

Si su máquina solo tiene una interfaz de red externa, y esta interfaz solo tiene una dirección IP, esta dirección IP se conoce comúnmente como la dirección de la máquina, pero eso es inexacto.
Por ejemplo, si la máquina está conectada a una VPN a través de una interfaz virtual, usará la dirección IP de esta interfaz para conectarse a otra máquina en la VPN, no a la dirección IP externa.

Entre las otras soluciones: usa " Sys::Hostname "
(Funciona si Sys::Hostname aparece con un nombre de host resoluble)

use Sys::Hostname; use Socket; my($addr)=inet_ntoa((gethostbyname(hostname))[4]); print "$addr/n";


usar WMI?

Ejemplo de extracción de direcciones IP (en Powershell, pero está bastante claro lo que está sucediendo)

Ejemplo de acceso a WMI desde Perl (no las mismas funciones de WMI, pero de nuevo el proceso es razonablemente claro)

EDITAR: después de una búsqueda en Google codesearch para la configuración de Networkadapter y el idioma "perl":

El ejemplo parece más o menos lo que necesitas

EDIT2: De hecho, el código OCS parece contener código para que la mayoría de las plataformas lo haga, por lo que, aunque tal vez no haya un solo conjunto de códigos que haga esto, es posible que pueda volver a utilizar sus ideas. Sin embargo, es GPL.

Por ejemplo, aquí está el código de Solaris . Otros bits cubren BSD, Linux, MacOS ...



Net :: Address :: IP :: Local parece prometedor.

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;


Para recuperar la dirección IP de todas las interfaces, use IO :: Interface :: Simple :

perl -MIO::Interface::Simple ''-Esay $_->address for grep { $_->is_running && defined $_->address } IO::Interface::Simple->interfaces''

Si no está interesado en 127.0.0.1 (loopback), puede filtrar en $_->is_loopback .



para ventanas que uso

foreach (split(//r?/n/,`netstat -r`)) { next unless /^/s+0.0.0.0/; @S = split(//s+/); # $S[3] = Default Gateway # $S[4] = Main IP }

La primera línea que comienza 0.0.0.0 es la puerta de enlace predeterminada. Puede haber varias puertas de enlace. Las líneas que comienzan en 255.255.255.255 también son útiles. netstat -r y la impresión de ruta son lo mismo.

Se puede adaptar para OSX, Linux no es tan útil.


He usado una combinación de estos comandos de Linux para que no haya dependencia en ningún módulo de Perl.

hostname -i hostname -I ls /sys/class/net ip -f inet addr show eth0| grep -Po ''inet /K[/d.]+''