2026年9月27日

2026年9月27日

FLSMのサブネット一覧を作るツール|ipcalc・Pythonで分割しVLSMに組み替える

FLSM(固定長サブネットマスク)の計算は、「元のネットワーク」と「必要なサブネット数またはホスト数」を入力すると、同じ大きさのサブネットの一覧に変換してくれるツールを使うと手早く正確にできます。この記事では、Linux の ipcalc 系コマンド、追加インストール不要の Python スクリプト、そして FLSM で作った割り当てを VLSM(可変長)に組み替える方法を順に紹介します。FLSM の考え方そのものや手計算の手順は別記事の範囲とし、ここでは「ツールで一覧を出し、結果を検証して設計書に落とす」作業に絞ります。

FLSM の変換で入力するものと出力されるもの

FLSM は、1 つのネットワークを同じプレフィックス長のサブネットに等分する方式です。ツールに渡す情報は次の 2 つです。

  • 元のネットワーク(例: 192.168.10.0/24)
  • 分割の条件。「サブネットが 6 個ほしい」か「1 サブネットに 100 台入れたい」のどちらか

ツールはこの条件から新しいプレフィックス長を決め、各サブネットのネットワークアドレス、サブネットマスク、ホストに割り当てられる範囲、ブロードキャストアドレスを出力します。6 個ほしい場合は 2 の 3 乗 = 8 個に切り上がるため /27 が 8 個、100 台入れたい場合は 128 アドレス必要なので /25 が 2 個、という結果になります。FLSM ではすべてのサブネットが同じ大きさになるので、「数を優先するか、1 個あたりの台数を優先するか」で結果が大きく変わる点を押さえておくと、ツールの出力を読み違えません。

Linux のコマンドで変換する(ipcalc・sipcalc)

Linux には ipcalc という名前のコマンドが2系統あり、ディストリビューションによって中身と使えるオプションが異なります(2026年10月時点)。同じ /24 を /27 に分割するコマンドは、系統ごとに次のようになります。

コマンド 入手先 /24 を /27 に分割する書き方
ipcalc(ipcalc プロジェクト版) RHEL・Fedora 系の ipcalc パッケージ。Debian・Ubuntu では ipcalc-ng パッケージ(コマンド名も ipcalc-ng) ipcalc -S 27 192.168.10.0/24
ipcalc(Perl 版) Debian・Ubuntu の ipcalc パッケージ ipcalc 192.168.10.0/24 255.255.255.224
sipcalc Debian・Ubuntu などの sipcalc パッケージ sipcalc -s 27 192.168.10.0/24

それぞれの使い方は次のとおりです。

# ipcalc プロジェクト版:-S(--split)に新しいプレフィックス長を渡す
ipcalc -S 27 192.168.10.0/24
# Debian・Ubuntu で ipcalc-ng パッケージを入れた場合
ipcalc-ng -S 27 192.168.10.0/24

# Perl 版:2つ目の引数に分割後のサブネットマスクを渡すと、分割後の一覧が出る
ipcalc 192.168.10.0/24 255.255.255.224

# sipcalc:-s(--v4split)に分割後のマスクを渡す
sipcalc -s 27 192.168.10.0/24

Perl 版の ipcalc には、必要なホスト数を並べて分割する -s(--split)もあります(例: ipcalc 192.168.10.0/24 -s 100 50 20)。こちらは大きさの違うサブネットを作るので、FLSM ではなく後で説明する VLSM 寄りの動きです。ipcalc プロジェクト版の新しい版にも、ホスト数で分割する --split-hosts があります。

どちらの ipcalc が入っているかは、ipcalc --help や man ipcalc のオプション一覧で見分けられます。-S, --split が載っていればプロジェクト版、-s, --split に「n1 n2 n3」のような引数が並んでいれば Perl 版です。オプション名や出力形式は版によって変わるため、使う前に手元の --help や man で確認してください。

コマンドの系統が混在する環境(作業者ごとに OS が違う、踏み台サーバーと手元で結果が違う)では、次に紹介する Python スクリプトに揃えると、誰が実行しても同じ出力になります。

Python で FLSM の一覧を出力する

Python 3 の標準ライブラリ ipaddress には、ネットワークを指定したプレフィックス長に等分する subnets(new_prefix=...) があります。これを使うと、追加のパッケージなしで FLSM の変換ツールを作れます。次のスクリプトは、サブネット数またはホスト数を指定すると CSV 形式で一覧を出力します。

#!/usr/bin/env python3
"""FLSM: 1つの IPv4 ネットワークを同じ大きさのサブネットに分割して一覧にする"""
import argparse
import ipaddress
import sys


def prefix_for_subnets(base, count):
    # count 個に分けるのに必要な借用ビット数を足す
    return base.prefixlen + (count - 1).bit_length()


def prefix_for_hosts(hosts):
    # ネットワーク・ブロードキャストの 2 個を足し、2 のべき乗に切り上げる(最小 /30)
    host_bits = max(2, (hosts + 2 - 1).bit_length())
    return 32 - host_bits


