Python3のipaddressモジュールの使い方

ipaddressモジュールは名前の通りIPアドレスを扱うためのモジュールです。

ipaddressモジュールはIPアドレスやネットワークアドレスを扱ういくつかのクラスを提供しています。これらのオブジェクトを使うと、IPアドレスがネットワークに含まれるかを確認したり、ネットワークに含まれるIPアドレスを一覧するなど、IPアドレスに関する様々な処理を簡単に行うことができます。

ipaddressモジュールはIPv6にも対応していますが、この記事ではIPv4を中心に説明します。しかし、多くの属性やメソッドは共通ですので、IPv6で使用する場合も参考になると思います。

目次

ipaddressモジュールの概要

ipaddressモジュールではIPv4用とIPv6用のクラスが提供されていますが、これらのオブジェクトに次の3つに大きく分けられます。

アドレスオブジェクト

「192.168.10.5」のような単一のIPアドレスを表す。

IPv4AddressクラスとIPv6Addressクラスのオブジェクトがアドレスオブジェクトに分類されます。

ネットワークオブジェクト

「192.168.10.0/24」のようにネットワークアドレスとサブネットマスクでネットワークを表す。

IPv4NetworkクラスとIPv6Networkクラスのオブジェクトがネットワークオブジェクトに分類されます。

インターフェイスオブジェクト

「192.168.10.5/24」のように単一のIPアドレスと、それが所属するネットワークの情報を表す。この例では「192.168.10.5」というIPアドレスと、それが「192.168.10.0/24」というネットワークの所属していることを表しています。

IPv4InterfaceクラスとIPv6Interfaceクラスのオブジェクトがインターフェイスオブジェクトに分類されます。

IPv4InterfaceクラスとIPv6Interfaceクラスは、それぞれIPv4AddressクラスとIPv6Addressクラスのサブクラスです。

ipaddressモジュールは、これらのオブジェクトを生成するファクトリー関数も提供しています。ファクトリー関数はオブジェクトの生成には便利ですが詳細を隠してしまうため、先ほど分類したオブジェクトから順に説明していき、最後にファクトリー関数について説明します。

アドレスオブジェクト

アドレスオブジェクトは単一のIPアドレスを表すオブジェクトです。IPv4用のIPv4AddressクラスとIPv6用のIP64Addressクラスのオブジェクトがアドレスオブジェクトです。

アドレスオブジェクトはhashable(ハッシュ可能 なオブジェクト)なので、辞書のキーとして利用できます。

IPv4Addressオブジェクトの生成

IPv4AddressクラスはIPv4のIPアドレスを表します。IPv4Addressオブジェクトを生成するには次の関数を使います。

ipaddress.IPv4Address(address)

address引数には次のいずれかの形式を渡すことが出来ます。

  • ドット付き10進表記の文字列。つまり0~255の範囲の4つの10進数をドッド(.)で区切ったもの (例:192.168.0.1)
  • 32ビットに収まる整数
  • 長さ4のbytesオブジェクト(最上位オクテットが先頭)

次の例は、どれも同じIPアドレスを表すIPv4Addressオブジェクトを生成します。

>>> import ipaddress
>>> ipaddress.IPv4Address('192.168.1.10')
IPv4Address('192.168.1.10')
>>> ipaddress.IPv4Address(3232235786)
IPv4Address('192.168.1.10')
>>> ipaddress.IPv4Address(bytes([192, 168, 1, 10]))
IPv4Address('192.168.1.10')

IPv4アドレスとして不正な引数を渡すとAddressValueErrorが発生します。

>>> ipaddress.IPv4Address('192.168.100.256')
Traceback (most recent call last):
...
    raise AddressValueError("%s in %r" % (exc, ip_str)) from None
ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.100.256'

IPv4Addressオブジェクトの情報を参照する

アドレスオブジェクトからいくつかの情報を参照できます。

IPアドレスのバージョンを取得する

