ipaddressモジュールの紹介—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/howto/ipaddress
移動先:案内検索

ipaddressモジュールの紹介

著者
ピータームーディ
著者
ニック・コグラン

概要

このドキュメントは、 ipaddress モジュールの概要を説明することを目的としています。 これは主に、IPネットワークの用語にまだ精通していないユーザーを対象としていますが、 ipaddress がIPネットワークアドレス指定の概念をどのように表すかについての概要を知りたいネットワークエンジニアにも役立つ場合があります。


アドレス/ネットワーク/インターフェースオブジェクトの作成

ipaddress はIPアドレスを検査および操作するためのモジュールであるため、最初に実行したいのはいくつかのオブジェクトを作成することです。 ipaddress を使用して、文字列と整数からオブジェクトを作成できます。

IPバージョンに関する注記

IPアドレッシングに特に精通していない読者にとっては、インターネットプロトコルが現在プロトコルのバージョン4からバージョン6に移行中であることを知っておくことが重要です。 この移行は主に、プロトコルのバージョン4が全世界のニーズを処理するのに十分なアドレスを提供していないために発生しています。特に、インターネットに直接接続するデバイスの数が増えているためです。

プロトコルの2つのバージョンの違いの詳細を説明することは、この紹介の範囲を超えていますが、読者は少なくともこれら2つのバージョンが存在することを認識しておく必要があり、1つのバージョンまたは他の。


IPホストアドレス

「ホストアドレス」と呼ばれることが多いアドレスは、IPアドレッシングを使用する場合の最も基本的な単位です。 アドレスを作成する最も簡単な方法は、 ipaddress.ip_address()ファクトリ関数を使用することです。このファクトリ関数は、渡された値に基づいてIPv4アドレスとIPv6アドレスのどちらを作成するかを自動的に決定します。

>>> ipaddress.ip_address('192.0.2.1')
IPv4Address('192.0.2.1')
>>> ipaddress.ip_address('2001:DB8::1')
IPv6Address('2001:db8::1')

アドレスは整数から直接作成することもできます。 32ビット内に収まる値は、IPv4アドレスであると見なされます。

>>> ipaddress.ip_address(3221225985)
IPv4Address('192.0.2.1')
>>> ipaddress.ip_address(42540766411282592856903984951653826561)
IPv6Address('2001:db8::1')

IPv4またはIPv6アドレスの使用を強制するために、関連するクラスを直接呼び出すことができます。 これは、小さい整数のIPv6アドレスを強制的に作成する場合に特に便利です。

>>> ipaddress.ip_address(1)
IPv4Address('0.0.0.1')
>>> ipaddress.IPv4Address(1)
IPv4Address('0.0.0.1')
>>> ipaddress.IPv6Address(1)
IPv6Address('::1')

ネットワークの定義

ホストアドレスは通常、IPネットワークにグループ化されるため、 ipaddress は、ネットワーク定義を作成、検査、および操作する方法を提供します。 IPネットワークオブジェクトは、そのネットワークの一部であるホストアドレスの範囲を定義する文字列から構築されます。 その情報の最も単純な形式は「ネットワークアドレス/ネットワークプレフィックス」ペアです。プレフィックスは、アドレスがネットワークの一部であるかどうかを判断するために比較される先行ビットの数を定義し、ネットワークアドレスはの期待値を定義します。それらのビット。

アドレスに関しては、正しいIPバージョンを自動的に決定するファクトリ関数が提供されています。

>>> ipaddress.ip_network('192.0.2.0/24')
IPv4Network('192.0.2.0/24')
>>> ipaddress.ip_network('2001:db8::0/96')
IPv6Network('2001:db8::/96')

ネットワークオブジェクトにホストビットを設定することはできません。 これの実際的な効果は、192.0.2.1/24がネットワークを記述しないことです。 ip-on-a-network表記は、特定のネットワーク上のコンピューターのネットワークインターフェイスを記述するために一般的に使用され、次のセクションでさらに説明されるため、このような定義はインターフェイスオブジェクトと呼ばれます。