def main():
    p = argparse.ArgumentParser(description="FLSM サブネット一覧を出力する")
    p.add_argument("network", help="例: 192.168.10.0/24")
    g = p.add_mutually_exclusive_group(required=True)
    g.add_argument("--subnets", type=int, help="必要なサブネット数")
    g.add_argument("--hosts", type=int, help="1サブネットあたりの必要ホスト数")
    a = p.parse_args()

    count = a.subnets if a.subnets is not None else a.hosts
    if count < 1:
        sys.exit("--subnets と --hosts には 1 以上を指定してください")

    base = ipaddress.IPv4Network(a.network, strict=True)
    if a.subnets is not None:
        new = prefix_for_subnets(base, a.subnets)
    else:
        new = prefix_for_hosts(a.hosts)
    if new > 30 or new < base.prefixlen:
        sys.exit("この条件では %s に収まりません(必要なプレフィックス長 /%d)" % (base, new))

    subs = list(base.subnets(new_prefix=new))
    print("# /%d → /%d  サブネット数 %d  ホスト上限 %d" % (
        base.prefixlen, new, len(subs), subs[0].num_addresses - 2))
    print("no,network,netmask,first_host,last_host,broadcast")
    for i, s in enumerate(subs, 1):
        print("%d,%s,%s,%s,%s,%s" % (i, s, s.netmask, s.network_address + 1,
                                     s.broadcast_address - 1, s.broadcast_address))


if __name__ == "__main__":
    main()

flsm.py という名前で保存し、次のように実行します。

python3 flsm.py 192.168.10.0/24 --subnets 6
python3 flsm.py 192.168.10.0/24 --hosts 100 > flsm_plan.csv

1 行目は /27 が 8 個、2 行目は /25 が 2 個の一覧になります。出力は CSV なので、そのまま表計算ソフトに読み込んで用途や担当を書き足せば設計書の下書きになります。

スクリプトを作るときにつまずきやすい点が 3 つあります。1 つ目は strict=True です。192.168.10.5/24 のようにホスト部に 1 が立った値を渡すとエラーになり、入力ミスに気づけます。2 つ目は切り上げの計算で、(count - 1).bit_length() は「count 個を表すのに必要なビット数」を浮動小数点を使わずに求めています。3 つ目は条件が収まらない場合の扱いで、/24 に 300 台を入れようとすると必要なプレフィックス長が元より短くなるため、一覧を出さずに理由を表示して終了します。ここでは /31 や /32 は対象外とし、通常の LAN 向けに最小 /30 としています。

クラウドのサブネットに使う場合は、事業者の予約分を足して指定します。たとえば AWS は各サブネットで 5 個を予約するので、ネットワーク・ブロードキャスト分としてスクリプトが足す 2 個との差の 3 個を、--hosts の値に上乗せしてください。予約数は事業者ごと・仕様変更で変わり得るため、公式ドキュメントで確認します。

FLSM の割り当てを VLSM に組み替える

FLSM は計算と管理が単純な反面、部署ごとに台数の差が大きいとアドレスを無駄にします。たとえば 192.168.10.0/24 を「営業 100 台・開発 50 台・管理 20 台・拠点間リンク 2 台」に分けたい場合、いちばん大きい営業に合わせて /25 にすると 2 個しか作れず、4 つの用途を収められません。サブネット数に合わせて /26 にすると、今度は営業の 100 台が入りません。

このような場合は、FLSM の一覧から VLSM の割り当てに組み替えます。手順は「必要数の大きい順に並べ、それぞれに足りる最小のサブネットを、境界をそろえて先頭から詰める」です。

import ipaddress


def prefix_for_hosts(hosts):
    return 32 - max(2, (hosts + 1).bit_length())


def to_vlsm(base, needs):
    """needs: {名前: 必要ホスト数}。大きい順に、境界をそろえて先頭から詰める"""
    base = ipaddress.IPv4Network(base)
    cursor = int(base.network_address)
    plan = []
    for name, hosts in sorted(needs.items(), key=lambda x: -x[1]):
        pl = prefix_for_hosts(hosts)
        size = 2 ** (32 - pl)
        cursor = (cursor + size - 1) // size * size
        net = ipaddress.IPv4Network((cursor, pl))
        if not net.subnet_of(base):
            raise ValueError("%s が %s に収まりません" % (name, base))
        plan.append((name, hosts, net))
        cursor += size
    return plan


needs = {"営業": 100, "開発": 50, "管理": 20, "拠点間リンク": 2}
for name, hosts, net in to_vlsm("192.168.10.0/24", needs):
    print(name, hosts, net, net.num_addresses - 2)

実行すると、営業 192.168.10.0/25、開発 192.168.10.128/26、管理 192.168.10.192/27、拠点間リンク 192.168.10.224/30 となり、/24 の中に 4 用途が収まって 192.168.10.228 以降が予備として残ります。大きい順に並べるのは、小さいサブネットを先に置くと大きいサブネットの境界(/25 なら 0 か 128 から始まる必要がある)に合わず、隙間が生まれるからです。

変換結果を検証してから使う

ツールの出力をそのまま機器に設定する前に、次の点を確認します。

  • 重複していないか: 既存のサブネットと新しい一覧を ipaddress の overlaps() で総当たりすると、目視より見落としが減ります
  • 用途に必要な台数が上限を下回っていないか: 一覧のホスト上限と、固定アドレス・DHCP 範囲・予約分を足した値を比べます
  • ルーティングで集約できるか: 拠点ごとに連続した範囲を割り当てると、上位のルーターで 1 本の経路にまとめやすくなります

Web 上のサブネット計算サイトも便利ですが、社内のアドレス設計をそのまま入力したくない場合や、結果を記録として残したい場合は、手元のスクリプトで出力した CSV を設計書に添付しておくと、後から検証しやすくなります。

まとめ

  • FLSM の変換ツールには「元のネットワーク」と「サブネット数またはホスト数」を渡し、同じ大きさのサブネット一覧を得る
  • ipcalc は系統ごとにオプションが違うため、--help で確認してから使う。環境が混在するなら Python の ipaddress で揃える
  • subnets(new_prefix=...) を使ったスクリプトで、CSV の一覧をそのまま設計書の下書きにできる
  • 台数の差が大きい場合は、大きい順・境界をそろえて詰める手順で VLSM に組み替える
  • 出力は重複・台数・集約のしやすさを確認してから機器に設定する

関連する記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