IPアドレスのバージョンを知りたければversion属性を参照します。

>>> ipaddr = ipaddress.IPv4Address('192.168.1.10')
>>> ipaddr.version
4

IPv6のアドレスオブジェクトでは「6」が返されます。

ドット付き10進表記を取得する

アドレスオブジェクトのドット付き10進表記の文字列はstr()関数で得られます。print()関数にオブジェクトを渡すとこの文字列を印字します。

>>> str(ipaddr)
'192.168.1.10'
>>> print(ipaddr)
192.168.1.10

ドット付き10進表記の文字列はexploded属性またはcompressed属性を参照することで得ることもできます。

>>> ipaddr.exploded
'192.168.1.10'
>>> ipaddr.compressed
'192.168.1.10'

IPv6は通常128ビットのIPアドレスを16ビットごとにコロン(:)で区切って16進数で表記しますが、省略記法も使えます。exploded属性とcompressed属性この通常表記と省略表記のために用意されています。IPv4に省略記法はないので、IPv4のアドレスオブジェクトではどちらも同じアドレス表現になります。

IPv4の場合は2つの属性がコードに混在してしまうと理解しづらいコードになるので、個人的には一貫してstr()関数を使うことをお勧めします。

IPアドレスの数値表現を取得する

本来、IPアドレスは単なる数値です。ドット付き10進表記は人間が理解しやすいようにが用意されているに過ぎません。

アドレスオブジェクトから数値表現を得るには組み込みのint()関数を使います。

>>> int(ipaddr)
3232235786

IPアドレスの用途の確認

IPアドレスはさまざまな用途に予約されています。これらを確認するにはオブジェクトの次の属性を参照します。is_global属性とis_private属性でグローバルIPアドレスかプライベートIPアドレスか確認できます。そのほかの属性についてはドキュメントを確認してください。

>>> ipaddr = ipaddress.IPv4Address('192.168.1.10')
>>> ipaddr.is_global
False
>>> ipaddr.is_private
True
>>> ipaddr.is_multicast
False
>>> ipaddr.is_loopback
False
>>> ipaddr.is_reserved
False
>>> ipaddr.is_unspecified
False

アドレスオブジェクトの演算

アドレスオブジェクトはいくつかの演算をサポートしています。

比較演算

アドレスオブジェクト同士は比較演算子で比較することができます。これらの使い方は直感的でわかりやすいでしょう。

>>> ip1 = ipaddress.IPv4Address('192.168.0.1')
>>> ip2 = ipaddress.IPv4Address('192.168.0.2')
>>> ip1 == ip2
False
>>> ip1 != ip2
True
>>> ip1 < ip2
True
>>> ip1 < ip1
False
>>> ip1 <= ip1
True

算術演算

アドレスオブジェクトへ整数を加算したり、減算したりできます。

>>> ip1 + 1
IPv4Address('192.168.0.2')
>>> ip1 - 2
IPv4Address('192.167.255.255')

ネットワークオブジェクト

一般にネットワークは「ネットワークアドレス」と「サブネットマスク(あるいは単にマスク)」で表されます。ネットワークオブジェクトは「ネットワークアドレス/サブネットマスク」の形式でネットワークを表すオブジェクトです。

IPアドレスはマスクによって、ネットワークアドレス部とホストアドレス部に分けらます。ホストアドレス部のビットがすべて0のIPアドレスはネットワークアドレスと呼ばれます。

ネットワークオブジェクトのマスクにはドット付き10進表記かプレフィックス表記が使用できます。それぞれ次のような形式です。

192.168.1.0/255.255.255.0
192.168.1.0/24

アドレスオブジェクトの属性は、ネットワークオブジェクトにもすべて実装されています。加えてネットワークオブジェクト特有の属性も追加されています。

またネットワークオブジェクトはhashable(ハッシュ可能 なオブジェクト)なので、辞書のキーとして利用できます。

IPv4Networkオブジェクトの生成