デフォルトでは、ホストビットが設定されたネットワークオブジェクトを作成しようとすると、 ValueError が発生します。 代わりに追加ビットをゼロに強制変換するように要求するには、フラグstrict=Falseをコンストラクターに渡すことができます。

>>> ipaddress.ip_network('192.0.2.1/24')
Traceback (most recent call last):
   ...
ValueError: 192.0.2.1/24 has host bits set
>>> ipaddress.ip_network('192.0.2.1/24', strict=False)
IPv4Network('192.0.2.0/24')

文字列形式の方がはるかに柔軟性がありますが、ホストアドレスと同様に、ネットワークを整数で定義することもできます。 この場合、ネットワークには整数で識別される単一のアドレスのみが含まれていると見なされるため、ネットワークプレフィックスにはネットワークアドレス全体が含まれます。

>>> ipaddress.ip_network(3221225984)
IPv4Network('192.0.2.0/32')
>>> ipaddress.ip_network(42540766411282592856903984951653826560)
IPv6Network('2001:db8::/128')

アドレスと同様に、特定の種類のネットワークの作成は、ファクトリ関数を使用する代わりに、クラスコンストラクタを直接呼び出すことによって強制できます。


ホストインターフェース

上記のように、特定のネットワーク上のアドレスを記述する必要がある場合、アドレスもネットワーククラスも十分ではありません。 192.0.2.1/24のような表記は、ネットワークエンジニアや、ファイアウォールやルーターのツールを作成する人々が「ネットワーク上のホスト192.0.2.1 192.0.2.0/24」の省略形として一般的に使用します。 X196X] ipaddress は、アドレスを特定のネットワークに関連付けるハイブリッドクラスのセットを提供します。 作成用のインターフェースは、アドレス部分がネットワークアドレスであることに制約されないことを除いて、ネットワークオブジェクトを定義するためのインターフェースと同じです。

>>> ipaddress.ip_interface('192.0.2.1/24')
IPv4Interface('192.0.2.1/24')
>>> ipaddress.ip_interface('2001:db8::1/96')
IPv6Interface('2001:db8::1/96')

整数入力は(ネットワークと同様に)受け入れられ、特定のIPバージョンの使用は、関連するコンストラクターを直接呼び出すことによって強制できます。


アドレス/ネットワーク/インターフェースオブジェクトの検査

IPv(4 | 6)(Address | Network | Interface)オブジェクトを作成するのに苦労したので、おそらくそれに関する情報を取得したいと思うでしょう。 ipaddress は、これを簡単かつ直感的に行えるようにします。

IPバージョンの抽出:

>>> addr4 = ipaddress.ip_address('192.0.2.1')
>>> addr6 = ipaddress.ip_address('2001:db8::1')
>>> addr6.version
6
>>> addr4.version
4

インターフェイスからネットワークを取得する:

>>> host4 = ipaddress.ip_interface('192.0.2.1/24')
>>> host4.network
IPv4Network('192.0.2.0/24')
>>> host6 = ipaddress.ip_interface('2001:db8::1/96')
>>> host6.network
IPv6Network('2001:db8::/96')

ネットワーク内にある個々のアドレスの数を調べる:

>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> net4.num_addresses
256
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
>>> net6.num_addresses
4294967296

ネットワーク上の「使用可能な」アドレスを反復処理します。

>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> for x in net4.hosts():
...     print(x)  
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
...
192.0.2.252
192.0.2.253
192.0.2.254

ネットマスクの取得(つまり ネットワークプレフィックスに対応するビットを設定する)またはホストマスク(ネットマスクの一部ではないビット):

>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> net4.netmask
IPv4Address('255.255.255.0')
>>> net4.hostmask
IPv4Address('0.0.0.255')
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
>>> net6.netmask
IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
>>> net6.hostmask
IPv6Address('::ffff:ffff')

アドレスの展開または圧縮:

