
あるIP以外のアクセスを制限する場合は、以下処理で良いものと思っています。
if ("210.161.126.144" != $REMOTE_ADDR){
# アクセス制限の関数呼び出し
hoge2();
}
今回、サブネットマスクを用いて、ある範囲のIPにのみアクセス許可をしたいと思っています。
例えば、以下の範囲のIPのみ許したいと思います。
210.161.126.144-210.161.126.159
実際には、プリフィックスを用いた 210.161.126.144/28 の形で許可IPのデータを持つつもりです。
この場合、どのような処理を行ったらよいのでしょうか?
サブネットマスク含めネットワークの知識が足りない為か、ロジックがとても思いつきません。
210.161.126.144/28 から、210.161.126.144-210.161.126.159を算出する方法もピンときません。
判定処理は関数化してしまい、以下のような感じにしたいと思っております。
$permit_ip = "210.161.126.144/28";
if (!hoge($REMOTE_ADDR,$ip)){
# アクセス制限の関数呼び出し
hoge2();
}
# 引数1のIPが、引数2のIPの範囲内であるか判定する関数
function hoge($p_ip,$p_permit_ip){
if (){
# 範囲内
true;
} else {
# 範囲外
false;
}
}
どうかご教授宜しくお願い致します。
No.4ベストアンサー
- 回答日時:
No.1さんの回答を見て改良しました
<?php
function hoge($p_ip, $p_permit_ip){
list($ip, $mask_bit) = explode("/", $p_permit_ip);
$ip_long = ip2long($ip) >> (32 - $mask_bit);
$p_ip_long = ip2long($p_ip) >> (32 - $mask_bit);
if ($p_ip_long == $ip_long) {
return true;
}
else {
return false;
}
}
$permit_ip = "210.161.126.144/28";
$test_ip = "210.161.126.144";
if (hoge($test_ip, $permit_ip)) echo "OK";
else echo "NG";
?>
サンプルコード、ありがとうございます。
改良後のコードが分かりやすいです。
ビット演算子はこういう時に使うものなんですね。
大変参考になりました。
No.3
- 回答日時:
こうですかね
<?php
function hoge($p_ip, $p_permit_ip){
list($ip, $mask_bit) = explode("/", $p_permit_ip);
$ip_long = ip2long($ip);
$start = ($ip_long >> (32 - $mask_bit)) << (32 - $mask_bit);
$end = $start | (1 << (32 - $mask_bit + 1)) - 1;
$p_ip_long = ip2long($p_ip);
if (($p_ip_long >= $start) and ($p_ip_long <= $end)) {
return true;
}
else {
return false;
}
}
$permit_ip = "210.161.126.145/28";
$test_ip = "210.161.126.159";
if (hoge($test_ip, $permit_ip)) echo "OK";
else echo "NG";
?>
No.2
- 回答日時:
list($a,$b,$c,$d) = explode(".",$IP);
if($a == 210 and $b == 161 and $c == 126) {
if (144 <= $d and $d <= 159) {
#OK
}
}
としたほうが早いような・・・
もしかしたら#1さんのように二進数にしたほうが早いかもしれません。
プレフィックスを使用せずに、許可IPも固定であればそれで十分ではありますが、少々質問の意図とずれてしまっているようです。
せっかくご回答頂いたのに申し訳ありません。
No.1
- 回答日時:
IPアドレス(IPv4)は4つの数字で書かれますが、内部的には32ケタの二進数です。
そのままでは見にくいので、人間にも分かりやすいように8bitずつの四つに区切り、それぞれを10進法表記したのが210.161.126.144の形式です。
だから各項の最大が255 ( 2の8乗ひく1 ) なんですね。
210.161.126.144 および210.161.126.159を二進数で表すと、
11010010 10100001 1111110 10010000
11010010 10100001 1111110 10011111
となり、はじめの28ケタが共通しているのが分かると思います。
この共通部分の長さをプレフィックス長といいます。
この範囲内にアドレスが含まれるとき、そのアドレスは
11010010 10100001 1111110 1001XXXX
という形式をしているはずです。
これに当てはまるかどうか知りたければ、下の4ケタをゼロにしてから
11010010 10100001 1111110 10010000
と同じか判定すればいいですね。
それをするための判定式がサブネットマスクです。
サブネットマスクは、プレフィックス長とおなじ長さだけ1が続き、残りが0の32ケタのビットパターンです。
たとえば今回の例で言えば、初めの28ケタが1で残りがゼロの数字ですから、
11111111 11111111 11111111 11110000
という感じになります。
で、これと元のIPとの「ビットごとのand」を取れば、元のIPの上28ケタはそのままで下4ケタはゼロになります。
「ビットごとのand」というのは、
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
で定められる計算を各ケタにやっているだけです。
http://www.net-newbie.com/tcpip/terms.html
こちらの「ビットごとのAND」の項目などをご参照のこと。
なお、サブネットマスクの1が続く長さをプレフィックス長というのが元々なので、ちょっと説明が変ですがご容赦を。
またPHPでプレフィックス長を含んだIPアドレスの文字列を扱いやすい形に変換する関数が準備されているかどうかは存じません。自作の必要があるかも知れません。
大変わかりやすく、非常に参考になりました!
No.1さんの解説を読んだ後にNo.4さんのサンプルコードを見ましたがロジックの理解が得られました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA コレクションに2次元配列...
-
VB.NETからVBAマクロ(引数)を呼...
-
VB6のコンボボックスのテキスト...
-
既存関数の上書き
-
PHP の system コマンド
-
Dosブロンプトでtabを出力したい
-
wordの差し込み印刷で文字...
-
バッチファイルでpingの結果を...
-
shシェルスクリプト 空白行の...
-
フォームを使わずにPOST送信す...
-
セッション変数の命名規則
-
POSTで受け渡したものを保存し...
-
開始と終了を指定して、その間...
-
curlで取得出来るデータの制限...
-
vbsのif文で複数条件の判定
-
ps3で久しぶりにCDの音楽情報取...
-
strtok関数の使い方
-
カレンダーの今日の日付をハイ...
-
ローカルのコンピュータ名を取...
-
[Active Basic]デスクトップの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA コレクションに2次元配列...
-
どういうプログラムを関数化を...
-
VB.NETからVBAマクロ(引数)を呼...
-
PHP正規表現の難題・preg_repla...
-
PHPの名前空間インポートについて
-
関数の入れ子ができない。
-
UNIX CP "で上書きしません"
-
配列の操作時にLNK2001外部シン...
-
number_formatが勝手に四捨五入
-
次のhtml・cssでspan内の文字を...
-
外部ファイル(テキスト)を取...
-
Let's Encryptで自動更新がされ...
-
可変変数にアロー演算子を使いたい
-
vb作成したらでbeep音が鳴りま...
-
CakePHPでの自作関数保存場所
-
正規表現に関する質問です。HTM...
-
String変数の文字列の検索方法
-
クラス内で上位クラス内メンバ...
-
Fatal error: Cannot use []
-
ExcelVBAで部分一致(*)をしたい
おすすめ情報