IPv4NetworkクラスはIPv4のネットワークを表すクラスです。このクラスのオブジェクトを生成するには次の関数を使います。

ipaddress.IPv4Network(address, strict=True)

address引数には「IPアドレス/サブネットマスク」形式の文字列を指定できます。IPアドレスはドット付き10進表記です。マスクはドット付き10進表記かプレフィックス形式です。

>>> ipaddress.IPv4Network('192.168.1.0/24')
IPv4Network('192.168.1.0/24')
>>> ipaddress.IPv4Network('192.168.1.0/255.255.255.0')
IPv4Network('192.168.1.0/24')

オプションのサブネットマスクはを省略するとマスクは「/32」で作成されます。32ビットのマスクは、1つのIPアドレスのみを含むネットワークアドレスを表すとして許容されます。

>>> ipaddress.IPv4Network('192.168.1.0')
IPv4Network('192.168.1.0/32')

address引数には「IPアドレス/サブネットマスク」形式以外にも次のものを渡せます。

  • 32ビットに収まる整数
  • 長さ4のbytesオブジェクト(最上位オクテットが先頭)

これらはマスクの指定がないので「/32」のマスクを持つアドレスオブジェクトを作成します。

>>> ipaddress.IPv4Network(3232235776)
IPv4Network('192.168.1.0/32')
>>> ipaddress.IPv4Network(bytes([192, 168, 1, 0]))
IPv4Network('192.168.1.0/32')

最後はIPアドレスとサブネットマスクを要素とするタプルからIPv4Networkオブジェクトを作成します。

IPアドレスは次のいずれでかです。

  • ドット付き10進表記の文字列
  • 32ビットに収まる整数
  • 長さ4のbytesオブジェクト(最上位オクテットが先頭)
  • IPv4Addressオブジェクト

マスクは次のどちらかです。

  • ドット付き10進表記
  • プレフィックス
>>> ipaddress.IPv4Network(('192.168.1.0', 24))
IPv4Network('192.168.1.0/24')
>>> ipaddress.IPv4Network(('192.168.1.0', '255.255.255.0'))
IPv4Network('192.168.1.0/24')
>>> ipaddress.IPv4Network((3232235776, 24))
IPv4Network('192.168.1.0/24')
>>> ipaddress.IPv4Network((bytes([192, 168, 1, 0]), 24))
IPv4Network('192.168.1.0/24')
>>> ipaddress.IPv4Network((ipaddress.IPv4Address('192.168.1.0'), 24))
IPv4Network('192.168.1.0/24')

strict引数がTrue(デフォルト)の場合、ネットワークアドレス(IPアドレスのホストアドレス部のビットがすべて0)以外を指定するとValueErrorが発生します。

>>> ipaddress.IPv4Network('192.168.1.1/24')
...
ValueError: 192.168.1.1/24 has host bits set

strict引数にFalseを指定した場合、引数からネットワークアドレスを計算してネットワークオブジェクトを作成します。

>>> ipaddress.IPv4Network('192.168.1.1/24', strict=False)
IPv4Network('192.168.1.0/24')

address引数がIPv4アドレスとして不正な場合はAddressValueError例外が発生します。マスクが不正な場合はNetmaskValueError例外が発生します。

>>> ipaddress.IPv4Network('192.168.256.0/24')
...
ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.256.0'
>>> ipaddress.IPv4Network('192.168.1.0/33')
...
ipaddress.NetmaskValueError: '33' is not a valid netmask

アドレスオブジェクトと同じ属性

アドレスオブジェクトのすべての属性は、ネットワークオブジェクトにも実装されています。加えてネットワークオブジェクトにはいくつかの属性が追加されています。

追加された属性については後述します。アドレスオブジェクトと同じ属性は、アドレスオブジェクトの説明を参照ください。

