2008-12-01 10 views
8

Czy istnieje czysty i niezależny od systemu operacyjnego sposób określania adresów IP lokalnej maszyny z Perla?Jak określić adresy IP komputerów lokalnych z Perla?

Do tej pory znaleziono następujące rozwiązania:

  • analizować dane wyjściowe ifconfig i ipconfig (twarde, różne wersje Windows mają różne wyjścia polecenia ipconfig)

  • ustanowić połączenie sieciowe do studni - znany adres IP i sprawdź lokalny adres IP gniazda (nie zadziała, jeśli nie uda się nawiązać połączenia i określi tylko jeden adres IP)

Jakieś lepsze sugestie?

+0

Magiczna liczba to 127.0.0.1 –

+2

To nie jest to, czego potrzebuję. Chcę wydrukować adresy IP urządzenia w niestandardowej formie, nie chcę używać adresów. – Zizzencs

Odpowiedz

15

Net::Address::IP::Local wygląda obiecująco.

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

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

+0

Wykonano niezależną wersję łącza ;-) –

+1

@ zizzencs Nie rozumiem, dlaczego zaakceptowałeś odpowiedź, gdy prosiłeś o * wszystkie * adresy IP urządzenia. Ta odpowiedź zwraca tylko jeden. – dolmen

0

korzystać z usługi WMI?

Example of extracting IP addresses (w PowerShell, ale jest to całkiem jasne, co się dzieje)

Example of accessing WMI from Perl (nie same funkcje WMI, ale znowu jest to proces dość oczywiste)

EDIT: po przeprowadzeniu wyszukiwania w Google codesearch dla Networkadapterconfiguration i język "Perl":

Example looks like pretty much what you need

EDIT2: W rzeczywistości kod OCS wydaje się zawierać kod dla większości platform, aby to zrobić , więc chociaż nie może istnieć żaden zestaw kodu, który to robi, możesz być w stanie ponownie wykorzystać swoje pomysły. Ale to GPL. Na przykład here's the Solaris code. Inne bity obejmują BSD, Linux, MacOS ...

+0

Wygląda obiecująco, ale WIKA afaik nie jest dostępny w większości systemów Linux. Oczywiście, możesz użyć OpenPegasusa, ale byłoby to trochę za duże dla tego problemu. – Zizzencs

+0

Nie, WMI nie byłoby. Wygląda na to, że być może trzeba włączyć system operacyjny i mieć inny kod. –

+0

Zrobię to, jeśli nic innego nie pomoże. Dziękuję za Twoją odpowiedź. – Zizzencs

13

Masz również pewną liczbę other options, łącznie z rozwiązaniem "nawiązania połączenia sieciowego z dobrze znanym adresem IP i sprawdzenia lokalnego adresu IP gniazda".

w tym przypadku (ustanawiający połączenia sieciowego) jednakże, że artykuł ten wskazuje, że:

nie ma czegoś takiego jak adres IP hosta.
Interfejsy sieciowe mają adresy IP, a nie hosty, a pojedynczy interfejs sieciowy może mieć wiele (wirtualnych) adresów IP. Podsystem trasowania systemu operacyjnego decyduje o tym, który interfejs sieciowy i adres IP są używane do łączenia się ze zdalnym komputerem.

Jeśli urządzenie ma tylko jeden zewnętrzny interfejs sieciowy, a ten interfejs ma tylko jeden adres IP, wówczas ten adres IP jest zwykle nazywany adresem urządzenia, ale jest to niedokładne.
Na przykład, jeśli urządzenie jest podłączone do sieci VPN za pośrednictwem wirtualnego interfejsu będzie używać adresu IP tego interfejsu, aby połączyć się z innym komputerem w sieci VPN, a nie zewnętrznego adresu IP

Wśród innych rozwiązań: Zastosowania "Sys::Hostname"
(działa jeśli Sys::Hostname wyjdzie z rozwiązywana hosta)

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

Te też są fajnymi rozwiązaniami, które nie będą działać we wszystkich przypadkach.Stworzę niestandardowe rozwiązanie łączące je, jeśli nie ma lepszego rozwiązania. Dzięki. – Zizzencs

1

miałem dobrego sukcesu z IO::Interface w środowisku Linux i Solaris, i myślę, że nawet pracował w systemie AIX, ale nie mogę sobie przypomnieć na pewno. Przeglądając witryny search.cpan.org, rt.cpan.org i ActiveState, wygląda na to, że IO :: Interface może mieć problemy z budowaniem w systemie Windows. Domyślam się, że jedynym sposobem sprawdzenia, czy jest dostępny, jest wyszukanie interfejsu io w PPM.

0

Net :: :: Adres IP :: Local działa dobrze, ale ponieważ oryginalny plakat prosi o wszystkich lokalnych adresów, myślę, że to jest lepsze:

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

To działało w porządku dla mnie z ActivePerl dla Windows XP.

13

W moim przypadku potrzebuję rozwiązania bez żadnych podstawowych zależności. Wpadłem na to po przestudiowaniu kod w Net :: Adres IP :: :: lokalny:

#!/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() powinien zwrócić ten sam ciąg jako Net::Address::IP::Local->public_ipv4.

W razie potrzeby można zmienić atrybut PeerAddr (w argumentach konstruktora dla IO :: Socket :: INET) na lokalny serwer DNS.

+0

-1 jako kopiowanie/wklejanie nie jest zalecanym sposobem pracy z Perl. – dolmen

+1

@dolmen Zgoda. Jeśli w ogóle mi to pomoże, napisany przeze mnie skrypt został wykorzystany jako zadanie cron, wdrożone w skrzynkach programistycznych, aby zachować aktywne rejestry DNS. Gdybym to powtórzył, zamiast tego rozważałabym [fatpacking] (https://metacpan.org/module/fatpack) Net :: Address :: IP :: Local w skrypcie. > = D –

+3

@dolmen Łatwe do -1. Tego typu rzeczy pomagają ludziom, którzy nie znają perla i po prostu chcą to zrobić. – pelesl

5

Aby pobrać adres IP wszystkich interfejsów, należy IO::Interface::Simple:

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

Jeżeli nie jesteś zainteresowany 127.0.0.1 (sprzężenia zwrotnego), można filtrować $_->is_loopback.

0

do okien używam

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

Pierwszą linię startu 0.0.0.0 to brama domyślna. Może jest wiele bramek. Przydatne są również linie zaczynające się od 255.255.255.255. netstat -r i wydruk trasy są takie same.

Może być przystosowany do OSX, Linux nie jest tak pomocny.

0

Użyłem kombinacji tych poleceń Linuksa, więc nie ma zależności od żadnego modułu perla.

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