1#!/usr/bin/perl 2 3# loclist.pl -- check a list of hostnames for LOC records 4 5# -v -- verbose output (include NO results). used to be the default 6# -n -- try looking for network LOC records as well (slower) 7# -r -- try doing reverse-resolution on IP-appearing hosts 8# -d -- debugging output 9 10# egrep 'loc2earth.*host' /serv/www/logs/wn.log | 11# perl -pe 's/^.*host=//; s/([a-zA-Z0-9.-]+).*/$1/' | 12# sort -u | ~/loclist.pl > loc.sites 13 14use Net::DNS '0.08'; 15use Getopt::Std; 16 17getopts('vnrd'); 18 19$res = new Net::DNS::Resolver; 20 21line: 22 foreach $_ (<>) { 23 chomp; 24 $foundloc = $namefound = 0; 25 26 next line if m/^$/; 27 next line if m/[^\w.-\/+_]/; # /, +, _ not actually valid in hostnames 28 29 print STDERR "$_ DEBUG looking up...\n" if $opt_d; 30 31 if (m/^\d+\.\d+\.\d+\.\d+$/) { 32 if ($opt_r) { 33 $query = $res->query($_); 34 35 if (defined ($query)) { 36 foreach $ans ($query->answer) { 37 if ($ans->type eq "PTR") { 38 $_ = $ans->ptrdname; 39 $namefound++; 40 } 41 } 42 } 43 } 44 next line unless $namefound; 45 } 46 47 $query = $res->query($_,"LOC"); 48 49 if (defined ($query)) { # then we got an answer of some sort 50 foreach $ans ($query->answer) { 51 if ($ans->type eq "LOC") { 52 print "$_ YES ",$ans->rdatastr,"\n"; 53 $foundloc++; 54 } 55 } 56 } 57 if ($opt_n && !$foundloc) { # try the RFC 1101 search bit 58 @addrs = @netnames = (); 59 $query = $res->query($_,"A"); 60 if (defined ($query)) { 61 foreach $ans ($query->answer) { 62 if ($ans->type eq "A") { 63 push(@addrs,$ans->address); 64 } 65 } 66 } 67 if (@addrs) { 68 checkaddrs: 69 foreach $ipstr (@addrs) { 70 $ipnum = unpack("N",pack("CCCC",split(/\./,$ipstr,4))); 71 ($ip1) = split(/\./,$ipstr); 72 if ($ip1 >= 224) { # class D/E, treat as host addr 73 $mask = 0xFFFFFFFF; 74 } elsif ($ip1 >= 192) { # "class C" 75 $mask = 0xFFFFFF00; 76 } elsif ($ip1 >= 128) { # "class B" 77 $mask = 0xFFFF0000; 78 } else { # class A 79 $mask = 0xFF000000; 80 } 81 $oldmask = 0; 82 while ($oldmask != $mask) { 83 $oldmask = $mask; 84 $querystr = 85 join(".", reverse (unpack("CCCC",pack("N",$ipnum & $mask)))) 86 . ".in-addr.arpa"; 87 $query = $res->query($querystr,"PTR"); 88 if (defined ($query)) { 89 foreach $ans ($query->answer) { 90 if ($ans->type eq "PTR") { 91 # we want the list in LIFO order 92 unshift(@netnames,$ans->ptrdname); 93 } 94 } 95 $query = $res->query($querystr,"A"); 96 if (defined ($query)) { 97 foreach $ans ($query->answer) { 98 if ($ans->type eq "A") { 99 $mask = unpack("L",pack("CCCC", 100 split(/\./,$ans->address,4))); 101 } 102 } 103 } 104 } 105 } 106 if (@netnames) { 107 foreach $network (@netnames) { 108 $query = $res->query($network,"LOC"); 109 if (defined ($query)) { 110 foreach $ans ($query->answer) { 111 if ($ans->type eq "LOC") { 112 print "$_ YES ",$ans->rdatastr,"\n"; 113 $foundloc++; 114 last checkaddrs; 115 } elsif ($ans->type eq "CNAME") { 116 # XXX should follow CNAME chains here 117 } 118 } 119 } 120 } 121 } 122 } 123 } 124 } 125 if ($opt_v && !$foundloc) { 126 print "$_ NO\n"; 127 } 128 } 129