>>> netaddr = ipaddress.IPv4Network('192.168.1.0/24')
>>> netaddr.version
4
>>> netaddr.exploded
'192.168.1.0/24'
>>> netaddr.compressed
'192.168.1.0/24'
>>> netaddr.is_global
False
>>> netaddr.is_private
True
>>> netaddr.is_loopback
False
>>> netaddr.is_reserved
False
>>> netaddr.is_unspecified
False

IPv4Networkオブジェクトの情報を参照する

ネットワークオブジェクトから、さまざまな情報を参照することが出来ます。

ネットワークの文字列表現を取得

プレフィックス表記のネットワークの文字列表現はwith_prefixlen属性、compressed属性、exploded属性で参照します。

>>> netaddr.with_prefixlen
'192.168.1.0/24'
>>> netaddr.exploded
'192.168.1.0/24'
>>> netaddr.compressed
'192.168.1.0/24'

IPv6は通常128ビットのIPアドレスを16ビットごとにコロン(:)で区切って16進数で表記しますが、省略記法も使えます。exploded属性とcompressed属性この通常表記と省略表記のために用意されています。

IPv4には省略記法がないのでIPv4Networkオブジェクトの場合、compressed属性もexploded属性も同じ文字列を返します。

組み込みのstr()関数も同じ文字列表現を返します。print()関数にネットワークオブジェクトストプレフィックス表記の文字列を印字します。

>>> str(netaddr)
'192.168.1.0/24'
>>> print(netaddr)
192.168.1.0/24

ドット付き10進表記のマスクの文字列表現はwith_netmask属性を参照します。

>>> netaddr.with_netmask
'192.168.1.0/255.255.255.0'

ネットワークアドレスとブロードキャストアドレスの取得

オブジェクトのネットワークアドレスはnetwork_address属性で参照できます。ブロードキャストアドレスはbroadcast_address属性を参照します。どちらもIPv4Addressオブジェクトで返されます。

>>> netaddr = ipaddress.IPv4Network('192.168.1.0/24')
>>> netaddr.network_address
IPv4Address('192.168.1.0')
>>> netaddr.broadcast_address
IPv4Address('192.168.1.255')

サブネットマスクの情報

オブジェクトのサブネットマスクはnetmask属性を参照します。プレフィックス長が知りたければprefixlen属性を参照します。

>>> netaddr.netmask
IPv4Address('255.255.255.0')
>>> netaddr.prefixlen
24

プレフィックス長

ネットワークのプレフィックス長はprefixlen属性を参照します。

>>> netaddr.prefixlen
24

ネットワークアドレス数

ネットワーク内のIPアドレスの数はnum_addresses属性で得られます。

>>> netaddr.num_addresses
256

ネットワーク内のIPアドレス

ネットワーク内の「すべてのIPアドレス」と「ホストに使用可能なIPアドレス」を取得することが出来ます。

ネットワーク内のすべてのIPアドレス

ネットワークオブジェクトはイテラブルです。イテレートすると、そのネットワークに属するすべてのIPアドレスが順に返されます。

これにはネットワークアドレスやブロードキャストアドレスも含まれます。ホストに使用可能なアドレスだけが必要な場合はhosts()メソッドを使います。

>>> for addr in ipaddress.IPv4Network('192.168.0.0/30'):
...     addr
...
IPv4Address('192.168.0.0')
IPv4Address('192.168.0.1')
IPv4Address('192.168.0.2')
IPv4Address('192.168.0.3')

ホストに使用可能なIPアドレス

ネットワークのIPアドレスの内、ホストに利用可能なIPアドレスだけが必要なことがあります。ネットワークアドレスとブロードキャストはホストのアドレスとしては使用できないので、これ以外がホストに利用可能なIPアドレスです。

hosts()メソッドはホストに利用可能なIPアドレスのイテレーターを返します。

ただしマスクのプレフィック長が31の場合、ネットワークアドレスとブロードキャストしかないのでこれらを含みます。マスクのプレフィック長が32の場合、単一のIPアドレスのみ含まれます。

