CUBE SUGAR STORAGE

技術系のことかきます。
Recent Tweets @

Python で IP, MAC アドレスを扱うためのライブラリに netaddr がある。 このライブラリは API がめちゃくちゃかっこいいので一見の価値あり。

インストールはいつも通り pip (PyPI) から。

$ pip install netaddr

IPAddress

まずは 1 つの IP アドレスを表す IPAddress のサンプル。 もちろん IPv6 にも対応してる。
>>> from netaddr.ip import IPAddress
>>> v4addr = IPAddress('192.168.0.1')
>>> v4addr.version
4
>>> v4addr.is_private()
True
>>> v4addr.is_multicast()
False
>>> str(v4addr)
'192.168.0.1'
>>> int(v4addr)
3232235521
>>> hex(v4addr)
'0xc0a80001'
>>> v4addr.bin
'0b11000000101010000000000000000001'
>>> v6addr = IPAddress('2001:0db8::0001:1')
>>> v6addr.version
6
>>> str(v6addr)
'2001:db8::1:1'

IPNetwork

次にプレフィックス付きの IP アドレスを表す IPNetwork を試してみる。
>>> v4netaddr = IPNetwork('192.0.2.1/24')
>>> v4netaddr.ip
IPAddress('192.0.2.1')
>>> v4netaddr.netmask
IPAddress('255.255.255.0')
>>> v4netaddr.broadcast
IPAddress('192.0.2.255')

アドレスやプレフィックス長を変更するには以下のようにする。
>>> v4netaddr.value = int(IPAddress('172.16.0.1'))
>>> v4netaddr.prefixlen = 16
>>> v4netaddr.cidr
IPNetwork('172.16.0.0/16')

IPv6 互換アドレスや IPv6 射影アドレスへの変換、逆変換もできる。
>>> v4netaddr.ipv6()
IPNetwork('::ffff:172.16.0.1/112')
>>> v4netaddr.ipv6(ipv4_compatible=True)
IPNetwork('::172.16.0.1/112')
>>> v4netaddr.ipv6().ipv4()
IPNetwork('172.16.0.1/16')
>>> v4netaddr.ipv6(ipv4_compatible=True).ipv4()
IPNetwork('172.16.0.1/16')

そしてなんと IPNetwork は IPAddress の配列として扱うことができる!
>>> v4netaddr[0]
IPAddress('172.16.0.0')
>>> v4netaddr[1]
IPAddress('172.16.0.1')
>>> [i for i in v4netaddr[0:2]]
[IPAddress('172.16.0.0'), IPAddress('172.16.0.1')]
>>> list(v4netaddr[0:2])
[IPAddress('172.16.0.0'), IPAddress('172.16.0.1')]
>>> [i for i in IPNetwork('192.168.0.1/30')]
[IPAddress('192.168.0.0'), IPAddress('192.168.0.1'), IPAddress('192.168.0.2'), IPAddress('192.168.0.3')]
>>> len(IPNetwork('192.168.0.1/30'))
4

IPRange

プレフィックスでキレイに切れない IP アドレスの範囲には IPRange を使うと良い。 こちらも IPNetwork と同様、IPAddress の配列として扱うことができる。
>>> from netaddr.ip import IPRange
>>> v4range = IPRange('172.16.0.1', '172.16.0.3')
>>> v4range
IPRange('172.16.0.1', '172.16.0.3')
>>> list(v4range)
[IPAddress('172.16.0.1'), IPAddress('172.16.0.2'), IPAddress('172.16.0.3')]

IPSet

IP アドレスを集合として扱うときは IPSet を使うと捗る。 IPSet 同士で論理演算すると計算結果が IPSet として得られる。
>>> from netaddr import IPSet
>>> IPSet(['172.16.0.0/16']) | IPSet(['172.17.0.0/16'])
IPSet(['172.16.0.0/15'])
>>> IPSet(['172.16.0.0/16']) | IPSet(['172.18.0.0/16'])
IPSet(['172.16.0.0/16', '172.18.0.0/16'])
>>> IPSet(['172.16.0.0/16']) & IPSet(['172.16.0.0/24'])
IPSet(['172.16.0.0/24'])
>>> IPSet(['172.16.0.0/16']) - IPSet(['172.16.0.0/17'])
IPSet(['172.16.128.0/17'])
>>> ips = IPSet(['172.16.128.0/17'])
>>> ips.update(['172.16.0.0/17'])
>>> ips
IPSet(['172.16.0.0/16'])

EUI

netaddr では MAC アドレスも扱うことができる。
>>> from netaddr import EUI
>>> macaddr = EUI('7c-d1-c3-01-02-03')
>>> macaddr
EUI('7C-D1-C3-01-02-03')
>>> str(macaddr)
'7C-D1-C3-01-02-03'
>>> macaddr.oui, macaddr.ei, macaddr.version
(OUI('7C-D1-C3'), '01-02-03', 48)
>>> macaddr.oui.registration()
{'address': ['1 Infinite Loop', 'cupertino  cA 95014', 'UNITED STATES'],
 'idx': 8180163,
 'offset': 2367351,
 'org': 'Apple Inc',
 'oui': '7C-D1-C3',
 'size': 123}

ちなみに IEEE に登録されていない MAC アドレスで OUI を扱おうとすると例外が上がる。
>>> EUI('ab-cd-ef-01-02-03').oui
Traceback (most recent call last):
…(snip)...
netaddr.core.NotRegisteredError: OUI 11259375 not registered!

ちょーべんりなんですけど。
  1. wnoguchi reblogged this from momijiame
  2. momijiame posted this