PostgreSQL 関数で CIDR から IP アドレス一覧を生成する


PostgreSQL で与えられた CIDR から IP アドレス一覧を生成する

PostgreSQL の関数(PL/PgSQL)で、CIDR (例えば 192.168.1.0/24) アドレスから IP アドレス一覧を作成する必要がある場合、次の関数が要件を満たしてくれると思います。




PL/PgSQL 関数の作成

CREATE OR REPLACE FUNCTION generate_ips_from_cidr(cidr)
  RETURNS SETOF inet AS
$BODY$
  SELECT ip FROM (
    SELECT $1 + s AS ip
    FROM generate_series(1, broadcast($1) - (network($1)) - 1) s
  ) ips
  WHERE host(ips.ip) NOT LIKE '%.0' AND host(ips.ip) NOT LIKE '%.255';
$BODY$
  LANGUAGE sql IMMUTABLE STRICT;


PL/PgSQL 関数の呼び出し

上記関数を作成したら、以下のようにして関数を呼び出します。
SELECT host(generate_ips_from_cidr)
FROM generate_ips_from_cidr('192.168.1.0/24');

上記関数呼び出しで SELECT 内で host() 関数を呼び出している理由は、host() 関数を使わないと "192.168.1.1/24" のようにネットマスク値が付与されてしまいます。ですので host() 関数で IP アドレスのみ返すよう変換をかけています。

この関数呼び出しによって、以下のような結果が得られます。
"192.168.1.1"
"192.168.1.2"
"192.168.1.3"
"192.168.1.4"
"192.168.1.5"
..........
"192.168.1.250"
"192.168.1.251"
"192.168.1.252"
"192.168.1.253"
"192.168.1.254"

なおこの関数はネットワークアドレス(末尾が 0)とブロードキャスアドレス(末尾が 255)は返さないようにしています。もし必要であれば、関数内の "host(ips.ip) NOT LIKE '%.0' AND host(ips.ip) NOT LIKE '%.255'" という条件を外してください。

なおこの関数は PostgreSQL-8.2 以上で動作確認済みです。