>>> netaddr24 = ipaddress.IPv4Network('192.168.1.0/24')
>>> for addr in netaddr24.hosts():
...     addr
... 
IPv4Address('192.168.1.1')
IPv4Address('192.168.1.2')
...
IPv4Address('192.168.1.253')
IPv4Address('192.168.1.254')
>>> list(ipaddress.IPv4Network('192.168.1.0/31'))
[IPv4Address('192.168.1.0'), IPv4Address('192.168.1.1')]
>>> list(ipaddress.IPv4Network('192.168.1.0/32'))
[IPv4Address('192.168.1.0')]

ネットワークの比較

ネットワークオブジェクトは比較演算子をサポートしています。そのほかネットワークオブジェクト同士でIPアドレスが重複しているか調べることもできます。

ネットワークオプジェクトの比較

ネットワークオブジェクトは比較演算子で比較できます。最初にネットワークアドレスが比較され、次にネットマスクで比較されまる。

>>> n1 = ipaddress.IPv4Network('192.168.10.0/24')
>>> n2 = ipaddress.IPv4Network('192.168.20.0/24')
>>> n3 = ipaddress.IPv4Network('192.168.20.0/26')

>>> n1 < n2
True
>>> n1 < n3
True
>>> n3 < n2
False

>>> n1 == ipaddress.IPv4Network('192.168.10.0/24')
True
>>> n1 != ipaddress.IPv4Network('192.168.10.0/24')
False

IPアドレスの重複を確認する

overlaps()メソッドは、メソッドを呼び出したネットワークオブジェクトのネットワークが、引数のネットワークに含まれる、あるいは引数のネットワークがメソッド呼び出し元のネットワークに含まれる場合はTrueを返します。そうでなければFalseが返されます。

>>> netaddr1 = ipaddress.IPv4Network('192.168.1.0/28')
>>> netaddr2 = ipaddress.IPv4Network('192.168.1.4/30')
>>> netaddr3 = ipaddress.IPv4Network('192.168.1.16/28')
>>> netaddr1.overlaps(netaddr2)
True
>>> netaddr2.overlaps(netaddr1)
True
>>> netaddr1.overlaps(netaddr3)
False

サブネットとスーパーネット

ネットワークオブジェクトは自身が表すネットワークのサブネットやスーパネットに関する操作もサポートします。

サブネットに分割する

subnets()メソッドはネットワークをサブネットに分割します。現在のプレフィックからの増分をprefixlen_diff引数に指定します。prefixlen_diff引数のデフォルト値は1です。

subnets()メソッドは、サブネットのネットワークオブジェクトを生成するジェネレータオブジェクトを返します。

>>> netaddr = ipaddress.IPv4Network('192.168.1.0/24')

>>> list(netaddr.subnets())
[IPv4Network('192.168.1.0/25'), IPv4Network('192.168.1.128/25')]
>>> list(netaddr.subnets(prefixlen_diff=1))
[IPv4Network('192.168.1.0/25'), IPv4Network('192.168.1.128/25')]
>>> list(netaddr.subnets(prefixlen_diff=2))
[IPv4Network('192.168.1.0/26'), IPv4Network('192.168.1.64/26'), IPv4Network('192.168.1.128/26'), IPv4Network('192.168.1.192/26')]

プレフィックス長の増分ではなく、new_prefix引数に新しいプレフィックス長を指定することもできます。

>>> list(netaddr.subnets(new_prefix=26))
[IPv4Network('192.168.1.0/26'), IPv4Network('192.168.1.64/26'), IPv4Network('192.168.1.128/26'), IPv4Network('192.168.1.192/26')]

prefixlen_diff引数とnew_prefix引数はどちらか一方しか指定できません。

現在のプレフィックス長より小さい値を指定するとValueErrorがおきます。

>>> list(netaddr.subnets(new_prefix=23))
...
ValueError: new prefix must be longer

ネットワークから一部のサブネットを除外する

