Pythonのipaddressモジュールの使い方を解説していく

スポンサーリンク

今日はPythonのipaddressモジュールについて学びます。

では、早速ですが、始めましょう。

スポンサーリンク

IPアドレスとは?

IPとは、インターネットプロトコルの略です。

ネットワーク上のノードを識別するために使用されます。

したがって、インターネットに接続するすべてのデバイスは、IP アドレスを所有する必要があります。

IPアドレスには、2つのバージョンがあります。

IPv4とIPv6です。

現在使用されているのはIPv4ですが、IPv6はネットワーク上の機器に比べてIPv4アドレスが不足しているため、主要なネットワークプロバイダーによって徐々に採用されつつあります。

IPアドレスの詳細については、こちらのWikiページをご覧ください。

How to use ipaddress module in Python?

では、さっそくipaddressモジュールを使ってみましょう。

ホストアドレスを設定するには、ipaddress.ip_address()を使用します。

この関数は、渡された値からどのバージョンを使用するかを自動的に判断します。

IPv4アドレスとIPv6アドレスのどちらかを返します。

1. 有効なIPv4アドレスの作り方は?

IPv4では、0から255の範囲の値を有効としています。

32ビットに収まる整数が、アドレスの1オクテットを表します。

長さ4バイトのオブジェクトにパックされた整数。

import ipaddress
ipaddress.ip_address('199.138.0.1')

結果は以下の通りです。

出力:

IPv4Address('199.138.0.1')

2. 有効なIPv6アドレスを作成するには?

IPv6では、0からffffまでの値を有効としています。

128ビットに収まる整数。

長さ16のバイトオブジェクトに収まる整数。

import ipaddress
ipaddress.ip_address('2011:cb0::')
ipaddress.ip_address('FFFF:9999:2:FDE:257:0:2FAE:112D')

出力してください。

出力:

IPv6Address('2011:cb0::')
IPv6Address('ffff:9999:2:fde:257:0:2fae:112d')

Python で ipaddress モジュールを使って IP アドレスを操作する

IPアドレスは、一連のルールを伴っています。

IPアドレスの範囲には、異なる機能が割り当てられています。

例えば、127.0.0.1はあなたのコンピュータのネットワーキングモジュールに割り当てられたループバックアドレスです。

このIPアドレスにpingパケットを送信すると、基本的に自分のコンピューターにpingを打っていることになります。

1. IPの基本機能

Pythonのipaddressモジュールを使って、どのアドレスがループバック、マルチキャスト、ローカルリンク、予約済みであるかを確認する方法を見てみましょう。

import ipaddress
 
ipa = ipaddress.ip_address('199.138.0.1')
print(ipa.is_private) # Checks if address is private
print(ipa.is_global)  # Checks if address is global
 
#If address is a loopback address
print(ipaddress.ip_address("127.0.0.1").is_loopback)
 
#If address is reserved for multiclass use
print(ipaddress.ip_address("229.100.0.23").is_multicast)
 
#If address is reserved for link local usage
print(ipaddress.ip_address("169.254.0.100").is_link_local)
 
#True if the address is otherwise IETF reserved.
print(ipaddress.ip_address("240.10.0.1").is_reserved)

結果は以下の通りです。

False
True
True
True
True
True

2. IP逆引き

逆引き機能は、ここで引数として追加されたIPアドレスの解決をDNSに依頼するものです。

DNSがIPを解決できた場合、割り当てられた名前が出力されます。

ドメイン名に割り当てられたIPにpingを打つと、そのドメインが存在するサーバーの名前が出力されることが多いようです。

ただし、これはファイアウォールの設定によって変わる可能性があります。

ipaddress.ip_address("199.138.0.1").reverse_pointer

出力してください。

'1.0.138.199.in-addr.arpa'

ipaddressモジュールを使ってIPネットワークを操作する

IPv4NetworkとIPv6Networkは、IPネットワーク定義の定義と検査を手助けしてくれます。

カスタムコードを書くことなく、必要なフォーマットでIPネットワークを取得することができます

  1. プレフィックス / は、ネットワークマスクの上位ビットの数を表します。
      1. ネットマスクは、高次ビットの数を設定したIPアドレスです。
    1. ホストマスクは、ネットマスクの論理的逆数で、Ciscoのアクセス制御リストで使用されます。
ipn = ipaddress.ip_network("10.0.0.0/16")
print(ipn.with_prefixlen)
print(ipn.with_hostmask)
print(ipn.with_netmask)

結果を出力すると、以下の様になります。

10.0.0.0/16
10.0.0.0/0.0.255.255
10.0.0.0/255.255.0.0

1. IPアドレスがIPv4かIPv6かを確認する

ipaddress.ip_network( )関数は、アドレスがどのようなネットワークに属しているかを返します。

IPがIP4ネットワークに属しているか、IP6ネットワークに属しているかを確認します。

import ipaddress
ipaddress.ip_network('199.138.0.1')
ipaddress.ip_network('FFFF:9999:2:FDE:257:0:2FAE:112D')

結果は以下の通りです。

出力:

IPv4Network('199.138.0.1/32')
IPv6Network('ffff:9999:2:fde:257:0:2fae:112d/128')

2. IPネットワーク上のホストの特定

ホストとは、ネットワークに属するIPアドレスのうち、ネットワークアドレスとネットワークブロードキャストアドレスを除くすべてのIPアドレスを指します。

host()は、ネットワーク上の使用可能なホストのイテレータを返します。

マスク長が31のネットワークでは、ネットワークアドレスとネットワークブロードキャストアド レスも結果に含まれ、マスク長が32のネットワークでは、単一のホストアドレスのリ ストが返されます。

ipn= ipaddress.ip_network('192.0.2.0/29')
list(ipn.hosts())

