Ottenere tutti i nomi degli host dell’indirizzo IP in Perl

Sto cercando di trovare un modo per ottenere tutti i nomi degli host, che consente di risolvere un indirizzo IP.

La funzione gethostbyaddr sembra recuperare solo il primo record DNS (non importa se si tratta di scalare o un elenco di contesto).

Esempio:

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,?)
}

Da terminale:

$ 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.

Ho sentito che Net::DNS è un po ‘ più robusto, ma non ho avuto fortuna che a tirare tutte le voci.

InformationsquelleAutor arcdegree | 2011-04-15

 

5 Replies
  1. 3

    Ho usato una combinazione di risposte date qui e altrove su stack overflow di trovare la risposta che stavo cercando.

    # 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. 2

    Il gethostby... interfaccia è abbastanza vecchio e goffo, in corso di definizione indietro nei tempi primordiali prima Perl ricevuto referenze e pretese di OO. E non funziona il modo in cui si sta tentando di utilizzare. Quando utilizzato in elenco contesto, restituisce il nome primario come primo elemento e separato da spazio(!) elenco di alias il secondo:

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

    Ora in teoria io non individuare eventuali indirizzi IP con più record PTR lì per lì, quindi non posso verificare se gethostbyaddr restituirà loro-probabilmente dipende dal sottostante di runtime C, come pure-ma funziona se si utilizza gethostbyname con un CNAMEd nome, per esempio.

    • Grazie per l’aiuto, ma non ho potuto ottenere questo per restituire più di un nome di dominio. Scommetto che questo è perché la funzione gethostbyaddr è semplicemente obsoleto e non è inteso per l’uso che stavo cercando.
    • Ho subito cercato su google una versione del codice sorgente per la risposta DNS di analisi che il vecchio utilizzare librerie C — e si scopre che, quando alla ricerca di un indirizzo IP si ferma semplicemente al primo PTR record di risorsa. Probabilmente funziona solo come progettato, in quanto la presenza di più PTR record non è raccomandato. Indietro nel giorno, c’era un concetto di ‘canonica’ il nome di un host che il PTR il record sarebbe punto. Ma un altro motivo per non farlo è esattamente libreria C, sceglie uno a caso, dare risultati imprevedibili. Questo è il modo in cui il mondo è, si arriva a decidere se ti piace.
    • Bel commento, grazie per il chiarimento.
  3. 2

    Ecco un piccolo programma che uso per la ricerca di tutti i record PTR per una maschera di rete (per esempio 192.0.2.0/28 ) quando si fa un abuso di compiti di monitoraggio. Invia fino a 15 query di un secondo e quando sono tutti inviati inizia a leggere le risposte (e che quindi avrei bisogno di un po ‘ di lavoro per funzionare correttamente e per i più grandi blocchi di rete).

    #!/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;
        }
    }
    • Grazie per il vostro aiuto, ho usato parti di script, in risposta alla domanda.
  4. 1

    Non credo che questo è ben formata problema economico. Nel caso generale, c’è un numero pressoché infinito di nomi DNS in grado di risolvere qualsiasi indirizzo IP, anche se sconosciuti, per la parte che contiene l’indirizzo. Reverse-le ricerche sono fondamentalmente inaffidabile, e non sono in grado di rispondere alla domanda poster perchè tutti i nomi per un IP non è necessario essere visibile inversione di mappa.

    La prima risposta, che enumera inverso mappa, è il meglio che si può fare, ma non mancheranno i nomi che non sono stati inseriti nella mappa.

  5. 0

    Questo è quello che ho usato:

    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;
            }
        }

    Fintanto che $rr->nome, trova nome, si mantiene l’aggiunta di loro.

    • Non so se mi segui. Da dove viene “listaricerca=>$config->{listaricerca}” vieni?

Lascia un commento