ネットワークオブジェクトから一部のネットワークを除外するにはaddress_exclude()メソッドを使います。引数に除外したいネットワークを表すネットワークオブジェクトを指定します。

このメソッドは除外した結果のネットワークを表すネットワークオブジェクトのジェネレータを返します。

>>> netaddr1 = ipaddress.IPv4Network('192.168.1.0/28')
>>> netaddr2 = ipaddress.IPv4Network('192.168.1.4/30')
>>> list(netaddr1.address_exclude(netaddr2))
[IPv4Network('192.168.1.8/29'), IPv4Network('192.168.1.0/30')]

元のネットワークに完全に含まれていないネットワークを引数に渡すとValueErrorが起きます。

ネットワークのスーパーネットを取得する

現在のネットワークのスーパーネットを得るにはsupernet()メソッドを使います。prefixlen_diff引数にプレフィックス長の減分を指定します。prefixlen_diff引数のデフォルト値は1です。

supernet()メソッドは単一のネットワークオブジェクトを返します。

>>> netaddr = ipaddress.IPv4Network('192.168.1.0/24')

>>> netaddr.supernet()
IPv4Network('192.168.0.0/23')
>>> netaddr.supernet(prefixlen_diff=1)
IPv4Network('192.168.0.0/23')
>>> netaddr.supernet(prefixlen_diff=2)
IPv4Network('192.168.0.0/22')

new_prefixにスーパーネットのプレフィックス長を指定することもできます。現在のプレフィックス長より大きい値を指定するとValueErrorが発生します。

>>> netaddr.supernet(new_prefix=22)
IPv4Network('192.168.0.0/22')
>>> netaddr.supernet(new_prefix=25)
...
ValueError: new prefix must be shorter

prefixlen_diff引数とnew_prefix引数はどちらか一方しか指定できません。

サブネット/スーパーネットであるか確認する

subnet_of()メソッドを使うと、あるネットワークがサブネットワークか確認できす。サブネットであればTrue、そうでなければFalseを返す。

同様にsupernet_of()メソッドを使うと、あるネットワークがスーパーネットか確認できます。

>>> netaddr1 = ipaddress.IPv4Network('192.168.1.0/28')
>>> netaddr2 = ipaddress.IPv4Network('192.168.1.4/30')
>>> netaddr2.subnet_of(netaddr1)
True
>>> netaddr1.subnet_of(netaddr2)
False
>>> netaddr1.supernet_of(netaddr2)
True
>>> netaddr2.supernet_of(netaddr1)
False

IPアドレスのコンテナとしての振る舞い

ネットワークオブジェクトは、リストのようなコンテナのように振る舞います。

次のようにインデックスで参照することができます。

>>> ipaddress.IPv4Network('192.168.0.0/30')[0]
IPv4Address('192.168.0.0')
>>> ipaddress.IPv4Network('192.168.0.0/30')[-1]
IPv4Address('192.168.0.3')

inを使ってネットワークにIPアドレスが含まれるか確認もできます。

>>> ipaddress.IPv4Address('192.168.0.3') in ipaddress.IPv4Network('192.168.0.0/30')
True
>>> ipaddress.IPv4Address('192.168.0.4') in ipaddress.IPv4Network('192.168.0.0/30')
False

インターフェイスオブジェクト

インターフェイスオブジェクトは、単一のIPアドレスとサブネットマスクの情報を合わせたものです。これによりIPアドレスがどのネットワークに所属しているか明確に示すことができます。

インターフェイスオブジェクトのクラスはIPv4InterfaceクラスとIPv6Interfaceクラスの2つのクラスがありますが、この記事では前者を取り上げます。

IPv4InterfaceクラスはIPv4Addressクラスのサブクラスです。したがって、IPv4Addressクラスのすべての属性を継承し、独自の属性も追加されています。

インターフェイスオブジェクトはhashable(ハッシュ可能 なオブジェクト)なので、辞書のキーとして利用できます。

