yamamoWorks

.NET技術を中心に気まぐれに更新していきます

あるIPアドレスがあるネットワークに属しているか判定する処理

送信元のIPアドレスでアクセス制限や処理の振り分け行う場面などで、あるIPアドレスがあるネットワークに属しているかどうかを判定する処理を書いてみました。


class Program
{
static void Main(string[] args)
{
// 許可するネットワーク
string[] allowNetworks =
{
"192.168.0.0/24",
"192.168.1.0/24",
"192.168.3.16/28"
};

string line = Console.ReadLine();

while (!string.IsNullOrEmpty(line))
{
// 入力されたIPアドレス
byte[] ip = IPAddress.Parse(line).GetAddressBytes();

if (allowNetworks.Any(
(allow) =>
{
// ネットワークアドレス
byte[] network = IPAddress.Parse(allow.Split('/')[0]).GetAddressBytes();

// サブネットマスク
string bits = new string('1', int.Parse(allow.Split('/')[1])).PadRight(32, '0');
byte[] mask = new[] {
Convert.ToByte(bits.Substring(0, 8), 2),
Convert.ToByte(bits.Substring(8, 8), 2),
Convert.ToByte(bits.Substring(16, 8), 2),
Convert.ToByte(bits.Substring(24, 8), 2)
};

// AND演算する為にintに変換
int i = BitConverter.ToInt32(ip, 0);
int m = BitConverter.ToInt32(mask, 0);
int n = BitConverter.ToInt32(network, 0);

// 入力されたIPアドレスのネットワークアドレスを算出して比較
return (i & m) == n;
}))
{
Console.WriteLine("OK");
}
else
{
Console.WriteLine("NG");
}

line = Console.ReadLine();
}
}
}

「/24」と表記されたサブネットマスクをもっとスマートに変換する方法があれば教えてください Huh?