Получение всех имен хостов с IP-адреса в Perl - PullRequest
2 голосов
/ 16 апреля 2011

Я пытаюсь найти способ получить все имена хостов, которые разрешаются в IP-адрес.

Функция gethostbyaddr, по-видимому, извлекает только первую запись из DNS (независимо от того, находится ли она в скалярном или списочном контексте).

Пример:

my $hostname = gethostbyaddr(inet_aton($ip_to_check), AF_INET);
$print($hostname); //output: joe.example.com

my @hostnames = gethostbyaddr(inet_aton($ip_to_check), AF_INET);
foreach my $hostname (@hostnames){
 print "(", join(',',@hostnames), ")"; //output: (joe.example.com,,2,4,?)
}

С терминала:

$ host 192.168.1.5
5.1.168.192.in-addr.arpa domain name pointer joe.example.com.
5.1.168.192.in-addr.arpa domain name pointer john.example.com.

Я слышал, что Net :: DNS немного более устойчив, но у меня нетНе повезло, что это тоже потянуло все записи.

Ответы [ 5 ]

3 голосов
/ 18 апреля 2011

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

# create new Resolver Object
my $res = Net::DNS::Resolver->new;

# change IP from 192.168.1.15 to 15.1.168.192.in-addr.arpa for searching
my $target_IP = join('.', reverse split(/\./, $ip_to_check)).".in-addr.arpa";

# query DNS
my $query = $res->query("$target_IP", "PTR");

# if a result is found
if ($query){
    print("Resolves to:\n");

    # for every result, print the IP address
    foreach my $rr ($query->answer){
        # show all unless the type is PTR (pointer to a canonical name)
        next unless $rr->type eq "PTR";

        # remove the period at the end
        printf(substr($rr->rdatastr, 0, -1));
    }
}
2 голосов
/ 16 апреля 2011

Интерфейс gethostby... довольно старый и неуклюжий, определяемый еще в первобытные времена, до того, как Perl получил ссылки и претензии к OO. И это не работает так, как вы пытаетесь его использовать. При использовании в контексте списка он возвращает первичное имя в качестве первого элемента и разделенный пробелами (!) Список псевдонимов в качестве второго:

my ($hostname, $aliases) = gethostbyaddr($addr, AF_INET);
my @hostname = ($hostname, split ' ', $aliases);
say join ' ', @hostname;

Теперь это теория; Я не обнаружил ни одного IP-адреса с несколькими записями PTR, поэтому не могу проверить, действительно ли gethostbyaddr их вернет - это, вероятно, также зависит от вашего базового времени выполнения C - но это работает, если вы используете gethostbyname с именем CNAME d, например.

2 голосов
/ 17 апреля 2011

Вот небольшая программа, которую я использую для поиска всех записей PTR для маски сети (например, 192.0.2.0/28) при выполнении задач отслеживания злоупотреблений.Он отправляет до 15 запросов в секунду, а когда все они отправляются, затем начинает читать ответы (поэтому для правильной работы больших сетевых блоков потребуется небольшая работа).

#!/usr/bin/env perl
use strict;
use warnings;

use Net::Netmask;
use Net::DNS;

@ARGV or die "$0 ip/cidr\n";

my $block = Net::Netmask->new(shift);

my $res = Net::DNS::Resolver->new;

my %sockets;

my $i = 0;
for my $i (1 .. $block->size - 1) {
    my $ip = $block->nth($i);

    my $reverse_ip = join ".", reverse split m/\./, $ip;
    $reverse_ip .= ".in-addr.arpa";

    #print "$ip\n";

    my $bgsock = $res->bgsend($reverse_ip, 'PTR');
    $sockets{$ip} = $bgsock;

    sleep 1 unless $i % 15;
}

$i = 0;
for my $i (1 .. $block->size - 1) {

    my $ip = $block->nth($i);

    my $socket = $sockets{$ip};
    my $wait   = 0;
    until ($res->bgisready($socket)) {
        print "waiting for $ip\n" if $wait > 0;
        sleep 1 + $wait;
        $wait++;
    }
    my $packet = $res->bgread($socket);
    my @rr     = $packet->answer;

    printf "%-15s %s\n", $ip, $res->errorstring
      unless @rr;

    for my $rr (@rr) {
        printf "%-15s %s\n", $ip, $rr->string;
    }
}
1 голос
/ 08 марта 2012

Я не думаю, что это правильно сформулированная проблема.В общем случае существует почти бесконечное количество DNS-имен, которые могут преобразовываться в любой IP-адрес, даже неизвестный стороне, владеющей этим адресом.Обратный поиск принципиально ненадежен и не способен ответить на вопрос, который хотел бы представить плакат, поскольку все имена для IP не обязательно должны быть в видимой обратной карте.

Первый ответ, который перечисляетобратная карта - лучшее, что можно сделать, но при этом будут пропущены любые имена, которые не были введены на карте.

0 голосов
/ 16 апреля 2011

Это то, что я использовал:

sub getauthoritivename
    {
    my ($printerdns)=@_;
    my $res = Net::DNS::Resolver->new(searchlist=>$config->{searchlist});

    my $query = $res->search($printerdns);
    if ($query) 
        {
        foreach my $rr ($query->answer) 
            {
            next unless $rr->type eq "A";
            print $rr->name;
            }
        } 
    else
        {
        warn "query failed: ", $res->errorstring, "\n";
        return 0;
        }
    }

Пока $ rr-> name находит имена, оно продолжает их добавлять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...