PHPで携帯キャリアのIPアドレス帯域を求める

(1/1)
携帯サイトでは、携帯キャリア各社が利用している IP 帯域を調べ、携帯電話からのアクセスかどうかを確認することが多い。この IP 帯域は、携帯キャリア各社が公表している。
今回は、PHP を使って公表データの IP 帯域の部分を抽出・表示するプログラムを作ってみることにする。

サンプル・プログラムの実行例

PHPで携帯キャリアのIPアドレス帯域を求める

サンプル・プログラム

解説:IP帯域の取得処理

0164: /**
0165:  * NTTドコモのIPアドレス帯域を取得する
0166:  * @return array IPアドレス帯域を示す配列
0167: */
0168: function getDoCoMo() {
0169:     $url = 'https://www.nttdocomo.co.jp/service/developer/smart_phone/spmode/index.html';
0170:     $IPs = FALSE;
0171:     $cnt = 0;
0172: 
0173:     if (($infp = @fopen($url, 'r')) == FALSE)    return FALSE;
0174:     $IPs['DoCoMo'][$cnt] = '#DoCoMo';
0175:     $cnt++;
0176: 
0177:     //IPアドレス帯域までスキップ
0178:     while (! feof($infp)) {
0179:         $s = mb_convert_encoding(fgets($infp), INTERNAL_ENCODING, 'SJIS');
0180:         if (preg_match('/<h2 class\="title">/u', $s) > 0)     break;
0181:     }
0182: 
0183:     //IPアドレス帯域を読み込む
0184:     while (! feof($infp)) {
0185:         $s = mb_convert_encoding(fgets($infp), INTERNAL_ENCODING, 'SJIS');
0186:         if (preg_match('/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+)/iu', $s$arr) > 0) {
0187:             $IPs['DoCoMo'][$cnt] = $arr[1];
0188:             $cnt++;
0189:         }
0190:     }
0191:     fclose($infp);
0192: 
0193:     return $IPs;
0194: }

0196: /**
0197:  * au by KDDIのIPアドレス帯域を取得する
0198:  * @return array IPアドレス帯域を示す配列
0199: */
0200: function getAu() {
0201:     $url = 'http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html';
0202:     $IPs = FALSE;
0203:     $cnt = 0;
0204: 
0205:     if (($infp = @fopen($url, 'r')) == FALSE)    return FALSE;
0206:     $IPs['au'][$cnt] = '#au';
0207:     $cnt++;
0208: 
0209:     //IPアドレス帯域を読み込む
0210:     while (! feof($infp)) {
0211:         $s = mb_convert_encoding(fgets($infp), INTERNAL_ENCODING, 'SJIS');
0212:         if (preg_match('/<td[^\>]*><div class="TableText">(.+)<\/div><\/td>/u', $s$arr) > 0) {
0213:             $s1 = strip_tags($arr[1]);
0214:             if (preg_match('/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/u', $s1) == 0)  continue;
0215:             $s = mb_convert_encoding(fgets($infp), INTERNAL_ENCODING, 'SJIS');
0216:             $s2 = '';
0217:             if (preg_match('/(\/[0-9]+)/u', $s$arr) > 0)    $s2 = $arr[1];
0218:             $IPs['au'][$cnt] = $s1 . $s2;
0219:             $cnt++;
0220:         }
0221:     }
0222:     fclose($infp);
0223:     
0224:     return $IPs;
0225: }

0227: /**
0228:  * SoftBankのIPアドレス帯域を取得する
0229:  * @return array IPアドレス帯域を示す配列
0230: */
0231: function getSoftBank() {
0232:     $url = 'http://creation.mb.softbank.jp/mc/tech/tech_web/web_ipaddress.html';
0233:     $IPs = FALSE;
0234:     $cnt = 0;
0235: 
0236:     if (($infp = @fopen($url, 'r')) == FALSE)    return FALSE;
0237:     $IPs['SoftBank'][$cnt] = '#SoftBank';
0238:     $cnt++;
0239: 
0240:     //IPアドレス帯域までスキップ
0241:     while (! feof($infp)) {
0242:         $s = fgets($infp);
0243:         if (preg_match('/<h4>IPアドレス<\/h4>/u', $s) > 0)    break;
0244:     }
0245: 
0246:     //IPアドレス帯域を読み込む
0247:     while (! feof($infp)) {
0248:         $s = fgets($infp);
0249:         if (preg_match('/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+)/u', $s$arr) > 0) {
0250:             $IPs['SoftBank'][$cnt] = $arr[1];
0251:             $cnt++;
0252:         }
0253:     }
0254:     fclose($infp);
0255: 
0256:     return $IPs;
0257: }

0259: /**
0260:  * ワイモバイル(EMOBILE)のIPアドレス帯域を取得する
0261:  * @return array IPアドレス帯域を示す配列
0262: */
0263: function getEMnet() {
0264:     $url = 'http://developer.emnet.ne.jp/ipaddress.html';
0265:     $IPs = FALSE;
0266:     $cnt = 0;
0267: 
0268:     if (($infp = @fopen($url, 'r')) == FALSE)    return FALSE;
0269:     $IPs['EMnet'][$cnt] = '#EMnet';
0270:     $cnt++;
0271: 
0272:     //IPアドレス帯域を読み込む
0273:     while (! feof($infp)) {
0274:         $s = fgets($infp);
0275:         if (preg_match('/\<div.+?>([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+)/u', $s$arr) > 0) {
0276:             $IPs['EMnet'][$cnt] = $arr[1];
0277:             $cnt++;
0278:         }
0279:     }
0280:     fclose($infp);
0281: 
0282:     return $IPs;
0283: }

0285: /**
0286:  * 全キャリアのIPアドレス帯域を取得する
0287:  * @return array IPアドレス帯域を示す配列
0288: */
0289: function getAll() {
0290:     $IPs = array();
0291:     if (($arr[1] = getDoCoMo()) == FALSE)       return FALSE;
0292:     if (($arr[2] = getAu()) == FALSE)           return FALSE;
0293:     if (($arr[3] = getSoftBank()) == FALSEreturn FALSE;
0294:     if (($arr[4] = getEMnet()) == FALSE)        return FALSE;
0295: 
0296:     foreach ($arr as $arr2) {
0297:         foreach ($arr2 as $carrier=>$val) {
0298:             foreach ($val as $key=>$ip)     $IPs[$carrier][$key] = $ip;
0299:         }
0300:     }
0301:     return $IPs;
0302: }

携帯キャリア各社は、下記ページで IP 帯域を公表している。
各々のページの構造を解析して作ったのが、取得処理用のユーザー関数 getDoCoMo, getAu, getSoftBank, getEMnet である。

構造は簡単で、IP アドレス帯域が羅列されている部分までスキップし、正規表現を使って IP アドレスを取り出すというものである。getAu については、スキップ処理は行わない。
ただし、このような取得方法をしているため、各社の公表ページの仕様やレイアウトが変わると、このプログラムは正常に動かなくなってしまう。

プログラムのアウトプットは、Apache の ".htaccess" にそのまま利用できるテキスト形式にした。

参考サイト

(この項おわり)
header