paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

pythonのipaddressモジュールでサブネット計算して全部のアドレスを出す

IPアドレスをデータベースで管理したいという思いがあるのですが、
table作成の練習として特定のサブネットのレンジを出力させてみようと思います。

コード

出番が多くてもいいように引数から読み込むようにしました。

  • create_subnet.py
import ipaddress
import sys

if len(sys.argv) != 2:
    print('Usage: python3 ', sys.argv[0], ' <ipaddress/prefix>')
    exit()

Address = sys.argv[1]

def Create_segment(cider):
    # Convet to Network address with strict
    Segment = ipaddress.IPv4Network(cider, strict=False)
    Hosts = Segment.hosts()
    Mask = Segment.netmask

    if Segment.prefixlen == 32:
        print(Segment.network_address, Mask)
    elif Segment.prefixlen == 31:
        print(Segment.network_address, Mask, 'Network Address')
        print(Segment.broadcast_address, Mask, 'Broadcast Address')
    else:
        print(Segment.network_address, Mask, 'Network Address')
        for IP in Hosts:
            print(IP, Mask, 'Usable host')
        print(Segment.broadcast_address, Mask, 'Broadcast Address')

if __name__ == '__main__':
    Create_segment(Address)

環境

WindowsサブノートPCで動かします。

PS C:\Users\masashi\tools\ipaddresses> Get-WmiObject Win32_OperatingSystem


SystemDirectory : C:\WINDOWS\system32
Organization    :
BuildNumber     : 18363
RegisteredUser  : user
SerialNumber    : 00330-80000-00000-AA868
Version         : 10.0.18363


PS C:\Users\masashi\tools\ipaddresses> python --version
Python 3.7.2

動作

CIDER表記でIPアドレスを入力するとネットワークアドレスを拾って
サブネット分のアドレスを出力してくれます。

  • 今のアドレス
Wireless LAN adapter Wi-Fi:

…
   リンクローカル IPv6 アドレス. . . . .: fe80::fc0c:5db:ec24:8ed1%19
   IPv4 アドレス . . . . . . . . . . . .: 192.168.0.12
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: 192.168.0.1
PS C:\Users\masashi\tools\ipaddresses> python .\create_subnet.py 192.168.0.12/24
192.168.0.0 255.255.255.0 Network Address
192.168.0.1 255.255.255.0 Usable host
192.168.0.2 255.255.255.0 Usable host
192.168.0.3 255.255.255.0 Usable host
192.168.0.4 255.255.255.0 Usable host
192.168.0.5 255.255.255.0 Usable host
192.168.0.6 255.255.255.0 Usable host
192.168.0.7 255.255.255.0 Usable host
…
192.168.0.250 255.255.255.0 Usable host
192.168.0.251 255.255.255.0 Usable host
192.168.0.252 255.255.255.0 Usable host
192.168.0.253 255.255.255.0 Usable host
192.168.0.254 255.255.255.0 Usable host
192.168.0.255 255.255.255.0 Broadcast Address
PS C:\Users\masashi\tools\ipaddresses>
  • 29bit
PS C:\Users\masashi\tools\ipaddresses> python .\create_subnet.py 192.168.0.12/29
192.168.0.8 255.255.255.248 Network Address
192.168.0.9 255.255.255.248 Usable host
192.168.0.10 255.255.255.248 Usable host
192.168.0.11 255.255.255.248 Usable host
192.168.0.12 255.255.255.248 Usable host
192.168.0.13 255.255.255.248 Usable host
192.168.0.14 255.255.255.248 Usable host
192.168.0.15 255.255.255.248 Broadcast Address
PS C:\Users\masashi\tools\ipaddresses>
  • 30bit
PS C:\Users\masashi\tools\ipaddresses> python .\create_subnet.py 192.168.0.12/30
192.168.0.12 255.255.255.252 Network Address
192.168.0.13 255.255.255.252 Usable host
192.168.0.14 255.255.255.252 Usable host
192.168.0.15 255.255.255.252 Broadcast Address
PS C:\Users\masashi\tools\ipaddresses>
  • 31bit
PS C:\Users\masashi\tools\ipaddresses> python .\create_subnet.py 192.168.0.12/31
192.168.0.12 255.255.255.254 Network Address
192.168.0.13 255.255.255.254 Broadcast Address
PS C:\Users\masashi\tools\ipaddresses>
  • 32bit
PS C:\Users\masashi\tools\ipaddresses> python .\create_subnet.py 192.168.0.12/32
192.168.0.12 255.255.255.255

細かいサブネットもこの通り。

これの気に入っているところはわざわざネットワークアドレスを計算して指定しなくても
モジュールが探し出してくれるのですごく楽です。

こりゃ暗記するのがバカらしくなるぜ!

コード振り返り

ipaddressモジュールって似た機能のクラスがあってまぎらわしいです。

IPv4Interfaceをよく使うのですが
今回はネットワークを出すツールなのでIPv4Networkで統一しました。
IPv4Interfaceはホスト単位で細かく操作できるイメージです。

また、hostsメソッドは有効なアドレスしか出力しないので、
サブネットらしく別でネットワークアドレスとブロードキャストアドレスを出してます。
31bitと32bitのときはIPv4Networkで処理しきれないので切り出してます。

あと引数チェックで失敗したら抜けるという処理を入れたら
このスクリプトをimportできなくなってしまいました。

今は考えていませんが、他のスクリプトから読み込ませる際は
引数チェックを読ませないようにしないとですね。

というわけで簡単なコードですが指定したIPのサブネットを丸ごと出力できるようになりました。
細かいサブネットも業務で使うことがあるのでこいつでサクッと計算しようと思います。

ipcalcより一歩先行く(?)ツールが作れましたw

これも改めてgithubに上げたいと思います。

追記

これでリポジトリ作りました!

github.com

参考サイト

少しバージョンが違いますが
ipaddress --- IPv4/IPv6 操作ライブラリ — Python 3.7.7 ドキュメント