2008-12-01 13 views
8

¿Existe una manera limpia y de OS independiente para determinar las direcciones IP de la máquina local de Perl?¿Cómo puedo determinar las direcciones IP de la máquina local desde Perl?

Hasta ahora he encontrado las siguientes soluciones:

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

  • establecer una conexión de red a un pozo -conocido IP 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?

+0

El número mágico es 127.0.0.1 –

+2

Eso no es lo que necesito. Solo quiero imprimir las direcciones IP de la máquina en forma personalizada, no quiero usar las direcciones. – Zizzencs

Respuesta

15

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; 
+0

nuevo enlace http://search.cpan.org/~jmehnle/Net-Address-IP-Local-0.1.2/lib/Net/Address/IP/Local.pm –

+0

Hizo la versión de enlace independiente ;-) –

+1

@ zizzencs No entiendo por qué aceptó la respuesta ya que pidió * todas * las direcciones IP de la máquina. Esta respuesta devuelve solo uno. – dolmen

0

usar WMI?

Example of extracting IP addresses (en Powershell, pero está bastante claro lo que está pasando)

Example of accessing WMI from Perl (no las mismas funciones de WMI, pero de nuevo el proceso es razonablemente claro)

EDIT: después de una búsqueda en Google CodeSearch para Networkadapterconfiguration y el lenguaje "perl":

Example looks like pretty much what you need

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

Por ejemplo, here's the Solaris code. Otros bits cubren BSD, Linux, MacOS ...

+0

Parece prometedor, pero afaik WMI no está disponible en la mayoría de los sistemas Linux. Claro que puedes usar OpenPegasus, pero eso sería un poco demasiado grande para este problema. – Zizzencs

+0

No, WMI no lo sería. Parece que debe activar el tipo de sistema operativo y tener un código diferente. –

+0

Haré eso si nada más ayuda. Gracias por su respuesta. – Zizzencs

13

También tiene algunos other options, 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 (el establecimiento de la conexión de red) caso, sin embargo, dicho artículo señala que:

no hay tal cosa como la dirección IP de un 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 que utilizará la dirección IP de esta interfaz para conectarse a otra máquina en la VPN, no la dirección de IP externa

Entre las otras soluciones: usos "Sys::Hostname"
(Obras Sys::Hostname si se le ocurre un nombre de host resoluble)

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

Estas también son buenas soluciones que no funcionarán en todos los casos.Crearé una solución personalizada que combine estos si no hay una mejor solución. Gracias. – Zizzencs

1

He tenido buen éxito con IO::Interface en Linux y Solaris, y creo que incluso trabajó en AIX, pero no puedo recordar a ciencia cierta. 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.

0

Net :: Dirección :: :: IP local funciona bien, pero dado que el creador original se debe detallar todas las direcciones locales, creo que éste es mejor:

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

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

13

En mi caso, necesito una solución sin dependencias que no sean centrales. Se me ocurrió esto después de estudiar el código de Net :: Dirección :: :: 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() debe 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.

+0

-1 como copiar/pegar no es la forma recomendada de desarrollar con Perl. – dolmen

+1

@dolmen De acuerdo. Si esto ayuda en mi caso, la secuencia de comandos que escribí se usó como una tarea cron, desplegada en cajas de desarrollo para mantener activos los registros DNS. Si volví a visitarlo, consideraría [el empaquetado de documentos] (https://metacpan.org/module/fatpack) Net :: Address :: IP :: Local en el script en su lugar. > = D –

+3

@dolmen Fácil en el -1. Este tipo de cosas ayudan a las personas que no están familiarizadas con perl y solo quieren hacerlo. – pelesl

5

para recuperar la dirección IP de todos los las interfaces, utilice 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 (bucle de retorno) se puede filtrar en $_->is_loopback.

0

para las ventanas que utilizan

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 de salida 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.

0

He utilizado una combinación de estos comandos de Linux para que no dependa de 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.]+' 
Cuestiones relacionadas