2008-12-01 2 views
8

Есть ли чистый и независимый от ОС способ определения IP-адресов локального компьютера с Perl?Как определить IP-адреса локального компьютера с Perl?

До сих пор я нашел следующие решения:

  • анализирующего вывод IFCONFIG и Ipconfig (жесткую, различные версии окна имеют различные IpConfig выходов)

  • установить сетевое соединение с хорошо -known IP и проверить локальный IP-адрес сокета (не будет работать, если я не смогу установить соединение и определю только один IP-адрес)

Любое лучшее предложение?

+0

Магическое число 127.0.0.1 – 2008-12-01 10:29:11

+2

Это не то, что мне нужно. Я просто хочу распечатать IP-адреса машины в настраиваемой форме, я не хочу использовать адреса. – Zizzencs 2008-12-01 10:32:17

ответ

15

Net::Address::IP::Local выглядит многообещающим.

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

использовать WMI?

Example of extracting IP addresses (в Powershell, но это довольно ясно, что происходит)

Example of accessing WMI from Perl (не одни и те же функции WMI, но опять-таки процесс достаточно ясно)

EDIT: после поиска на Google codesearch для Networkadapterconfiguration и язык «Perl»:

Example looks like pretty much what you need

EDIT2: на самом деле код OCS, кажется, содержит код для большинства платформ, чтобы сделать это , поэтому, хотя не может быть ни одного набора кода, который сделает это, вы сможете повторно использовать свои идеи. Это GPL'd.

Например, here's the Solaris code. Другие биты охватывают BSD, Linux, MacOS ...

+0

Выглядит многообещающе, но afaik WMI недоступен в большинстве Linux-систем. Конечно, вы можете использовать OpenPegasus, но это было бы слишком большим для этой проблемы. – Zizzencs 2008-12-01 10:46:18

+0

Нет, WMI не будет. Похоже, вам может потребоваться включить тип ОС и иметь другой код. – 2008-12-01 10:50:10

+0

Я сделаю это, если ничего не поможет. Спасибо за ваш ответ. – Zizzencs 2008-12-01 11:04:25

13

У вас также есть other options, включая ваше решение «установить сетевое соединение с известным IP-адресом и изучить локальный IP-адрес сокета».

В этом случае (установление сетевого соединения), однако, что статья указывает на то, что:

нет такой вещи, как IP-адреса хоста.
Сетевые интерфейсы имеют IP-адреса, а не хосты, а один сетевой интерфейс может иметь множество (виртуальных) IP-адресов. Подсистема маршрутизации операционной системы решает, какой сетевой интерфейс и IP-адрес использовать для подключения к удаленному компьютеру.

Если ваш компьютер имеет только один внешний сетевой интерфейс, и этот интерфейс имеет только один IP-адрес, этот IP-адрес обычно называется адресом компьютера, но это неточно.
Например, если аппарат подключен к виртуальной частной сети через виртуальный интерфейс будет использовать IP-адрес этого интерфейса для подключения к другому компьютеру по VPN, а не внешний IP-адрес

Среди других решений: использование "Sys::Hostname"
(работы, если Sys::Hostname придумывает разрешимый хост)

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

Я имел хороший успех с IO::Interface на Linux и Solaris, и я думаю, что он даже работал на AIX, но я не могу вспомнить точно. Находясь на сайтах search.cpan.org, rt.cpan.org и ActiveState, похоже, что в IO :: Interface могут возникать проблемы с сборкой в ​​Windows. Я предполагаю, что единственный способ узнать, доступен ли он, - это поиск io-интерфейса в PPM.

2

Perldoc имеет answer to this question in its FAQ («perlfaq9») - с использованием различных модулей (которые являются частью стандартной библиотеки) или даже встроенной функции.

0

Net :: Адрес :: IP :: Local работает нормально, но так как оригинальный плакат просит для всех локальных адресов, я думаю, что это один лучше:

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

Он работал хорошо для меня с ActivePerl для Windows XP.

13

В моем случае мне нужно решение без каких-либо неосновных зависимостей. Я пришел с этим после изучения кода в Net :: Адрес :: 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() должен возвращать ту же строку, Net::Address::IP::Local->public_ipv4.

При желании вы можете изменить атрибут PeerAddr (в аргументах конструктора для IO :: Socket :: INET) на локальный DNS-сервер.

5

Чтобы получить IP-адрес всех интерфейсов, используйте IO::Interface::Simple:

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

Если вы не заинтересованы в 127.0.0.1 (шлейф) можно фильтровать по $_->is_loopback.

0

для окон я использую

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

Первая строка запуска 0.0.0.0 является шлюз по умолчанию. Там может быть несколько шлюзов. Строки, начинающиеся с 255.255.255.255, также полезны. netstat -r и печать маршрута одинаковы.

Может быть адаптирован для OSX, Linux не очень полезен.

0

Я использовал комбинацию этих команд Linux, поэтому никакой зависимости от какого-либо модуля perl не было.

hostname -i 
hostname -I 
ls /sys/class/net 
ip -f inet addr show eth0| grep -Po 'inet \K[\d.]+' 
Смежные вопросы