PEAR::Net_Whois で IP アドレスから国名を調べる関数
アクセス元のホストの国籍を Apache のログからアクセス解析して、って頼まれたけど、どうしたらいいのかわからなくてスクリプトを書いてみた。
いろいろ調べたら、PHP の PEAR::Net_Whois を使えば、Whois 情報を取得できることがわかった。
サーバーに PEAR::Net_Socket と PEAR::Net_Whois をインストールする。
$ pear install Net_Socket $ pear install Net_Whois
でも、$whois->query() を行うときに、検索先の Whois サーバを指定しないといけない。
InterNIC のサイトを見る限り、IP アドレスの第 1 オクテット目ごとに、地域インターネット レジストラ (RIR) が決まっているらしい。(IP アドレスの割り当て状況)
それを参考に IP アドレスから、PEAR::Net_Whois を行う関数を作った。以下の通り。
function getWhoisFromIPAddr($ipaddr){ //Include PEAR::Net_Whois require_once("Net/Whois.php"); $whois = new Net_Whois; //Split IPaddr into 4 octets. preg_match("/^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})(.*)/",$ipaddr,$oct); //Choose WHOIS server by 1st octet. if($oct[1]<=40){ $server="whois.arin.net"; } elseif($oct[1]==41){ $server="whois.afrinic.net"; } elseif($oct[1]<=57){ $server="whois.arin.net"; } elseif($oct[1]<=61){ $server="whois.apnic.net"; } elseif($oct[1]==62){ $server="whois.ripe.net"; } elseif($oct[1]<=61){ $server="whois.apnic.net"; } elseif($oct[1]<=76){ $server="whois.arin.net"; } elseif($oct[1]<=95){ $server="whois.ripe.net"; } elseif($oct[1]<=113){ $server="whois.arin.net"; } elseif($oct[1]<=126){ $server="whois.apnic.net"; } elseif($oct[1]<=132){ $server="whois.arin.net"; } // elseif($oct[1]==133){ $server="whois.apnic.net"; } elseif($oct[1]<=140){ $server="whois.arin.net"; } elseif($oct[1]==141){ $server="whois.ripe.net"; } elseif($oct[1]<=144){ $server="whois.arin.net"; } elseif($oct[1]==145){ $server="whois.ripe.net"; } elseif($oct[1]<=149){ $server="whois.arin.net"; } elseif($oct[1]==150){ $server="whois.apnic.net"; } elseif($oct[1]==151){ $server="whois.ripe.net"; } elseif($oct[1]==152){ $server="whois.arin.net"; } elseif($oct[1]==153){ $server="whois.apnic.net"; } elseif($oct[1]==154){ $server="whois.afrinic.net"; } elseif($oct[1]<=162){ $server="whois.arin.net"; } elseif($oct[1]==163){ $server="whois.apnic.net"; } elseif($oct[1]<=170){ $server="whois.arin.net"; } elseif($oct[1]<=171){ $server="whois.apnic.net"; } elseif($oct[1]<=185){ $server="whois.arin.net"; } elseif($oct[1]<=187){ $server="whois.lacnic.net"; } elseif($oct[1]<=188){ $server="whois.ripe.net"; } elseif($oct[1]<=191){ $server="whois.lacnic.net"; } elseif($oct[1]==192){ $server="whois.arin.net"; } elseif($oct[1]<=195){ $server="whois.ripe.net"; } elseif($oct[1]==196){ $server="whois.afrinic.net"; } elseif($oct[1]<=199){ $server="whois.arin.net"; } elseif($oct[1]<=201){ $server="whois.lacnic.net"; } elseif($oct[1]<=203){ $server="whois.apnic.net"; } elseif($oct[1]<=209){ $server="whois.arin.net"; } elseif($oct[1]<=211){ $server="whois.apnic.net"; } elseif($oct[1]<=213){ $server="whois.ripe.net"; } elseif($oct[1]<=216){ $server="whois.arin.net"; } elseif($oct[1]<=217){ $server="whois.ripe.net"; } elseif($oct[1]<=222){ $server="whois.apnic.net"; } elseif($oct[1]<=255){ $server="whois.arin.net"; } else; //Exec query to chose WHOIS server. if($server){ return($reply=$whois->query($ipaddr,$server)); } else{ return(0); } }
133 で始まる IP アドレスといえば専ら、日本政府の機関、日本の国立大学法人 (うちの大学もそう)、日本の IT 企業のアドレスだから、APNIC なはずだけど、エラーがでるので、ARIN に問い合わせしている。
本来なら、エラーメッセージをもとに 2 次検索すべきなんだろうけど面倒なので省略する。
Whois 情報が返ってくるので、それを引数にしてに以下の関数を実行する。
function getCountryByWhois($result){ preg_match("/country:( )*([a-zA-Z]{1,3})/i",$result,$country); if($country[2]){ return($country[2]); } else{ return(0); } }
2 つの関数は、以下のようにして使える。
echo("Who is 133.62.198.174 ?<br />\n"); $result=getWhoisFromIPAddr("133.62.198.174"); echo("Country: ".getCountryByWhois($result));
実行すると、「Country: JP」とカントリーコードが出力される。
蛇足だけど、IP アドレスから会社名や法人名を調べるには、JPNIC のサーバ (whois.nic.ad.jp) に対して、$whois->query() を行えばよい。海外の企業も各国の下位レジストラの Whois サーバに置き換えれば検索できる。