>>> addr6.exploded
'2001:0db8:0000:0000:0000:0000:0000:0001'
>>> addr6.compressed
'2001:db8::1'
>>> net6.exploded
'2001:0db8:0000:0000:0000:0000:0000:0000/96'
>>> net6.compressed
'2001:db8::/96'

IPv4は展開または圧縮をサポートしていませんが、関連するオブジェクトは関連するプロパティを提供するため、バージョンニュートラルコードは、IPv4アドレスを正しく処理しながら、IPv6アドレスに最も簡潔または最も冗長な形式を簡単に使用できます。


アドレスのリストとしてのネットワーク

ネットワークをリストとして扱うと便利な場合があります。 これは、次のようにインデックスを付けることができることを意味します。

>>> net4[1]
IPv4Address('192.0.2.1')
>>> net4[-1]
IPv4Address('192.0.2.255')
>>> net6[1]
IPv6Address('2001:db8::1')
>>> net6[-1]
IPv6Address('2001:db8::ffff:ffff')

また、ネットワークオブジェクトは、次のようなリストメンバーシップテスト構文を使用するのに適していることも意味します。

if address in network:
    # do something

封じ込めテストは、ネットワークプレフィックスに基づいて効率的に実行されます。

>>> addr4 = ipaddress.ip_address('192.0.2.1')
>>> addr4 in ipaddress.ip_network('192.0.2.0/24')
True
>>> addr4 in ipaddress.ip_network('192.0.3.0/24')
False

比較

ipaddress は、オブジェクトを比較するためのいくつかの簡単で、うまくいけば直感的な方法を提供します。

>>> ipaddress.ip_address('192.0.2.1') < ipaddress.ip_address('192.0.2.2')
True

異なるバージョンまたは異なるタイプのオブジェクトを比較しようとすると、 TypeError 例外が発生します。


他のモジュールでのIPアドレスの使用

IPアドレスを使用する他のモジュール( socket など)は通常、このモジュールからのオブジェクトを直接受け入れません。 代わりに、他のモジュールが受け入れる整数または文字列に強制変換する必要があります。

>>> addr4 = ipaddress.ip_address('192.0.2.1')
>>> str(addr4)
'192.0.2.1'
>>> int(addr4)
3221225985

インスタンスの作成が失敗した場合の詳細の取得

バージョンに依存しないファクトリ関数を使用してアドレス/ネットワーク/インターフェイスオブジェクトを作成すると、エラーは ValueError として報告され、渡された値がそのタイプのオブジェクトとして認識されなかったことを示す一般的なエラーメッセージが表示されます。 。 特定のエラーがないのは、拒否された理由の詳細を提供するために、値が想定がIPv4であるかIPv6であるかを知る必要があるためです。

この追加の詳細にアクセスできると便利なユースケースをサポートするために、個々のクラスコンストラクターは実際に ValueError サブクラス ipaddress.AddressValueError および ipaddress.NetmaskValueError を発生させます。定義のどの部分が正しく解析できなかったかを正確に示します。

クラスコンストラクターを直接使用すると、エラーメッセージが大幅に詳細になります。 例えば:

>>> ipaddress.ip_address("192.168.0.256")
Traceback (most recent call last):
  ...
ValueError: '192.168.0.256' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.IPv4Address("192.168.0.256")
Traceback (most recent call last):
  ...
ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.0.256'

>>> ipaddress.ip_network("192.168.0.1/64")
Traceback (most recent call last):
  ...
ValueError: '192.168.0.1/64' does not appear to be an IPv4 or IPv6 network
>>> ipaddress.IPv4Network("192.168.0.1/64")
Traceback (most recent call last):
  ...
ipaddress.NetmaskValueError: '64' is not a valid netmask

ただし、両方のモジュール固有の例外には、親クラスとして ValueError があるため、特定のタイプのエラーに関心がない場合でも、次のようなコードを記述できます。

try:
    network = ipaddress.IPv4Network(address)
except ValueError:
    print('address/netmask is invalid for IPv4:', address)