#!/usr/bin/perl -w # # $Id: //pentools/main/whois/whois#19 $ # # written by : Stephen J. Friedl # Software Consultant # Tustin, California USA # steve@unixwiz.net # # This is a front end to the "fwhois" program that knows where # lots and lots of whois servers are. We look at the argument(s) # given and make our best guesses on how where we should ask for # the requested information, and whether we have to look in more # than one place given the first reply. # # [ more docs needed here ] # # ------------------------------------------------------------------------ # Given bits of the leading IP address, select the IP address registry. # If not in this table, we assume ARIN. This table is maintained by hand, # and we're not sure just where the authoritative information is. But # this has worked pretty well so far. # use strict; my %BY_IP = ( '24.192', 'apnic', # 24.192/14 '24.193', 'apnic', '24.194', 'apnic', '24,195', 'apnic', '211.40', 'krnic/e', '211.41', 'krnic/e', '169.208', 'apnic', # 169.208/12 '169.209', 'apnic', '169.210', 'apnic', '169.211', 'apnic', '169.212', 'apnic', '169.213', 'apnic', '169.214', 'apnic', '169.215', 'apnic', '169.216', 'apnic', '169.217', 'apnic', '169.218', 'apnic', '169.219', 'apnic', '169.220', 'apnic', '169.221', 'apnic', '169.222', 'apnic', '169.223', 'apnic', '61', 'apnic', # 61/8 '202', 'apnic', # 202/7 '203', 'apnic', '210', 'apnic', # 210/7 '211', 'apnic', '24.132', 'ripe', # 24.132/14 '24.133', 'ripe', '24.134', 'ripe', '24.135', 'ripe', '62', 'ripe', # 62/8 '193', 'ripe', '194', 'ripe', '195', 'ripe', '212', 'ripe', '213', 'ripe', ); # ------------------------------------------------------------------------ # Some subnets are partial that cannot be specified by a single spec, so # we populate them this way. # foreach $b ( 0 .. 85 ) { $BY_IP{"141.$b"} = 'ripe'; } foreach $b ( 208 .. 223 ) { $BY_IP{"168.$b"} = 'apnic'; } # 169.208/12 # ------------------------------------------------------------------------ # Given the tail end of a domain, find the proper registry for it. # my %BY_DOMAIN = ( # top-level domains 'com', 'whois.internic.net', 'net', 'whois.internic.net', 'org', 'whois.internic.net', 'edu', 'whois.internic.net', 'int', 'whois.internic.net', # betcha you never heard of this one 'mil', 'whois.nic.mil', 'gov', 'whois.nic.gov', # country-specific registries. EXPAND THIS! 'us', 'whois.isi.edu', 'cc', 'whois.nic.cc', # 'ch', 'whois.nic.ch', # Switzerland 'cn', 'whois.cnnic.net', # China 'de', 'whois.denic.de', # Germany 'hk', 'whois.hknic.net.hk', # Hong Kong 'is', 'whois.isnet.is', # Iceland 'it', 'whois.nic.it', # Italy 'jp', 'whois.nic.ad.jp/e', # Japan (/e = English) 'kr', 'whois.krnic.net/e', # Korea (South) 'mx', 'whois.nic.mx', # Mexico 'my', 'whois.mynic.net', # Malaysia 'ru', 'whois.ripn.net', # Russia 'se', 'whois.nic-se.se', # Sweden 'su', 'whois.ripn.net', # Soviet Union 'to', 'whois.tonic.to', # Tonga 'tw', 'whois.twnic.net', # Taiwan 'uk', 'whois.nic.uk', # United Kingdom 'nl', 'whois.domain-registry.nl', # Netherlands ); # ------------------------------------------------------------------------ # Sometimes the user wants to specify a registry by hand, and we permit # these shorthands for the longer names. # my %BY_ALIAS = ( 'abuse', 'whois.abuse.net', 'apnic', 'whois.apnic.net', 'arin', 'whois.arin.net', 'ripe', 'whois.ripe.net', 'krnic', 'whois.nic.or.kr/e' ); my $HOST; my $DFLT = 1; my $QUERY; my $arg; while ( @ARGV ) { $arg = shift @ARGV; if ( $arg =~ m/^(.*)\@(.+)/ ) { $QUERY = $1; $HOST = $2; $DFLT = 0; } elsif ( $QUERY ) { die "ERROR: too many params\n"; } else { $QUERY = $arg; } } die "ERROR: missing parameters\n" if ! $arg; # numeric parameters? try to do a bit of looking up # based on where the thing is located. if ( ! $HOST ) { if ( $arg =~ m/^(\d+)\.(\d+)\.\d+\.\d+$/ ) { my $part1 = $1; my $part2 = $2; $HOST = $BY_IP{"$part1.$part2"}; $HOST = $BY_IP{$part1} if ! $HOST; $HOST = "arin" if ! $HOST; } elsif ( $arg =~ m/\.([^.]+)$/ ) { my $dom = $1; $HOST = $BY_DOMAIN{$dom}; } } # ------------------------------------------------------------------------ # If we have no host yet, we generally assume the Internic, but if we have # entered the keywords "host" or "server" followed by a space, we probably # mean Network Solutions # if ( ! $HOST && $QUERY =~ m/^(host|server)\s/i ) { $HOST = "whois.networksolutions.com"; } # ------------------------------------------------------------------------ # If we've not figured out the host yet, always use Network Solutions. # Then see if we have an "alias" for the whois server. # $HOST = "whois.internic.net" if ! $HOST; #if ( ! $HOST || $HOST eq 'whois.internic.net' ) #{ # $HOST = "whois.networksolutions.com" #} my($alias) = $BY_ALIAS{$HOST}; $HOST = $alias if $alias; if ( $HOST =~ m/\/e$/ ) { $HOST =~ s/..//; $QUERY .= "/e"; } $QUERY = "\"$QUERY\"" if $QUERY =~ m/[^-_.a-z0-9]/i; # add quotes if needed # $QUERY .= '/e' if $HOST eq 'whois.nic.ad.jp'; # show results in English my @SKIPLINES = ( "The InterNIC Registration Services database contains ONLY" , "non-military and non-US Government Domains and contacts." , "Other associated whois servers:" , " American Registry for Internet Numbers - whois.arin.net" , " European IP Address Allocations - whois.ripe.net" , " Asia Pacific IP Address Allocations - whois.apnic.net" , " US Military - whois.nic.mil" , " US Government - whois.nic.gov" , "The ARIN Registration Services Host contains ONLY Internet" , "Network Information: Networks, ASN's, and related POC's." , "Please use the whois server at rs.internic.net for DOMAIN related", "Information and nic.mil for NIPRNET Information.", "The Data in Network Solutions' WHOIS database is provided by Network", "Solutions for information purposes, and to assist persons in obtaining", "information about or related to a domain name registration record.", "Network Solutions does not guarantee its accuracy. By submitting a", "WHOIS query, you agree that you will use this Data only for lawful", "purposes and that, under no circumstances will you use this Data to:", "(1) allow, enable, or otherwise support the transmission of mass", "unsolicited, commercial advertising or solicitations via e-mail", "(spam); or (2) enable high volume, automated, electronic processes", "that apply to Network Solutions (or its systems). Network Solutions", "reserves the right to modify these terms at any time. By submitting", "this query, you agree to abide by this policy.", "Information and whois.nic.mil for NIPRNET Information.", "The previous information has been obtained either directly from the", "registrant or a registrar of the domain name other than Network Solutions.", "Network Solutions, therefore, does not guarantee its accuracy or", "completeness.", # REGISTER.COM "The data in Register.com's WHOIS database is provided to you by", "Register.com for information purposes only, that is, to assist you in", "obtaining information about or related to a domain name registration", "record. Register.com makes this information available \"as is,\" and", "does not guarantee its accuracy. By submitting a WHOIS query, you", "agree that you will use this data only for lawful purposes and that,", "under no circumstances will you use this data to: (1) allow, enable,", "or otherwise support the transmission of mass unsolicited, commercial", "advertising or solicitations via direct mail, electronic mail, or by", "telephone; or (2) enable high volume, automated, electronic processes", "that apply to Register.com (or its systems). The compilation,", "repackaging, dissemination or other use of this data is expressly", "prohibited without the prior written consent of Register.com.", "Register.com reserves the right to modify these terms at any time.", "By submitting this query, you agree to abide by these terms.", # co.uk "The NIC.UK Registration Host contains ONLY information for domains", "within co.uk, org.uk, net.uk, ltd.uk and plc.uk. Please use the whois", "server at rs.internic.net for Internet Information or the whois server", "at nic.ddn.mil for MILNET Information.", "Domain names in the \.com, \.net, and \.org domains can now be registered", "with many different competing registrars. Go to http://www\.internic\.net", "for detailed information\.", "Register your domain name at http://www\.register\.com", "The Registry database contains ONLY .COM, .NET, .ORG, .EDU domains and", "Registrars.", " Domain servers in listed order:", " Referral URL: www.networksolutions.com", # .cc "The NIC.CC Registration Services database contains ONLY", "domain information for domain names registered under the .cc TLD.", "Access to the whois information may be denied to those submitting", "automated queries in excess of reasonable load in order to ensure that", "others wishing to use the resource have fair access.", "This information is (c) 1997, 1998, 1999, 2000, 2001 eNIC Corp.", # itsyourdomain.com "The Data in our WHOIS database is provided by", "us for information purposes, and to assist persons", "in obtaining information about or related to a domain name registration", "record. We do not guarantee its accuracy. By", "submitting a WHOIS query, you agree that you will use this Data only", "for lawful purposes and that, under no circumstances will you use this", "Data to: (1) allow, enable, or otherwise support the transmission of mass", "that apply to our systems. We", "reserve the right to modify these terms at any time. By submitting", # ARIN "To single out one record, look it up with \"!xxx\", where xxx is the", "handle, shown in parenthesis following the name, which comes first.", ); my $cmdline = "fwhois $QUERY\@$HOST"; # LINUX my $nblanks = 0; my $referal; my $last_cmdline = ""; while ( $cmdline ) { print "--> $cmdline\n"; if ( $last_cmdline eq $cmdline ) { print "NOTE: referral loop detected (exiting)\n"; last; } $last_cmdline = $cmdline; open(WHO, "$cmdline|") || die("cannot open whois process"); $cmdline = ""; # for next loop $referal = ""; # for next loop my $ARIN_NETBLK = ""; my $ARIN_count = 0; while ( ) { s/\s+$//; my $line = $_; next if grep( $line eq $_, @SKIPLINES ); # -------------------------------------------------------- # If this is an ARIN query and we see a handle, grab it. # If we see more than one handle, we save the last one # to dig even further. # if ( $HOST eq 'whois.arin.net' and $line =~ m/\s\((NET[^\)]+)\)/ ) { $ARIN_NETBLK = $1; ++$ARIN_count; } # Exodus lies about create date next if m/^network:Created:69/i; next if m/^network:Class-Name:network/; next if m/^>>> Last update of whois database: /; next if m/^ Database last updated on /; s/^network://; # for rwhois servers $nblanks++, next if m/^$/; $nblanks = 0, print "\n" if $nblanks > 0; print $_, "\n"; # -------------------------------------------------------- # See if there is a referral to a secondary server here. # if ( m/at (rwhois\.verio\.net) port/ || m/available from (rwhois\.dn\.net)/i || m/(rwhois\.[a-z0-9]+\.(net|com)) 4321/i || m/\* (rwhois\.concentric\.net)/i || m/\* available at (whois.nac.net)/ || m/^\%referral (rwhois.internic.net):4321/i ) { my $server = $1; my $port = 4321; if ( $server eq 'whois.nac.net' ) { $port = 'whois'; } elsif ( $server eq 'rwhois.internic.net' ) { $server = 'whois.internic.net'; $port = 'whois' } $HOST = "$server:$port"; $cmdline = "fwhois $QUERY\@$HOST"; } if ( m/Whois Server: ([^\s]+)/ ) { $HOST = $1; $cmdline = "fwhois $QUERY\@$HOST"; } } close(WHO); if ( $ARIN_count > 1 && not $cmdline ) { $cmdline = "fwhois \"!$ARIN_NETBLK\@whois.arin.net\""; } } if ( $referal ) { print "REFER TO $referal\n"; }