#!/bin/sh exec ${PERL-perl} -Sx $0 ${1+"$@"} #!perl # ptr --- resolve IP addresses to host names # Author: Noah Friedman # Created: 2001-11-27 # Public domain # $Id: ptr,v 2.2 2001/11/27 08:34:41 friedman Exp $ # Commentary: # Usage: ptr 192.168.1.30 127.0.0.1 ... # or invoke with no arguments and feed addresses one per line on stdin. # IP addresses will be picked out of lines which have other cruft in them, # so the input format is not very important. # The command `adnshost', from the adns (asynchronous dns) package is required. # See http://www.chiark.greenend.org.uk/~ian/adns/ or ftp://ftp.gnu.org/adns/ # Code: use strict; use Symbol; sub ip2arpa ($) { local $_ = shift; s/^(\d+)\.(\d+)\.(\d+)\.(\d+)\n?/$4.$3.$2.$1.in-addr.arpa/o; return $_; } sub arpa2ip ($) { local $_ = shift; s/^(\d+)\.(\d+)\.(\d+)\.(\d+)\.in-addr\.arpa/$4.$3.$2.$1/io; return $_; } sub adns (@) { my @adns_cmd = ("adnshost", "--asynch", "--fmt-inline", "--pipe", "--type", "ptr", #"--tcp", ); my ($irh, $iwh, $orh, $owh) = (gensym, gensym, gensym, gensym); pipe ($irh, $iwh); pipe ($orh, $owh); my $pid = fork; if ($pid == 0) { open (STDIN, "<&=" . fileno ($irh)); open (STDOUT, ">&=" . fileno ($owh)); map { close ($_) } ($irh, $iwh, $orh, $owh); exec (@adns_cmd) || die "exec: $adns_cmd[0]: $!"; } else { close ($irh); close ($owh); print $iwh map { $_ . "\n" } @_; close ($iwh); my @result = <$orh>; wait; close ($orh); return \@result; } } sub parse_results ($) { my $data = shift; my %cname; my %result; for my $ent (@$data) { next if ($ent =~ /^;/o); my ($ip, $type, $name) = split (/\s+/o, $ent); if (uc ($type) eq "CNAME") { $cname{$name} = $ip; } else { $result{$ip} = $name; } } while (my ($canon, $alias) = each %cname) { next unless (exists $result{$canon}); $result{$alias} = $result{$canon}; delete $result{$canon}; } return \%result; } sub max { return [ sort { -($a <=> $b) } @_ ]->[0]; } sub main () { unless (@ARGV) { while () { push @ARGV, $1 while (m/(\d+\.\d+\.\d+\.\d+(?:\.in-addr\.arpa|))/igo); } } my $output = adns (map { ip2arpa ($_) } @ARGV); my $result = parse_results ($output); my $maxlen = max (map { length } @ARGV); my $fmt = sprintf "%%-%ds %%s\n", $maxlen; for my $ip (@ARGV) { printf $fmt, $ip, ($result->{ip2arpa ($ip)} || $result->{$ip} || ""); } } main (); # local variables: # mode: perl # eval: (auto-fill-mode 1) # end: # ptr ends here