IPv4Interfaceオブジェクトの生成

IPv4Interfaceオブジェクトを生成するには次の関数を使います。

ipaddress.IPv4Interface(address)

address引数は、任意のIPアドレスを許容することを除いてIPv4Networkのコンストラクタと同じものです。

# IPアドレス/マスクの文字列
>>> ipaddress.IPv4Interface('192.168.1.1/24')
IPv4Interface('192.168.1.1/24')
>>> ipaddress.IPv4Interface('192.168.1.1/255.255.255.0')
IPv4Interface('192.168.1.1/24')

# IPアドレスの数値
>>> ipaddress.IPv4Interface(3232235777)
IPv4Interface('192.168.1.1/32')

# 長さ4のbytesオブジェクト
>>> ipaddress.IPv4Interface(bytes([192, 168, 1, 1]))
IPv4Interface('192.168.1.1/32')

# IPアドレスとマスクのタプル
>>> ipaddress.IPv4Interface((3232235777, 24))
IPv4Interface('192.168.1.1/24')
>>> ipaddress.IPv4Interface((bytes([192, 168, 1, 1]), 24))
IPv4Interface('192.168.1.1/24')
>>> ipaddress.IPv4Interface((ipaddress.IPv4Address('192.168.1.1'), 24))
IPv4Interface('192.168.1.1/24')

不正なIPアドレスやマスクは、それぞれAddressValueErrorとNetmaskValueErrorが発生します。

# 不正なIPアドレス
>>> ipaddress.IPv4Interface('192.168.1.256/255.255.255.0')
...
ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.1.256'

# 不正なマスク
>>> ipaddress.IPv4Interface('192.168.1.1/255.255.256.0')
...
ipaddress.NetmaskValueError: '255.255.256.0' is not a valid netmask

インターフェイスの文字列表現

プレフィックス表記のインターフェイスの文字列表現は、with_prefixlen属性、exploded属性、compressed属性で参照します。

>>> interaddr = ipaddress.IPv4Interface('192.168.1.1/24')
>>> interaddr.with_prefixlen
'192.168.1.1/24'
>>> interaddr.exploded
'192.168.1.1/24'
>>> interaddr.compressed
'192.168.1.1/24'

組み込みのstr()関数も同じ文字列表現を返します。print()関数にインターフェイスオブジェクトを渡すとプレフィックス表記の文字列を印字します。

>>> str(interaddr)
'192.168.1.1/24'
>>> print(interaddr)
192.168.1.1/24

ドット付き10進表記のマスクの文字列表現はwith_netmask属性を参照します。

>>> interaddr.with_netmask
'192.168.1.1/255.255.255.0'

IPアドレスとネットワーク

インターフェイスオブジェクトのIPアドレスとネットワークはそれぞれip属性とnetwork属性で参照できます。

>>> interaddr.ip
IPv4Address('192.168.1.1')
>>> interaddr.network
IPv4Network('192.168.1.0/24')

インターフェイスオブジェクトの演算

インターフェイスオブジェクトは比較演算子で比較できます。

==演算子での比較は、IPアドレスとネットマスクが同じ場合のみTrueになります。!=はその反対です。

>>> inter1 = ipaddress.IPv4Interface('192.168.1.1/24')
>>> inter2 = ipaddress.IPv4Interface('192.168.1.1/26')
>>> inter1 == inter2
False
>>> inter1 != inter2
True
>>> inter1 == ipaddress.IPv4Interface('192.168.1.1/24')
True

インターフェイスオブジェクトをアドレスオブジェクトやネットワークオブジェクトと比較することもできますが、常に同じではないと評価されます。

>>> inter = ipaddress.IPv4Interface('192.168.1.0/24')
>>> addr  = ipaddress.IPv4Address('192.168.1.0')
>>> net   = ipaddress.IPv4Network('192.168.1.0/24')
>>> inter == addr
False
>>> inter == net
False

