今日は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 addressprint(ipaddress.ip_address("127.0.0.1").is_loopback)
#If address is reserved for multiclass useprint(ipaddress.ip_address("229.100.0.23").is_multicast)
#If address is reserved for link local usageprint(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)
|
結果は以下の通りです。
FalseTrueTrueTrueTrueTrue |
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ネットワークを取得することができます。
- プレフィックス / は、ネットワークマスクの上位ビットの数を表します。
-
-
- ネットマスクは、高次ビットの数を設定したIPアドレスです。
-
-
- ホストマスクは、ネットマスクの論理的逆数で、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))
|
出力。
TrueFalseTrue |
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
|
この記事もチェック:Pythonのturtleモジュールの使い方|座標とか色の指定のやり方を解説する
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))
|
出力。
出力:
TrueTrue |
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)
|
結果は以下の通りです。
TrueFalseTrue |
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モジュール公式ドキュメント