結果は、以下の通りです。

出力:

[IPv4Address('192.0.2.1'),
 IPv4Address('192.0.2.2'),
 IPv4Address('192.0.2.3'),
 IPv4Address('192.0.2.4'),
 IPv4Address('192.0.2.5'),
 IPv4Address('192.0.2.6')]

3. ネットワークのブロードキャストアドレスの特定

broadcast_addressで、ネットワーク上のブロードキャストアドレスをDNSサーバーに応答するように要求することができる。

ipn= ipaddress.ip_network('199.1.8.0/29')
ipn.broadcast_address

結果を出力すると、以下の様になります。

出力:

IPv4Address('199.1.8.7')

4. IPネットワークの重複を特定する

この関数は、あるネットワークの一部または全部が他のネットワークに含まれているかどうかを知ることができる。

真か偽のどちらかを返す。

ipn1 = ipaddress.ip_network("10.10.1.32/29")
ipn2 = ipaddress.ip_network("10.10.1.32/27")
ipn3 = ipaddress.ip_network("10.10.1.48/29")
print(ipn1.overlaps(ipn2))
print(ipn1.overlaps(ipn3))
print(ipn3.overlaps(ipn2))

出力。

True
False
True

5. IPネットワーク上のサブネット

prefixlen_diff は増加させるべきプレフィックス量、new_prefix はサブネットの新しいプレフィックスで、我々のプレフィックスより大きなものです。

ipn1 = ipaddress.ip_network("10.10.1.32/29")
print(list(ipn1.subnets()))
print(list(ipn1.subnets(prefixlen_diff=2)))
print(list(ipn1.subnets(new_prefix=30)))

結果を出力すると、以下の様になります。

[IPv4Network('10.10.1.32/30'), IPv4Network('10.10.1.36/30')]
[IPv4Network('10.10.1.32/31'), IPv4Network('10.10.1.34/31'), IPv4Network('10.10.1.36/31'), IPv4Network('10.10.1.38/31')]
[IPv4Network('10.10.1.32/30'), IPv4Network('10.10.1.36/30')]

6. ipaddressモジュールによるスーパーネットの作成

スーパーネットは、1つまたは複数のサブネットの組み合わせです。

スーパーネットについては、こちらで詳しく解説しています。

ipaddressモジュールのsupernetメソッドでは、必要に応じて情報を指定することで、サブネットを作成することができます

  • prefixlen_diff はプレフィックス長を増加させる量です。
  • new_prefix はサブネットの新しいプレフィックスで、我々のプレフィックスより大きくする必要があります。
ipnn = ipaddress.ip_network("172.10.15.160/29")
print(ipnn.supernet(prefixlen_diff=3))
print(ipnn.supernet(new_prefix=20))

結果は以下の通りです。

結果は以下の通りです。

172.10.15.128/26
172.10.0.0/20

7. あるIPネットワークが他のIPネットワークのスーパーネット/サブネットであるかどうかをチェックします。

あるネットワークが他のネットワークのサブネットである場合、またはあるネットワークが他のネットワークのスーパーネットである場合、trueを返します。

trueまたはfalseを返します。

a = ipaddress.ip_network("192.168.1.0/24")
b = ipaddress.ip_network("192.168.1.128/30")
 
print(b.subnet_of(a))
print(a.supernet_of(b))

出力。

出力:

True
True

8. IPv4Interface オブジェクトの操作

インターフェースオブジェクトはハッシュ化できるため、辞書のキーとして使用できます。

IPv4InterfaceはIPv4Addressのサブクラスなので、IPv4Addressの属性を全て継承しています。

ここで、199.167.1.6のIPアドレスは、ネットワーク199.167.1.0/24に存在します。

from ipaddress import IPv4Interface
ifc = IPv4Interface("199.167.1.6/24")
print(ifc.ip)
print(ifc.network)

結果は、以下の通りです。

199.167.1.6
199.167.1.0/24

ネットワークインターフェースは、プレフィックス表記、ネットマスク、ホストマスクで表すことができます。

interface = IPv4Interface('192.0.2.5/24')
print(interface.with_prefixlen)
print(interface.with_netmask)
print(interface.with_hostmask)

出力。

192.0.2.5/24
192.0.2.5/255.255.255.0
192.0.2.5/0.0.0.255

IPアドレスを使った雑多な操作

Pythonの比較演算子を使って、あるIPアドレスと他のIPアドレスを比較することができます

以下の例を見てください。

ipa1=ipaddress.ip_address("127.0.0.2")
ipa2=ipaddress.ip_address("127.0.0.1")
print(ipa1>ipa2)
print(ipa1==ipa2)
print(ipa1!=ipa2)

結果は以下の通りです。

True
False
True


IPアドレスのオブジェクトから整数を足したり引いたりすることができます

ipa = ipaddress.ip_address("10.10.1.0")
print( ipa + 9)

結果を出力すると、以下の様になります。

出力:

10.10.1.9

組み込み関数の str( ) と int( ) を使って、アドレスを文字列や整数に変換することができる。

str(ipaddress.IPv4Address('199.138.0.1'))
int(ipaddress.IPv4Address('192.198.0.1'))

結果を出力すると、以下の様になります。

出力:

'199.138.0.1'
3234201601

IPv6アドレスは、ゾーンIDを除いた文字列に変換される。

str(ipaddress.IPv6Address('::8'))
int(ipaddress.IPv6Address('::100'))

結果を出力すると、以下の様になります。

'::8'
256

まとめ

この記事では、IPv4とIPv6のアドレス、ネットワーク、インターフェイスについて学びました。

このようなコンテンツをもっと知りたい方は、ぜひご期待ください。

参考文献

IPAddressモジュール公式ドキュメント

タイトルとURLをコピーしました