<と>(<=と>=を含む)演算子はオブジェクトの大小(順序)を比較します。インターフェイスオブジェクト同士の比較は最初にネットワークが比較され、ネットワークが同じならIPアドレスが比較されます。

ネットワークの比較はプレフィックス長が短い方の順序が前になります。

>>> inter3 = ipaddress.IPv4Interface('192.168.1.10/24')
>>> inter4 = ipaddress.IPv4Interface('192.168.1.10/26')
>>> inter3 < inter4
True

これはおそらく次のコードと同じ意味でしょう。

>>> inter3.network
IPv4Network('192.168.1.0/24')
>>> inter4.network
IPv4Network('192.168.1.0/26')
>>> inter3.network < inter4.network
True

ネットワークが同じ場合はIPアドレスが比較されます。

>>> inter5 = ipaddress.IPv4Interface('192.168.1.100/24')
>>> inter6 = ipaddress.IPv4Interface('192.168.1.200/24')
>>> inter5 < inter6
True

最初にネットワークが比較されるので「inter5 < inter7」の結果はFalseになります。IPアドレスの大小は関係ありません。

>>> inter7 = ipaddress.IPv4Interface('192.168.1.200/22')
>>> inter5.ip
IPv4Address('192.168.1.100')
>>> inter7.ip
IPv4Address('192.168.1.200')
>>> inter5 < inter7
False

アドレスオブジェクトと比較することが出来ます。アドレスオブジェクトは、常にインターフェイスオブジェクトより順序が前になります。

>>> inter5
IPv4Interface('192.168.1.100/24')
>>> ipaddress.IPv4Address('192.168.1.100') < inter5
True
>>> ipaddress.IPv4Address('192.168.1.200') < inter5
True

ファクトリー関数

ipaddressモジュールには、モジュールで定義されたクラスのオブジェクトを簡単に作成するためにファクトリー関数が提供されています。

アドレスオブジェクト、ネットワークオブジェクト、インターフェイスオブジェクトを作成する3つのファクトリー関数があります。

アドレスオブジェクトのファクトリー関数

アドレスオブジェクトのファクトリー関数は、与えられた引数によってIPv4AddresオブジェクトかIPv6Addressオブジェクトのいずれかを作成して返します。

アドレスオブジェクトを作成するファクトリー関数の構文は次の通りです。

  ip_address(address)

「IPv4Addressオブジェクトの生成」で説明した引数をaddress引数に渡すとIPv4Addressオブジェクトを作成します。IPv6Addressオブジェクトを作成方法はドキュメントを参照ください。

ネットワークオブジェクトのファクトリー関数

ネットワークオブジェクトのファクトリー関数は、与えられた引数によってIPv4NetworkオブジェクトかIPv6Networkのオブジェクトを作成して返します。

ネットワークオブジェクトを作成するファクトリー関数構文は次の通りです。

ip_network(address, strict=True)

「IPv4Networkオブジェクトの生成」で説明した引数をaddress引数に渡すと、IPv4Networkオブジェクトを作成します。IPv6Networkオブジェクトの作成方法はドキュメントを参照ください。

インターフェイスオブジェクトのファクトリー関数

インターフェイスオブジェクトのファクトリー関数は、与えられた引数によってIPv4InterfaceオブジェクトかIPv6Interfaceオブジェクトを作成して返します。

ファクトリー関数の構文は次の通りです。

ip_interface(address)

「IPv4Interfaceオブジェクトの生成」で説明した引数をaddress引数に渡すと、IPv4Interfaceオブジェクトを作成します。IPv6Interfaceオブジェクトの作成方法はドキュメントを参照ください。

まとめ

IPアドレスを扱うモジュールにはサードパーティ製のものもありますが、やはり組み込みのモジュールは安心感があります。みなさんも使ってみてはいかがでしょうか。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

・PM、SE、SIなどを20年以上経験
・ネットワークスペシャリスト、セキュリティスペシャリストなど複数の資格を保有

目次