Subversion Repositories vgwhois

Rev

Rev 2 | Blame | Last modification | View Log | RSS feed

  1. package GWhoIs::Core;
  2.  
  3. use warnings;
  4. use strict;
  5.  
  6. use LWP::Simple;
  7.  
  8. use FindBin;
  9. use lib "$FindBin::RealBin/../";
  10. use GWhoIs::Utils;
  11.  
  12. use List::Util 'max';
  13.  
  14. $GWhoIs::Core::confdir = "$FindBin::RealBin/pattern/";
  15.  
  16. # DM 11.09.2017: There is a weird bug: If I use TOR in combination with LWP on a Gopher protocol, I get error 500.
  17. $GWhoIs::Core::useLWP = 0;
  18.  
  19. $GWhoIs::Core::antispam = 1; # default: on
  20. $GWhoIs::Core::step = 1;
  21.  
  22. # Wieso muss das nicht deklariert werden? (Fehlermeldung "useless use")
  23. #%GWhoIs::Core::mirror;
  24.  
  25. # ($result, $exitcode) = GWhoIs::Core::getsource($url)
  26. sub GWhoIs::Core::getsource {
  27.         my ($url) = @_;
  28.         my $text = $GWhoIs::Core::useLWP ? LWP::Simple::get($url) : GWhoIs::Utils::lynxsource($url);
  29.         my $exitcode = defined($text) ? 0 : 1; # TODO: a better way to detect an error
  30.         return ($text, $exitcode);
  31. }
  32.  
  33. # ($result, $exitcode) = GWhoIs::Core::whoisaccess($host,$port,$query)
  34. sub GWhoIs::Core::whoisaccess {
  35.         my ($host,$port,$query) = @_;
  36.  
  37.         $query =~ s/ /%20/g;
  38.  
  39.         my ($result, $exitcode) = GWhoIs::Core::getsource("gopher://$host:$port/0$query");
  40.         if ($exitcode) {
  41.                 $result .= "Query to whois server failed.\n";
  42.         }
  43.         $result =~ s/\x0D//g; # remove CR from output
  44.  
  45.         return ($result, $exitcode);
  46. }
  47.  
  48. # ($result, $exitcode) = GWhoIs::Core::inicwhoisaccess($host,$port,$query)
  49. sub GWhoIs::Core::inicwhoisaccess { # todo: mehr als 1 redirect möglich, z.b. bei rwhois??
  50. #TODO: hier auch $mirror unterstützung?
  51.         my ($host,$port,$query) = @_;
  52.         my ($queryresult, $result);
  53.         my $exitcode;
  54.  
  55.         ($queryresult, $exitcode) = GWhoIs::Core::whoisaccess($host,$port,"=$query");
  56.  
  57.         # Result von NSI-Registry auf relevanten Part absuchen
  58.         if ( $queryresult =~ /Name:\s+$query\s/mi ) {
  59.                 $result = "-- From: $host:$port\n\n";
  60.                 ($host) = $queryresult =~
  61.                         /Name:\s+$query\s.*?Whois Server:\s+(.*?)\s/si;
  62.  
  63.                 my $relresult;
  64. #               my ($relresult) = $queryresult =~
  65. #                       /[\r\n]([^\r\n]+\S+\sName:\s+$query\s.*?Expiration Date:[^\r\n]+)[\r\n]/si;
  66. #               $relresult = "(Redirect to $host:$port)" if !defined $relresult;
  67.                 $relresult = $queryresult;
  68.  
  69.                 $result .= "$relresult\n\n-- End --\n\n";
  70.  
  71.                 # $port = 43;
  72.                 my ($host2, $port) = $host =~ /^(.*):(.*)$/;
  73.                 $port = 43     if !defined $port;
  74.                 $host = $host2 if  defined $host2;
  75.  
  76.                 # print $GWhoIs::Core::step++,". Step: Querying $host:$port with whois.\n\n"; # todo "rwhois"?
  77.                 $result .= ($GWhoIs::Core::step++).". Step: Querying $host:$port with whois.\n\n"; # todo "rwhois"?
  78.  
  79.                 $result .= "-- From: $host:$port\n\n";
  80.                 # TODO: beim referal whois ist die query ist nicht trimmed. scheint aber nix auszumachen
  81.                 my ($loc_text, $loc_exitcode) = GWhoIs::Core::whoisaccess($host,$port,$query);
  82.  
  83.                 $exitcode = max($exitcode, $loc_exitcode);
  84.                 $result .= $loc_text;
  85.         } else {
  86.                 $result = "-- From: $host:$port\n\n$queryresult-- End --\n";
  87.         }
  88.  
  89.         return ($result, $exitcode);
  90. }
  91.  
  92. # ($result, $exitcode) = GWhoIs::Core::wwwsgrep($url,$match)
  93. sub GWhoIs::Core::wwwsgrep {
  94.         my ($url,$match) = @_;
  95.         my ($result, $line, $exitcode) = ('', '', 0);
  96.  
  97.         ($line, $exitcode) = GWhoIs::Core::getsource($url);
  98.         if (!$exitcode) {
  99.                 $line =~ s/\n/ /g;
  100.                 if ($line =~ $match) {
  101.                         ($result) = $line =~ /$match/s;
  102.                 }
  103.         }
  104.         return ($result, $exitcode);
  105. }
  106.  
  107. # ($host, $additional) = GWhoIs::Core::methodpatternregex($query,$host,$additional,$queryline);
  108. sub GWhoIs::Core::methodpatternregex {
  109.         my ($query,$host,$additional,$line) = @_;
  110.  
  111.         my ($namewotld,$tld) = $query =~ /^([^\.]*)\.(.*)$/;
  112. # TODO: !defined
  113.         my ($p1,$p2,$p3,$p4,$p5,$p6,$p7,$p8,$p9) = $query =~ $line;
  114. # TODO: !defined
  115.         my ($ucq) = uc($query);
  116.  
  117.         $host       =~ s/~query~/$query/;
  118.         $host       =~ s/~ucquery~/$ucq/;
  119.         $host       =~ s/~namewotld~/$namewotld/;
  120.         $host       =~ s/~tld~/$tld/;
  121.         $host       =~ s/~1~/$p1/;
  122.         $host       =~ s/~2~/$p2/;
  123.         $host       =~ s/~2~/$p3/;
  124.         $host       =~ s/~2~/$p4/;
  125.         $host       =~ s/~2~/$p5/;
  126.         $host       =~ s/~2~/$p6/;
  127.         $host       =~ s/~2~/$p7/;
  128.         $host       =~ s/~2~/$p8/;
  129.         $host       =~ s/~2~/$p9/;
  130.  
  131.         $additional =~ s/~query~/$query/;
  132.         $additional =~ s/~ucquery~/$ucq/;
  133.         $additional =~ s/~namewotld~/$namewotld/;
  134.         $additional =~ s/~tld~/$tld/;
  135.         $additional =~ s/~1~/$p1/;
  136.         $additional =~ s/~2~/$p2/;
  137.  
  138.         return ($host,$additional);
  139. }
  140.  
  141. # @patternfiles = GWhoIs::Core::getpatternfiles()
  142. sub GWhoIs::Core::getpatternfiles {
  143.         my (@files, @files_new);
  144.  
  145.         opendir(DIR, $GWhoIs::Core::confdir);
  146.         @files_new = sort(readdir(DIR));
  147.         closedir(DIR);
  148.  
  149.         @files_new = grep {
  150.                             ($_ !~ /^\./)
  151.                          && ($_ !~ /\.dpkg-/)
  152.                          && ($_ !~ /\.orig$/)
  153.                          && ($_ !~ /\.bak$/)
  154.                          && ($_ !~ /\.save$/)
  155.                          && ($_ !~ /^\./)
  156.                         } @files_new;
  157.         @files_new = map { "$GWhoIs::Core::confdir/$_" } @files_new;
  158.  
  159.         @files = grep { -f } (@files_new);
  160.  
  161.         return (@files);
  162. }
  163.  
  164. # ($method, $host, $additional) = GWhoIs::Core::getmethodother($query);
  165. sub GWhoIs::Core::getmethodother {
  166.         my ($query) = @_;
  167.         my $found = 0;
  168.         my ($line,$cline,$method,$host,$additional);
  169.         my ($rang_prefix, $rang_beginning, $rang_ending);
  170.         my ($rang_actual_prefix, $rang_number);
  171.  
  172.         # Process file until we found a match
  173.         foreach my $patternfile (GWhoIs::Core::getpatternfiles()) {
  174.                 open(PATTERN,"<$patternfile") || die "Cannot open $patternfile. STOP.\n";
  175.  
  176.                 while ( defined($line = <PATTERN>) && (!$found) ) {
  177.                         # chomp $line;
  178.                         $line = GWhoIs::Utils::trim($line);
  179.  
  180.                         if ( $line =~ /^#/ ) {                       # comment
  181.                         } elsif ( ($cline) = $line =~ /^:(.*)$/ ) {  # method declaration
  182.                                 ($method,$host,$additional) = split(/\|/,$cline,3);
  183.                                 $method=''     if !defined $method;
  184.                                 $host=''       if !defined $host;
  185.                                 $additional='' if !defined $additional;
  186.  
  187.                         } elsif ( $line =~ /^\*/ && (($rang_actual_prefix, $rang_number) = $query =~ /^([^0-9]+)([0-9]+)$/) ) {
  188.                                 # e.g. for parsing ASNs
  189.  
  190.                                 if (($rang_prefix, $rang_beginning) = $line =~ /^\*([^0-9]+):([0-9]+)$/) {
  191.                                         # Single number
  192.                                         $rang_ending = $rang_beginning
  193.                                 } else {
  194.                                         # Range
  195.                                         ($rang_prefix, $rang_beginning, $rang_ending) = $line =~ /^\*([^0-9]+):([0-9]+)-([0-9]+)$/;
  196.                                         next if !defined $rang_prefix;
  197.                                         next if !defined $rang_beginning;
  198.                                         next if !defined $rang_ending;
  199.                                 }
  200.  
  201.                                 if ((lc($rang_prefix) eq lc($rang_actual_prefix))
  202.                                   && ($rang_number >= $rang_beginning)
  203.                                   && ($rang_number <= $rang_ending)) {
  204.                                         $found = 1;
  205.                                         # ($host,$additional) = GWhoIs::Core::methodpatternregex($query,$host,$additional,$line);
  206.                                 }
  207.                         } elsif ( $line ne '' && $line =~ /^[^\*]/ && $query =~ /$line/i ) {
  208.                                 # Regex
  209.                                 $found = 1;
  210.                                 ($host,$additional) = GWhoIs::Core::methodpatternregex($query,$host,$additional,$line);
  211.                         }
  212.                 }
  213.         }
  214.         if (!$found) {
  215.                 return ('','','')
  216.         }
  217.  
  218.         $host = $GWhoIs::Core::mirror{$method.$host} if defined $GWhoIs::Core::mirror{$method.$host};
  219.         return ($method,$host,$additional);
  220. }
  221.  
  222. # ($resulttext, $exitcode) = GWhoIs::Core::redirectwhois($query,$host,$port)
  223. sub GWhoIs::Core::redirectwhois {
  224.         my ($query,$host,$port) = @_; # todo: anstelle $port lieber ein $additional zulassen?
  225.         $port = 43 if !defined $port;
  226.  
  227.         # check for query modifier (if any)
  228.         my ($modmethod, $modhost, $modadditional) = GWhoIs::Core::getmethodother("redirect:$host(:$port){0,1}");
  229.  
  230.         return GWhoIs::Core::doquery($query,$modmethod,$modhost,$modadditional)
  231.                 if ( $modmethod ne 'none');
  232.  
  233.         return GWhoIs::Core::doquery($query, 'whois', "$host:$port");
  234. }
  235.  
  236. # ($resulttext, $exitcode) = GWhoIs::Core::doquery($query,$method,$host,$additional);
  237. sub GWhoIs::Core::doquery {
  238.         my ($query,$method,$host,$additional,$inside_multiple) = @_;
  239.         my $result = '';
  240.         my $exitcode = 0;
  241.  
  242.         $query = ''          if !defined $query;
  243.         $method = ''         if !defined $method;
  244.         $host = ''           if !defined $host;
  245.         $additional = ''     if !defined $additional;
  246.         $inside_multiple = 0 if !defined $inside_multiple;
  247.  
  248.         if ($method eq 'multiple') {
  249.                 my $triple;
  250.                 # do not match "::::", e.g. used by notice
  251.                 my @triple_split = split(/(?<!:):::(?!:)/, $additional);
  252.                 my $count = 0;
  253.                 foreach $triple (@triple_split) {
  254.                         ($method,$host,$additional) = split(/::/, $triple);
  255.  
  256.                         # We will not get the exact sequence of "prints" and "$result" outputs, but it is better than nothing.
  257.                         # If we would print everything, we would get the warning "print wide char" at nic.es
  258.                         # If we would save all output to $result without buffering the prints inside GWhoIs::Core::doquery(), the prints would not be in front of their section.
  259.                         my $output = '';
  260.                         open TOOUTPUT, '>', \$output or die "Can't open TOOUTPUT: $!"; # TODO: exitcode
  261.                         my $orig_select = select(TOOUTPUT);
  262.  
  263.                         my ($loc_text, $loc_exitcode) = GWhoIs::Core::doquery($query, $method, $host, $additional, 1);
  264.                         $exitcode = max($exitcode, $loc_exitcode);
  265.  
  266.                         $output .= GWhoIs::Utils::trim($loc_text);
  267.                         $output .= "\n\n------\n\n" if $count < $#triple_split;
  268.                         select($orig_select);
  269.                         $result .= $output;
  270.  
  271.                         $count += 1;
  272.                 }
  273.  
  274.                 # done
  275.                 $method = '';
  276.         }
  277.  
  278. # TODO: usage of methods. delete unused ones!
  279. # wwwgreplv -> removed
  280. # whoisjp: not in pattern
  281. # whoisarin: not in pattern
  282. # inicwhois: in use
  283.  
  284.         elsif ($method eq 'wwwsgrep') {
  285.                 my ($protocol, $hostname) = GWhoIs::Utils::splitProtocolHost($host);
  286.  
  287.                 print "Querying $hostname with $protocol.\n\n";
  288.  
  289.                 my ($loc_text, $loc_exitcode) = GWhoIs::Core::wwwsgrep($host,$additional);
  290.                 $exitcode = max($exitcode, $loc_exitcode);
  291.                 if ($loc_exitcode) {
  292.                         $result .= "Query to web server failed.\n";
  293.                 } else {
  294.                         if ($loc_text ne '') {
  295.                                 $result = "Match found:\n$loc_text\n";
  296.                         } else {
  297.                                 $result = "No match found. This probably means that this domain does not exist.\n";
  298.                         }
  299.                 }
  300.         }
  301.  
  302.         elsif ($method =~ /^whois(|jp|arin)$/) {
  303.                 my ($parameter,$outquery,$prefix) = ('', '', '');
  304.  
  305.                 my $port       = 43;
  306.                 my $noipprefix = '';
  307.                 my $ipprefix   = '';
  308.                 my $trailer    = '';
  309.                 my $strip      = '';
  310.  
  311.                 $additional = '' if !defined $additional;
  312.  
  313.                 foreach $parameter (split('\|', $additional)) {
  314.                         $trailer    = $1 if ( $parameter =~ /trailer=(.*)/ );
  315.                         $strip      = $1 if ( $parameter =~ /strip=(.*)/ );
  316.                         $prefix     = $1 if ( $parameter =~ /prefix=(.*)/ );
  317.                 }
  318.  
  319.                 $port = $1 if ( $host =~ /.+:(\d+)/ );
  320.                 $host =~ s/:(\d+)//g;
  321.  
  322.                 print "Querying $host:$port with whois.\n"; # todo "rwhois"?
  323.  
  324.                 $outquery = $prefix . $query . $trailer . "\n";
  325.                 $outquery =~ s/$strip//g if ( $strip ne '' );
  326.  
  327.                 my $loc_exitcode;
  328.                 ($result, $loc_exitcode) = GWhoIs::Core::whoisaccess($host,$port,$outquery);
  329.                 $exitcode = max($exitcode, $loc_exitcode);
  330.  
  331.                 # TODO rwhois:// implementierung ok?
  332.                 if ( $result =~ /ReferralServer: whois:\/\/(.*):43/mi || $result =~ /ReferralServer: whois:\/\/(.*)/mi ) {
  333.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,$1);
  334.                         $host = ''; #TODO???
  335.                         $exitcode = max($exitcode, $loc_exitcode);
  336.                 } elsif ( $result =~ /ReferralServer: r{0,1}whois:\/\/([^:]*):(\d+)/mi ) {
  337. #                       ($result, $loc_exitcode) = GWhoIs::Core::whoisaccess($1,$2,$query); # TODO rediretwhois ?
  338.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,$1,$2);
  339.                         $exitcode = max($exitcode, $loc_exitcode);
  340.                 } elsif ( $result =~ /ReferralServer: rwhois:\/\/(.*)/mi ) {
  341. #                       ($result, $loc_exitcode) = GWhoIs::Core::whoisaccess($1,4321,$query); # TODO rediretwhois ?
  342.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,$1,4321);
  343.                         $exitcode = max($exitcode, $loc_exitcode);
  344.                 } elsif ( $result =~ /(refer|whois server):\s+(.*)/m ) {
  345.                         # "refer:" is sent by whois.iana.org (e.g. if you query test.de )
  346.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,$2);
  347.                         $host = ''; #TODO???
  348.                         $exitcode = max($exitcode, $loc_exitcode);
  349.                 }
  350.  
  351.                 # TODO: http://tools.ietf.org/html/rfc1714#section-3.3.2
  352.                 #    %referral<SP><server>[:type]<SP>[authority area]
  353.  
  354.                 print "\n";
  355.         }
  356.  
  357.         elsif ($method eq 'inicwhois' ) {
  358.                 my $port = $additional || 43;
  359.                 $result = ($GWhoIs::Core::step++).". Step: Querying $host:$port with whois.\n\n"; #todo "rwhois"?
  360.                 $query .= "\n"; # ???
  361.  
  362.                 my ($loc_text, $loc_exitcode) = GWhoIs::Core::inicwhoisaccess($host,$port,$query);
  363.                 $result .= $loc_text;
  364.                 $exitcode = max($exitcode, $loc_exitcode);
  365.         }
  366.  
  367.         elsif ($method eq 'cgi') {
  368.                 my ($protocol, $hostname) = GWhoIs::Utils::splitProtocolHost($host);
  369.  
  370.                 print "Querying $hostname ($protocol) with cgi.\n\n";
  371. #!!
  372. #               print "$host\n";
  373.  
  374. # TODO: lynx seems to be better in some ways!
  375. #       For example, a website that outputs "text/plain" will be rendered correct in lynx!
  376. #               $result = `lynx -connect_timeout=10 -dump "$host" 2>&1`;
  377. #               $result .= "FAILED with exit code $?\n\n" if $?;
  378.  
  379.                 # TODO: GWhoIs::Core::getsource ok? war vorher IMMER lynx
  380.                 my ($loc_text, $loc_exitcode) = GWhoIs::Core::getsource($host);
  381.  
  382.                 $exitcode = max($exitcode, $loc_exitcode);
  383.                 if ($loc_exitcode) {
  384.                         $result .= "Query to web server failed.\n";
  385.                 } else {
  386.                         $result = GWhoIs::Utils::render_html($loc_text);
  387.                 }
  388.         }
  389.  
  390.         elsif ($method eq 'cgipost') {
  391.                 my ($protocol, $hostname) = GWhoIs::Utils::splitProtocolHost($host);
  392.  
  393.                 print "Querying $hostname ($protocol) with cgi.\n\n";
  394. #!!
  395. #               print "echo -e '$additional\n---' | lynx -connect_timeout=10 -dump -post_data '$host'\n";
  396.  
  397. # TODO: GWhoIs::Utils::render_html() better? TODO: lynx source?
  398. # [Ma 22.07.2013] "echo -e" does not work... "-e" will shown to the output... However "\n" will still work if I remove -e ... weird.
  399. #               $result = `echo -e "$additional\n---" | lynx -dump -post_data "$host" 2>&1`; # TODO escape
  400. #               $result = `echo "$additional\n---" | lynx -dump -post_data "$host" 2>&1`; # TODO escape
  401.                 $result = `echo "$additional" | curl --silent -X POST --data-binary \@- "$host" | lynx -dump -stdin 2>&1`; # TODO escape
  402.                 my $loc_exitcode = $?;
  403.                 $exitcode = max($exitcode, $loc_exitcode);
  404.                 $result .= "FAILED with exit code $loc_exitcode\n\n" if $loc_exitcode;
  405.         }
  406.  
  407.         elsif ($method eq 'cgipostcurl') {
  408.                 my ($protocol, $hostname) = GWhoIs::Utils::splitProtocolHost($host);
  409.  
  410.                 print "Querying $hostname ($protocol) with cgi.\n\n";
  411. #               print "$additional\n"; #!!
  412. #               print "curl --max-time 10 --stderr /dev/null -e $host --data '$additional' $host | lynx -dump -stdin\n";
  413.  
  414.                 # TODO: "set pipefail" doesn't work (insecure certificate will not cause the function to fail)
  415.                 $result = `curl --max-time 10 --insecure --stderr /dev/null -e "$host" --data "$additional" "$host" | lynx -dump -stdin 2>&1`; # TODO escape
  416.  
  417.                 my $loc_exitcode = $?;
  418.                 $exitcode = max($exitcode, $loc_exitcode);
  419.                 $result .= "FAILED with exit code $loc_exitcode\n\n" if $loc_exitcode;
  420.         }
  421.  
  422.         elsif ($method eq 'cgihttps') {
  423.                 my ($protocol, $hostname) = GWhoIs::Utils::splitProtocolHost($host);
  424.  
  425.                 print "Querying $hostname ($protocol) with cgi.\n\n";
  426. #               print "$additional\n"; #!!
  427. #               print "curl --max-time 10 --stderr /dev/null $host | lynx -dump -stdin\n";
  428. #               $result = `curl --max-time 10 --insecure --stderr /dev/null "$host" | lynx -dump -stdin 2>&1`;
  429.                 my $html = `curl --max-time 10 --insecure --stderr /dev/null "$host" 2>&1`; # TODO escape. why --insecure?
  430.                 my $loc_exitcode = $?;
  431.                 $exitcode = max($exitcode, $loc_exitcode);
  432.                 $html .= "FAILED with exit code $loc_exitcode\n\n" if $loc_exitcode;
  433.                 $result = GWhoIs::Utils::render_html($html);
  434.         }
  435.  
  436.         elsif ($method eq 'notice') {
  437.                 if ($inside_multiple) {
  438.                         $result = "\n\nAdditional information for query '$query'.\n\n" . $additional . "\n\n";
  439.                 } else {
  440.                         $result = "\n\nNo lookup service available for your query '$query'.\n\ngwhois remarks: " . $additional . "\n\n";
  441.                 }
  442.                 # $exitcode = 0;
  443.         }
  444.  
  445.         elsif ($method eq 'program') {
  446.                 my ($program) = GWhoIs::Utils::trim($host);
  447.                 $program =~ s/\$gwhois\$/$FindBin::RealBin/;
  448.                 print "Querying script $program\n\n";
  449.                 $result = `$program $additional "$query" 2>&1`;
  450.                 my $loc_exitcode = $?;
  451.                 $exitcode = max($exitcode, $loc_exitcode);
  452.                 $result .= "FAILED with exit code $loc_exitcode\n\n" if $loc_exitcode;
  453.         }
  454.  
  455.         if ($host =~ /arin/) {
  456.                 my $loc_exitcode;
  457.                 if ($result =~ /Maintainer: RIPE/) {
  458.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,'whois.ripe.net');
  459.                         $exitcode = max($exitcode, $loc_exitcode);
  460.                 } elsif ($result =~ /Maintainer: AP/) {
  461.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,'whois.apnic.net');
  462.                         $exitcode = max($exitcode, $loc_exitcode);
  463.                 }
  464.         }
  465.         elsif ($host =~ /apnic/) {
  466.                 my $loc_exitcode;
  467.                 if ($result =~ /netname: AUNIC-AU/) {
  468.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,'whois.aunic.net');
  469.                         $exitcode = max($exitcode, $loc_exitcode);
  470.                 } elsif ($result =~ /netname: JPNIC-JP/) {
  471.                         ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,'whois.nic.ad.jp');
  472.                         $exitcode = max($exitcode, $loc_exitcode);
  473.                 }
  474.         }
  475.         elsif ($host =~ /ripe/ && $result =~ /remarks:\s+whois -h (\S+)/) {
  476.                 my $loc_exitcode;
  477.                 ($result, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,$1);
  478.                 $exitcode = max($exitcode, $loc_exitcode);
  479.         }
  480.         # TODO: internic gibts doch gar nicht mehr, oder?
  481.         elsif (($host =~ /internic/) && ($result =~ /No match for/) && ($query !~ /\.(arpa|com|edu|net|org)$/) ) {
  482.                 my ($result1, $loc_exitcode) = GWhoIs::Core::redirectwhois($query,'whois.ripe.net');
  483.                 $result = $result1 if $result1 !~ /No entries found/;
  484.                 $exitcode = max($exitcode, $loc_exitcode);
  485.         }
  486.  
  487.         return ($result, $exitcode);
  488. }
  489.  
  490. 1;
  491.