Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear enlightened ones I have a code that summarises log files and returns a summary with the relevant ip addresses and their frequency. The code looks like this:
#!/usr/local/bin/perl # # ACLlogscan.pl -- a script to summarise ACL log files # # Set behaviour $log="H:/sys075/acls/local7.log"; # absolute path of ACL log file $ntop=40; # shows the top ten results(number can be cha +nged i.e.if # the number # is changed to 20 then you would see the top 20 r +esults) chomp ($acl=$ARGV[0]); # User can enter a specific acl numb +er if ($acl == "") { $acl=".*"}; # if nothing is entered then open(LOG , "<$log") or die; # open the log file stated in the b +ehaviour set while (<LOG>) { if (/IPACCESSLOGP: list $acl denied ([tcpudim]+) ([0-9.]+)\(([0-9]+)\ +) -> ([0-9.]+)\(([0-9]+)\), ([0-9]+) /) { # pattern ma +tching line $x=$6; $srca{$2}+=$x; $foo=sprintf("%16s -> %16s %3s port %-6s",$2,$4,$1,$5); $moo=sprintf("%3s port %-6s",$1,$5); $quad{$foo}+=$x; $port{$moo}+=$x; } } $n=0; printf ("Connection Summary:\n"); foreach $i (sort { $quad{$b} <=> $quad{$a} } keys %quad) { if ($n++ >= $ntop) { last }; printf ("%6s:%s\n", $quad{$i},$i); }
My question is this, Currently the out put is only ip numbers. I want to add another part to the script that shows the connections by their dns name. How would i go about doin this. I was thinkin it would be another foreach loop and doing an nslookup( i dont know the perl code for that) on each element. Any help or suggestions would be greatly appreciated. thanks, a perl newbie

Replies are listed 'Best First'.
Re: Adding an nslookup to a log script
by ikegami (Patriarch) on Dec 20, 2004 at 17:02 UTC

    I've never used it, but Net::Nslookup seems to do what you want.

    my $name = nslookup(host => $ip, type => "PTR") || $ip;

    I'd like to make three suggestions:

    1) Cache the results of your queries so you do lookup the same IP addresses over and over again. This will greatly improve your script's performance.

    if (!$name_cache{$ip}) { $name_cache{$ip} = nslookup(host => $ip, type => "PTR") || $ip; } my $name = $name_cache{$ip};

    2) You may want to insert a slight pause between lookups to give the DNS server a chance to breath. I don't know the proper etiquette in this situation.

    3) You may want to make the reverse lookup optional. It can put a fair load on the DNS server, and it can slow down your program greatly.

Re: Adding an nslookup to a log script
by NetWallah (Canon) on Dec 20, 2004 at 16:59 UTC
    Use Net::DNS.

    An example from the doc:

    use Net::DNS; my $res = Net::DNS::Resolver->new; my $query = $res->search("host.example.com"); if ($query) { foreach my $rr ($query->answer) { next unless $rr->type eq "A"; print $rr->address, "\n"; } } else { warn "query failed: ", $res->errorstring, "\n"; }

        ..."I don't know what the facts are but somebody's certainly going to sit down with him and find out what he knows that they may not know, and make sure he knows what they know that he may not know, and that's a good thing. I think it's a very constructive exchange," --Donald Rumsfeld

Re: Adding an nslookup to a log script
by borisz (Canon) on Dec 20, 2004 at 17:06 UTC
    Here is one way to get the name.
    use Socket; my $iaddr = inet_aton('64.236.172.30'); my $name = gethostbyaddr($iaddr, AF_INET); print $name;
    read perldoc -f gethostbyaddr
    Boris
Re: Adding an nslookup to a log script
by bgreenlee (Friar) on Dec 20, 2004 at 17:04 UTC
    use Socket; my $hostname = gethostbyaddr(inet_aton($ipaddr),AF_INET);

    -b

Re: Adding an nslookup to a log script
by Fletch (Bishop) on Dec 20, 2004 at 18:33 UTC

    An aside on efficiency whichever of the above approaches you take: you'll probably want to cache results (either manually with a hash or by using something like Memoize) to cut down on the DNS traffic you generate and to reduce the running time to get results out (e.g. if you save the results externally in a DBM file with Memoize the next time you run it'll only need to lookup new addresses seen since the last run).

Re: Adding an nslookup to a log script
by Random_Walk (Prior) on Dec 20, 2004 at 17:15 UTC

    Have a look at gethostbyaddr. This will take the address you want to look up as a packed binary representation. If @addr contains your four parts then I think $packed_addr=pack('C4', @addr) will get you the version you need. It also needs the address type, that is 4 for TCP/IP. It returns an array, the first element of which is what you want. Here is a one liner that should get your started, just feed it dotted format IPs on STDIN.

    perl -ple'chomp;@add=split/\./;$pkd=pack('C4',@add);($name)=(gethostby +addr $pkd,4);$_.=" > $name"'

    As for looping again, why not do the address lookup when you are in the output loop ?

    Cheers,
    R.