package whois; # # Author: Erik Heinz # Copyright: GPL # Version: 2005-06-28 # use DB_File; use IO::Socket; use IO::Handle; use Encode; use Net::LibIDN; $CACHE_FILE = '/var/lib/whois/cache.db'; $LOCK_FILE = '/var/lib/whois/LOCK'; # $GET_PROG = 'lynx -nolist -dump'; $GET_PROG = 'elinks -dump -dump-charset UTF-8'; $POST_PROG = 'lynx -post_data -nolist -dump'; sub tcp { my ($host, $port, $search) = @_; my $socket = new IO::Socket::INET ( PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Type => SOCK_STREAM, Timeout => 15 ); if (!$socket) { return "query to $host:$port failed"; } autoflush $socket 1; $socket->timeout(10); print $socket "$search\r\n"; return join('', <$socket>); } sub do_query { my ($addr, $search, $verbose) = @_; my ($host, $port, $url, $data, $result); if ($addr =~ /^https?:\/\//) { $addr =~ s/%D/$search/; $addr =~ s/%S/$search/; if ($addr =~ /^(.+) POST=(.+)$/) { ($url, $data) = ($1, $2); if ($verbose) { print "Posting data '$data' at URL $url\n"; } open(PIPE, "echo \"$data\" | $POST_PROG \"$url\" |"); } else { if ($verbose) { print "Requesting URL $addr\n"; } open(PIPE, "$GET_PROG \"$addr\" |"); } while() { $result .= $_; } close PIPE; } else { if ($addr =~ /^([^:]+):([^:]+)$/) { ($host, $port) = ($1, $2); } else { ($host, $port) = ($addr, 43); } if ($verbose) { print "Querying: $host:$port for '$search'\n"; } $result = tcp($host, $port, $search); } return $result; } sub check_utf8 { my ($s1) = @_; Encode::_utf8_on($s1); return Encode::is_utf8($s1, 1); } sub convert_idn { my ($s1) = @_; if (! check_utf8($s1)) { Encode::from_to($s1, 'iso-8859-1', 'utf-8'); } $s1 = Net::LibIDN::idn_to_ascii($s1, 'utf-8', IDNA_USE_STD3_ASCII_RULES); if ($verbose) { print "ACE: $s1\n"; } return $s1; } sub get_info { my ($search, $verbose, $addr) = @_; my ($h1, $s1); $_ = $s1 = $search; if ($addr) { } elsif (/^(\d+)\.(\d+)(?:\.\d+(?:\.\d+)?)?$/) { # IPv4 $stype = 'IP'; if ($verbose) { print "Search type: IPv4 address.\n"; } if (exists $IP_REG{$1}) { $addr = $IP_REG{$1}; } elsif (exists $IP_REG{"$1.$2"}) { $addr = $IP_REG{"$1.$2"}; } else { $addr = 'whois.arin.net'; $s1 = "+n $search"; } } elsif (/^([23][0-9A-F]{3}):([0-9A-F]{1,4}):[0-9A-F:]+/i) { # IPv6 $stype = 'IP'; if ($verbose) { print "Search type: IPv6 address.\n"; } my $s1 = uc($1); my $s2 = uc($2); while (length($s2) < 4) { $s2 = "0$s2"; } $addr = $IPv6_REG{$s1}{substr($s2,0,2)}; unless ($addr) { $addr = $IPv6_REG{$s1}{substr($s2,0,1)}; } unless ($addr) { $addr = 'whois.ripe.net'; } } elsif (/^(?:[\w\240-\377.-]+\.)?([\w\240-\377-]+)\.([a-z]+)$/) { # Domain $stype = 'DOM'; if ($verbose) { print "Search type: domain.\n"; } my ($sld, $tld) = ($1, $2); if (/[\240-\377]/) { $s1 = $search = convert_idn($search); } if (exists $WHOIS_SLD{"$sld.$tld"}) { $addr = $WHOIS_SLD{"$sld.$tld"}; } elsif (exists $WHOIS_TLD{$tld}) { $addr = $WHOIS_TLD{$tld}; if ($addr =~/%S/) { $s1 = $sld; } } elsif (gethostbyname("whois.nic.$tld")) { $addr = "whois.nic.$tld"; } elsif (gethostbyname("whois.$tld")) { $addr = "whois.$tld"; } else { $addr = 'whois.networksolutions.com'; } if ($addr eq 'whois.internic.net') { $s1 = "domain $search"; } elsif ($addr eq 'whois.denic.de') { $s1 = "-T dn,ace -C UTF-8 $search"; } } elsif (/^[\w-]+$/) { # Handle $stype = 'HDL'; if ($verbose) { print "Search type: NIC handle.\n"; } if ((/(-[a-z]+)$/) && (exists $WHOIS_HANDLE{$1})) { $addr = $WHOIS_HANDLE{$1}; } elsif ((/^([a-z]+-)/) && (exists $WHOIS_HANDLE{$1})) { $addr = $WHOIS_HANDLE{$1}; } elsif (/^[a-z]+\d+$/) { $addr = 'whois.networksolutions.com'; } else { return "Kein Server gefunden / No server found.\n", 'none'; } if ($addr eq 'whois.networksolutions.com') { $s1 = "HANDLE $search"; } elsif ($addr eq 'whois.arin.net') { $s1 = "! $search"; } elsif ($addr eq 'whois.norid.no') { $s1 = uc($search); } elsif ($addr eq 'saudinic.net.sa') { $s1 = "PERSON $search"; } } else { return "Ungültige Anfrage / Invalid query.\n", 'none'; } if ($addr eq 'whois.nic.ad.jp') { $s1 .= '/e'; } $result = do_query($addr, $s1, $verbose); $h1 = $addr; if (($addr eq 'whois.arin.net') && ($stype eq 'IP')) { if ($result =~ /ReferralServer: whois:\/\/(.+)$/) { $h1 = $1; } elsif ($result =~ /Maintainer: RIPE|Allocated to RIPE|Transferred to RIPE/) { $h1 = 'whois.ripe.net'; } elsif ($result =~ /Maintainer: AP|Allocated to APNIC|Transferred to APNIC/) { $h1 = 'whois.apnic.net'; } elsif ($result =~ /Allocated to LACNIC|Transferred to LACNIC/) { $h1 = 'whois.lacnic.net'; } elsif ($result =~ /(rwhois\.[\w.]+) (?:port )?(\d+)/) { $h1 = "$1:$2"; } elsif ($result =~ /Netname: XOXO-BLK-/) { $h1 = 'rwhois.internex.net:4321'; } } if (($addr eq 'whois.apnic.net') && ($stype eq 'IP')) { if ($result =~ /KRNIC Whois|imported from KRNIC/) { $h1 = 'whois.krnic.net'; } elsif ($result =~ /JPNIC whois server at whois.nic.ad.jp/) { $h1 = 'whois.nic.ad.jp'; $search .= ' /e'; } } if (($addr eq 'whois.lacnic.net') && ($stype eq 'IP')) { if ($result =~ /at (whois\.registro\.br) /) { $h1 = $1; } } elsif ($addr eq 'whois.ripe.net') { if ($result =~ /remarks:\s+whois -h (\S+)/) { $h1 = $1; } } elsif ($result =~ /Whois Server:[\t ]+(\S+)/) { $h1 = $1; } if ($h1 ne $addr) { $r1 = do_query($h1, $search, $verbose); if ($r1 !~ /query to \S+ failed/) { $result = $r1; $addr = $h1; } } if ($addr =~ /^whois\.(krnic\.net|nic\.or\.kr)$/) { Encode::from_to($result, 'EUC-KR', 'utf-8'); } elsif ($addr eq 'whois.twnic.net.tw') { Encode::from_to($result, 'BIG5', 'utf-8'); } return $result, $addr; } sub whois { my ($search, $addr, $maxage); my ($qhost, $result, $cached); ($search, $addr, $maxage, $verbose) = @_; if ($maxage == undef) { $maxage = 600; } $search =~ s/^\s+//; $search =~ s/\s+$//; $addr = lc($addr); $search = lc($search); open (LOCK, ">>$LOCK_FILE"); if ((open LOCK, ">>$LOCK_FILE") && (flock(LOCK, 6))) { LOCK->autoflush(1); print LOCK "$$\n"; $cached = 1; tie (%CACHE, DB_File, $CACHE_FILE, O_RDWR|O_CREAT, 0755, $DB_HASH) || die "$CACHE_FILE: $!\n"; } else { $cached = 0; } $result = $CACHE{"$addr~~$search"}; if ($result) { $date = $CACHE{"TIME~~$addr~~$search"}; if (time() - $date > $maxage) { print "Object in cache too old.\n" if $verbose; undef($result); } else { $qhost = $CACHE{"HOST~~$addr~~$search"}; if ($verbose) { print "Object found in cache, host=$qhost.\n"; } } } unless ($result) { ($result, $qhost) = get_info($search, $verbose, $addr); if ($result !~ /query.*failed|Connection refused/) { $CACHE{"$addr~~$search"} = $result; $CACHE{"TIME~~$addr~~$search"} = time(); $CACHE{"HOST~~$addr~~$search"} = $qhost; } else { delete $CACHE{"$addr~~$search"}; delete $CACHE{"TIME~~$addr~~$search"}; delete $CACHE{"HOST~~$addr~~$search"}; } } if ($cached) { untie %CACHE; flock(LOCK, 8); close(LOCK); unlink $LOCK_FILE; } return $result, $qhost; } %IP_REG = ( '41' => 'whois.afrinic.net', '58' => 'whois.apnic.net', '59' => 'whois.apnic.net', '60' => 'whois.apnic.net', '61' => 'whois.apnic.net', '62' => 'whois.ripe.net', '80' => 'whois.ripe.net', '81' => 'whois.ripe.net', '82' => 'whois.ripe.net', '83' => 'whois.ripe.net', '84' => 'whois.ripe.net', '85' => 'whois.ripe.net', '86' => 'whois.ripe.net', '87' => 'whois.ripe.net', '88' => 'whois.ripe.net', '124' => 'whois.apnic.net', '125' => 'whois.apnic.net', '126' => 'whois.apnic.net', '145' => 'whois.ripe.net', '189' => 'whois.lacnic.net', '190' => 'whois.lacnic.net', '193' => 'whois.ripe.net', '194' => 'whois.ripe.net', '195' => 'whois.ripe.net', '200' => 'whois.lacnic.net', '201' => 'whois.lacnic.net', '202' => 'whois.apnic.net', '203' => 'whois.apnic.net', '210' => 'whois.apnic.net', '211' => 'whois.apnic.net', '212' => 'whois.ripe.net', '213' => 'whois.ripe.net', '217' => 'whois.ripe.net', '218' => 'whois.apnic.net', '219' => 'whois.apnic.net', '220' => 'whois.apnic.net', '221' => 'whois.apnic.net', '222' => 'whois.apnic.net', ); %IPv6_REG = ( '2001' => { '02' => 'whois.apnic.net', '03' => 'whois.apnic.net', '04' => 'whois.arin.net', '05' => 'whois.arin.net', '06' => 'whois.ripe.net', '07' => 'whois.ripe.net', '08' => 'whois.ripe.net', '09' => 'whois.ripe.net', '0A' => 'whois.ripe.net', '0B' => 'whois.ripe.net', '0C' => 'whois.apnic.net', '0D' => 'whois.apnic.net', '0E' => 'whois.apnic.net', '0F' => 'whois.apnic.net', '12' => 'whois.lacnic.net', '13' => 'whois.lacnic.net', '14' => 'whois.ripe.net', '15' => 'whois.ripe.net', '16' => 'whois.ripe.net', '17' => 'whois.ripe.net', '18' => 'whois.arin.net', '19' => 'whois.arin.net', '1A' => 'whois.ripe.net', '1B' => 'whois.ripe.net', '1C' => 'whois.ripe.net', '1D' => 'whois.ripe.net', '1E' => 'whois.ripe.net', '1F' => 'whois.ripe.net', '2' => 'whois.ripe.net', '3' => 'whois.ripe.net', '40' => 'whois.ripe.net', '41' => 'whois.ripe.net', '42' => 'whois.arin.net', '43' => 'whois.arin.net', '44' => 'whois.apnic.net', '45' => 'whois.apnic.net', '46' => 'whois.ripe.net', '47' => 'whois.ripe.net', '48' => 'whois.arin.net', '49' => 'whois.arin.net', '4A' => 'whois.ripe.net', '4B' => 'whois.ripe.net', '4C' => 'whois.ripe.net', '4D' => 'whois.ripe.net', '5' => 'whois.ripe.net', '8' => 'whois.apnic.net', '9' => 'whois.apnic.net', 'A' => 'whois.apnic.net', }, '2400' => { '0' => 'whois.apnic.net', '1' => 'whois.apnic.net', }, '2600' => { '0' => 'whois.arin.net', }, '2604' => { '0' => 'whois.arin.net', }, '2608' => { '0' => 'whois.arin.net', }, '260C' => { '0' => 'whois.arin.net', }, ); %WHOIS_TLD = ( 'ae' => 'whois.uaenic.ae', 'ai' => 'whois.ainic.ai', 'ar' => 'http://www.nic.ar/consultas/consdom.html POST=nombre=%D', 'at' => 'whois.aco.net', 'arpa' => 'whois.iana.org', 'au' => 'whois.aunic.net', 'be' => 'whois.dns.be', 'bg' => 'whois.digsys.bg', 'bi' => 'http://www.nic.bi/Nic_search_result2.asp?search=%D&Submit=SEND+INFORMATIONS', 'bm' => 'rwhois.ibl.bm:4321', 'bs' => 'http://dns.nic.bs/cgi-bin/search.pl?dname=%D&ok=submit', 'bv' => 'whois.norid.no', 'bz' => 'whois.belizenic.bz', 'by' => 'http://www.tld.by/cgi-bin/checkdomain.cgi?domain=%D&lang=e&mode=slquest', 'ca' => 'whois.cira.ca', 'cg' => 'http://www.nic.cg/cgi-bin/whoiscg.pl POST=DOMAINWHOIS=%D', 'cn' => 'whois.cnnic.cn', 'cr' => 'http://www.nic.cr/cgi-bin/consulta-dns.pl POST=domdns=%D', 'com' => 'whois.internic.net', 'de' => 'whois.denic.de', 'edu' => 'whois.educause.net', 'ee' => 'whois.eenet.ee', 'es' => 'https://www.nic.es/esnic/servlet/WhoisControllerHTML?tipo=dominio&dominio=%D', 'fi' => 'whois.ripe.net', 'fj' => 'whois.usp.ac.fj', 'fm' => 'http://www.dot.fm/query_whois.cfm?domain2findamfm=%S&tld=fm', 'fo' => 'whois.ripe.net', 'ge' => 'whois.sanet.ge', 'gf' => 'whois.nplus.gf', 'gg' => 'whois.isles.net', 'gi' => 'http://whois.gibnet.gi/?lookup=%D', 'gm' => 'whois.ripe.net', 'gr' => 'whois.ripe.net', 'gs' => 'http://adamsnames.tc/whois/?domain=%D', 'hk' => 'whois.hkdnr.net.hk', 'hm' => 'whois.registry.hm', 'hr' => 'http://www.dns.hr/asp/trazidomenu.asp POST=Upit=%D&Submit=Tra¾i', 'id' => 'whois.idnic.net.id', 'ie' => 'whois.domainregistry.ie', 'il' => 'whois.isoc.org.il', 'in' => 'http://domain.ncst.ernet.in/search_reply.php POST=Domain_Name=%D', 'info' => 'whois.afilias.info', 'int' => 'whois.iana.org', 'je' => 'whois.isles.net', 'kh' => 'whois.khnic.net.kh', 'jp' => 'whois.nic.ad.jp', 'kr' => 'whois.nic.or.kr', 'li' => 'whois.nic.ch', 'lt' => 'whois.ripe.net', 'lu' => 'whois.restena.lu', 'lv' => 'whois.ripe.net', 'mc' => 'whois.ripe.net', 'md' => 'http://www.register.md/whois.jsp?domainName=%S', 'ms' => 'http://adamsnames.tc/whois/?domain=%D', 'net' => 'whois.internic.net', 'no' => 'whois.norid.no', 'nz' => 'whois.domainz.net.nz', 'org' => 'whois.publicinterestregistry.net', 'pe' => 'http://www.nic.pe/rpublicac.php?txtbuscar=%D&radopcion=D', 'pl' => 'whois.nask.pl', 'pm' => 'whois.nic.fr', 'pt' => 'whois.dns.pt', 'ru' => 'whois.ripn.net', 'sa' => 'saudinic.net.sa', 'se' => 'http://www.nic-se.se/cgi-bin/whois/www-to-whois?domain=%D', 'sg' => 'whois.nic.net.sg', 'si' => 'whois.arnes.si', 'sk' => 'whois.sk-nic.sk', 'sm' => 'whois.ripe.net', 'tc' => 'http://adamsnames.tc/whois/?domain=%D', 'tf' => 'http://adamsnames.tc/whois/?domain=%D', 'th' => 'whois.thnic.net', 'to' => 'whois.tonic.to', 'tr' => 'whois.ripe.net', 'tw' => 'whois.twnic.net.tw', 'ua' => 'whois.net.ua', 'va' => 'whois.ripe.net', 'vg' => 'http://adamsnames.tc/whois/?domain=%D', 'vu' => 'http://www.vunic.vu/whois POST=whois=%D', ); %WHOIS_SLD = ( 'priv.at' => 'whois.nic.priv.at', 'asn.au' => 'whois.ausregistry.net.au', 'com.au' => 'whois.ausregistry.net.au', 'id.au' => 'whois.ausregistry.net.au', 'net.au' => 'whois.ausregistry.net.au', 'org.au' => 'whois.ausregistry.net.au', 'au.com' => 'whois.au.com', 'ac.uk' => 'whois.ja.net', 'gov.uk' => 'whois.ja.net', 'de.vu' => 'http://www.vunic.vu/whois POST=whois=de.vu', 'ac.za' => 'http://whois.ac.za/cgi/cgi_DomainQuery.exe?domain=%D', 'co.za' => 'http://co.za/cgi-bin/whois.sh?Domain=%D', ); %WHOIS_HANDLE = ( '-abc' => 'whois.tmagnic.net', '-arin' => 'whois.arin.net', '-frnic' => 'whois.nic.fr', '-hst' => 'whois.networksolutions.com', '-itnic' => 'whois.nic.it', '-nicat' => 'whois.nic.at', '-norid' => 'whois.norid.no', '-sa' => => 'saudinic.net.sa', '-ripe' => 'whois.ripe.net', '-ripn' => 'whois.ripn.net', '-uanic' => 'whois.net.ua', '-vrio' => 'rwhois.verio.net:4321', 'coco-' => 'whois.corenic.net', 'core-' => 'whois.corenic.net', 'net-' => 'whois.arin.net', 'netblk-' => 'whois.arin.net', ); %COUNTRY_NAMES = ( 'AC', 'Ascension Island', 'AD', 'Andorra', 'AE', 'United Arab Emirates', 'AF', 'Afghanistan', 'AG', 'Antigua and Barbuda', 'AI', 'Anguilla', 'AL', 'Albania', 'AM', 'Armenia', 'AN', 'Netherland Antilles', 'AO', 'Angola', 'AQ', 'Antarctica', 'AR', 'Argentina', 'AS', 'American Samoa', 'AT', 'Austria', 'AU', 'Australia', 'AW', 'Aruba', 'AZ', 'Azerbaijan', 'BA', 'Bosnia-Herzegovina', 'BB', 'Barbados', 'BD', 'Bangladesh', 'BE', 'Belgium', 'BF', 'Burkina Faso', 'BG', 'Bulgaria', 'BH', 'Bahrain', 'BI', 'Burundi', 'BJ', 'Benin', 'BM', 'Bermuda', 'BN', 'Brunei Darussalam', 'BO', 'Bolivia', 'BR', 'Brazil', 'BS', 'Bahamas', 'BT', 'Bhutan', 'BV', 'Bouvet Island', 'BW', 'Botswana', 'BY', 'Belarus', 'BZ', 'Belize', 'CA', 'Canada', 'CC', 'Cocos (Keeling) Isl.', 'CD', 'Dem. Repub. of Congo', 'CF', 'Central African Rep.', 'CG', 'Congo', 'CH', 'Switzerland', 'CI', 'Ivory Coast', 'CK', 'Cook Islands', 'CL', 'Chile', 'CM', 'Cameroon', 'CN', 'China', 'CO', 'Colombia', 'CR', 'Costa Rica', 'CU', 'Cuba', 'CV', 'Cape Verde', 'CX', 'Christmas Island', 'CY', 'Cyprus', 'CZ', 'Czech Republic', 'DE', 'Germany', 'DJ', 'Djibouti', 'DK', 'Denmark', 'DM', 'Dominica', 'DO', 'Dominican Republic', 'DZ', 'Algeria', 'EC', 'Ecuador', 'EE', 'Estonia', 'EG', 'Egypt', 'EH', 'Western Sahara', 'ER', 'Eritrea', 'ES', 'Spain', 'ET', 'Ethiopia', 'FI', 'Finland', 'FJ', 'Fiji', 'FK', 'Falkland Isl.(Malvinas)', 'FM', 'Micronesia', 'FO', 'Faroe Islands', 'FR', 'France', 'FX', 'France', 'GA', 'Gabon', 'GB', 'Great Britain', 'GD', 'Grenada', 'GE', 'Georgia', 'GF', 'Guiana', 'GG', 'Guernsey', 'GH', 'Ghana', 'GI', 'Gibraltar', 'GL', 'Greenland', 'GM', 'Gambia', 'GN', 'Guinea', 'GP', 'Guadeloupe', 'GQ', 'Equatorial Guinea', 'GR', 'Greece', 'GS', 'South Georgia and South Sandwich Islands', 'GT', 'Guatemala', 'GU', 'Guam', 'GW', 'Guinea Bissau', 'GY', 'Guyana', 'HK', 'Hong Kong', 'HM', 'Heard & McDonald Isl.', 'HN', 'Honduras', 'HR', 'Croatia', 'HT', 'Haiti', 'HU', 'Hungary', 'ID', 'Indonesia', 'IE', 'Ireland', 'IL', 'Israel', 'IN', 'India', 'IM', 'Isle of Man', 'IO', 'British Indian O. Ter.', 'IQ', 'Iraq', 'IR', 'Iran', 'IS', 'Iceland', 'IT', 'Italy', 'JE', 'Jersey', 'JM', 'Jamaica', 'JO', 'Jordan', 'JP', 'Japan', 'KE', 'Kenya', 'KG', 'Kyrgyz Republic', 'KH', 'Cambodia', 'KI', 'Kiribati', 'KM', 'Comoros', 'KN', 'St.Kitts Nevis Anguilla', 'KP', 'Noth Korea', 'KR', 'South Korea', 'KW', 'Kuwait', 'KY', 'Cayman Islands', 'KZ', 'Kazakstan', 'LA', 'Laos', 'LB', 'Lebanon', 'LC', 'Saint Lucia', 'LI', 'Liechtenstein', 'LK', 'Sri Lanka', 'LR', 'Liberia', 'LS', 'Lesotho', 'LT', 'Lithuania', 'LU', 'Luxembourg', 'LV', 'Latvia', 'LY', 'Libya', 'MA', 'Morocco', 'MC', 'Monaco', 'MD', 'Moldova', 'MG', 'Madagascar', 'MH', 'Marshall Islands', 'MK', 'Macedonia', 'ML', 'Mali', 'MM', 'Myanmar', 'MN', 'Mongolia', 'MO', 'Macau', 'MP', 'Northern Mariana Isl.', 'MQ', 'Martinique', 'MR', 'Mauritania', 'MS', 'Montserrat', 'MT', 'Malta', 'MU', 'Mauritius', 'MV', 'Maldives', 'MW', 'Malawi', 'MX', 'Mexico', 'MY', 'Malaysia', 'MZ', 'Mozambique', 'NA', 'Namibia', 'NC', 'New Caledonia', 'NE', 'Niger', 'NF', 'Norfolk Island', 'NG', 'Nigeria', 'NI', 'Nicaragua', 'NL', 'Netherlands', 'NO', 'Norway', 'NP', 'Nepal', 'NR', 'Nauru', 'NU', 'Niue', 'NZ', 'New Zealand', 'OM', 'Oman', 'PA', 'Panama', 'PE', 'Peru', 'PF', 'Polynesia', 'PG', 'Papua New Guinea', 'PH', 'Philippines', 'PK', 'Pakistan', 'PL', 'Poland', 'PM', 'St. Pierre & Miquelon', 'PN', 'Pitcairn', 'PR', 'Puerto Rico', 'PT', 'Portugal', 'PW', 'Palau', 'PY', 'Paraguay', 'QA', 'Qatar', 'RE', 'Reunion', 'RO', 'Romania', 'RU', 'Russian Federation', 'RW', 'Rwanda', 'SA', 'Saudi Arabia', 'SB', 'Solomon Islands', 'SC', 'Seychelles', 'SD', 'Sudan', 'SE', 'Sweden', 'SG', 'Singapore', 'SH', 'St. Helena', 'SI', 'Slovenia', 'SJ', 'Svalbard & Jan Mayen Islands', 'SK', 'Slovakia', 'SL', 'Sierra Leone', 'SM', 'San Marino', 'SN', 'Senegal', 'SO', 'Somalia', 'SR', 'Suriname', 'ST', 'St. Tome and Principe', 'SU', 'Soviet Union', 'SV', 'El Salvador', 'SY', 'Syria', 'SZ', 'Swaziland', 'TC', 'Turks & Caicos Islands', 'TD', 'Chad', 'TF', 'French Southern Terr.', 'TG', 'Togo', 'TH', 'Thailand', 'TJ', 'Tadjikistan', 'TK', 'Tokelau', 'TM', 'Turkmenistan', 'TN', 'Tunisia', 'TO', 'Tonga', 'TP', 'East Timor', 'TR', 'Turkey', 'TT', 'Trinidad & Tobago', 'TV', 'Tuvalu', 'TW', 'Taiwan', 'TZ', 'Tanzania', 'UA', 'Ukraine', 'UG', 'Uganda', 'UK', 'United Kingdom', 'UM', 'US Minor outlying Islands', 'US', 'United States', 'UY', 'Uruguay', 'UZ', 'Uzbekistan', 'VA', 'Vatican City State', 'VC', 'St.Vincent & Grenadines', 'VE', 'Venezuela', 'VG', 'Virgin Islands (Brit)', 'VI', 'Virgin Islands (US)', 'VN', 'Vietnam', 'VU', 'Vanuatu', 'WF', 'Wallis & Futuna Islands', 'WS', 'Western Samoa', 'YE', 'Yemen', 'YT', 'Mayotte', 'YU', 'Yugoslavia', 'ZA', 'South Africa', 'ZM', 'Zambia', 'ZR', 'Dem. Rep. of Congo', 'ZW', 'Zimbabwe' ); 1; ######## Ende