IPアドレスの携帯判定処理について
携帯IPアドレスと携帯端末固有番号によるチェック処理を実装しようとしたけど
仕様上の問題でポシャりそうな感じなのでここにでも残す
IPアドレスは各キャリアともHP上に公開されており、
・docomo
・au
・softbank
・emobile
・willcom
で、上記HPリストのIPアドレスかどうかで携帯orPC、キャリアの判定する。
IPリストはデータベースに格納
開発はphpなのでPEARモジュールでIPアドレスを取得するモジュールを
探したけどなかったのでperlのNet::CIDR::MobileJPを利用させて頂く。
(ちなみにemobileは非対応だが3キャリアのIPが欲しかったので無問題)
CPANからモジュールをインスコ
# perl -MCPAN -eshell
cpan> install Net::CIDR::MobileJP
cpan> install Net::CIDR
↓のファイルを適当なディレクトリにコピって試しに実行
/usr/lib/perl5/site_perl/5.8.8/Net/CIDR/net-cidr-mobilejp-scraper.pl
$ perl net-cidr-mobilejp-scraper.pl
- -
E:
- 210.230.128.224/28
- 121.111.227.160/27
- 61.117.1.0/28
CIDR形式で出力されるがこのままではデータベースでのチェック処理には向かないので
CIDRをIPアドレスのリストへ出力する関数を作成
ちなみにNet::CIDR::cidr2octetsはクラスC以上のアドレスだと下のオクテットが省略されるので
自分で展開してます
(例えば「210.230.128.0/24」を指定すると「210.230.128」が出力される)
sub myCidr2octets
{
my ($cidr) = @_;
my @list = Net::CIDR::cidr2octets($cidr);return &setupIpaddrList(@list);
}sub setupIpaddrList
{
my (@source) = @_;
my @dist = ();
foreach my $ip_source ( @source )
{
my @work = split(/\./, $ip_source);
my $cnt = @work;$cnt = 4 - $cnt;
if( $cnt )
{
my @next = ();
for( my $i = 0; $i <= 255; $i++)
{
push(@next, $ip_source.'.'.$i);
}push(@dist, &setupIpaddrList(@next));
}
else
{
push(@dist, ($ip_source) );
}
}
return @dist;
}
これを「net-cidr-mobilejp-scraper.pl」に組み込んでデータベースに格納
データベース定義はこんな感じ
(IPをintで格納すると落とし穴がありそうなのでcharにしてます)
CREATE TABLE `mobile_carrier_ip` (
`mobile_carrier_id` int(10) unsigned NOT NULL auto_increment,
`carrier_code` char(1) NOT NULL,
`ip_address` char(15) NOT NULL,
`created_at` datetime default NULL,
`update_at` datetime default NULL,
PRIMARY KEY (`mobile_carrier_id`),
UNIQUE KEY `uniq_idx_ip_addr` (`ip_address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
symfonyのfilterからクライアントIPアドレスを検索にかけてチェックを実装
(memcacheの利用とかも妄想)
ちなみにデータを入れてみた所、4776件だったのでデータ数的には大した事は無いです。