NETADDR(1) netaddr NETADDR(1)

netaddr - مستندات کتابخانه و ابزار مدیریت آدرس‌های شبکه netaddr

یک کتابخانه Python و یک ابزار CLI <> برای نمایش و دستکاری آدرس‌های شبکه در لایه ۳ (IP) و لایه ۲ (MAC).

ابزار netaddr از موارد زیر پشتیبانی می‌کند:

آدرس‌های لایه ۳

  • آدرس‌ها، زیرشبکه‌ها، ماسک‌ها و پیشوندهای IPv4 و IPv6
  • پیمایش، برش (slicing)، مرتب‌سازی، خلاصه‌سازی و دسته‌بندی شبکه‌های IP
  • پشتیبانی از قالب‌های مختلف بازه (CIDR، بازه‌ها و الگوهای دلخواه، nmap)
  • عملیات بر پایه مجموعه‌ها (اجتماع، اشتراک و غیره) روی آدرس‌های IP و زیرشبکه‌ها
  • تجزیه طیف گسترده‌ای از قالب‌ها و نمادگذاری‌های مختلف
  • جستجوی اطلاعات بلوک‌های IP در IANA
  • تولید جستجوهای معکوس DNS
  • ابرشبکه‌سازی (supernetting) و زیرشبکه‌سازی (subnetting)

آدرس‌های لایه ۲

  • نمایش و دستکاری آدرس‌های MAC و شناسه‌های EUI-64
  • جستجوی اطلاعات سازمانی IEEE (شامل OUI و IAB)
  • تولید آدرس‌های IPv6 مشتق‌شده

مستندات netaddr از رویکرد Diátaxis برای نگارش مستندات فنی https://diataxis.fr بهره می‌برد و به این صورت سازمان‌دهی شده است:

  • آموزش‌ها (Tutorials) <> شما را در مسیری گام‌به‌گام با برخی از قابلیت‌های netaddr آشنا می‌کنند. اگر به‌تازگی کار با netaddr را شروع کرده‌اید، از اینجا آغاز کنید.
  • راهنماهای کاربردی (How-to guides) <> دستورالعمل‌هایی گام‌به‌گام برای حل مسائل و سناریوهای رایج هستند.
  • مرجع (Reference) <> حاوی توضیحات فنی بخش‌های گوناگون سازوکار netaddr است (شامل مرجع API <>).

    صفحات این بخش شما را به صورت گام‌به‌گام با برخی از قابلیت‌های netaddr آشنا می‌کنند.

    اگر در استفاده از netaddr تازه‌کار هستید، از اینجا شروع کنید.

پیش از هر چیز باید کلاس‌ها و توابع گوناگون netaddr را به فضای‌نام (namespace) خود وارد کنید.

نکته:

این کار را تنها برای اهداف این آموزش انجام دهید. در کدهای خودتان، برای جلوگیری از تداخل نام‌ها (name clashes)، باید کلاس‌ها، توابع و مقادیر ثابتی را که وارد (import) می‌کنید به صورت صریح مشخص نمایید.
>>> from netaddr import *

ما همچنین ماژول کتابخانه استاندارد pprint را برای کمک به قالب‌بندی خروجی وارد می‌کنیم.

>>> import pprint

شیء IPAddress زیر یک آدرس IP منفرد را نمایش می‌دهد.

>>> ip = IPAddress('192.0.2.1')
>>> ip.version
4

فراخوانی repr() یک عبارت پایتون بازمی‌گرداند که در صورت اجرا در مفسر پایتون، می‌تواند برای بازسازی وضعیت شیء آدرس IP مشابه از ابتدا مورد استفاده قرار گیرد.

>>> repr(ip)
"IPAddress('192.0.2.1')"
>>> ip
IPAddress('192.0.2.1')

دسترسی به شیء IP در بافت رشته‌ای (string context)، مقدار آن را به صورت رشته برمی‌گرداند.

>>> str(ip)
'192.0.2.1'
>>> '%s' % ip
'192.0.2.1'
>>> ip.format()  # only really useful for IPv6 addresses.
'192.0.2.1'

شما می‌توانید یک آدرس IP را در قالب‌های گوناگون دیگری مشاهده کنید.

>>> int(ip) == 3221225985
True
>>> hex(ip)
'0xc0000201'
>>> ip.bin
'0b11000000000000000000001000000001'
>>> ip.bits()
'11000000.00000000.00000010.00000001'
>>> ip.words == (192, 0, 2, 1)
True

اشیای IPNetwork برای نمایش زیرشبکه‌ها، شبکه‌ها یا VLANهایی به کار می‌روند که پیشوندهای CIDR و netmaskها را می‌پذیرند.

>>> ip = IPNetwork('192.0.2.1')
>>> ip.ip
IPAddress('192.0.2.1')
>>> ip.network, ip.broadcast
(IPAddress('192.0.2.1'), None)
>>> ip.netmask, ip.hostmask
(IPAddress('255.255.255.255'), IPAddress('0.0.0.0'))
>>> ip.size
1

در این حالت، آدرس شبکه و برودکست (broadcast) یکسان هستند، مشابه با یک مسیر میزبان (host route).

>>> ip = IPNetwork('192.0.2.0/24')
>>> ip.ip
IPAddress('192.0.2.0')
>>> ip.network, ip.broadcast
(IPAddress('192.0.2.0'), IPAddress('192.0.2.255'))
>>> ip.netmask, ip.hostmask
(IPAddress('255.255.255.0'), IPAddress('0.0.0.255'))
>>> ip.size
256

و در نهایت، این شیء IPNetwork نمایانگر یک آدرس IP است که متعلق به یک زیرشبکه IP مشخص است.

>>> ip = IPNetwork('192.0.3.112/22')
>>> ip.ip
IPAddress('192.0.3.112')
>>> ip.network, ip.broadcast
(IPAddress('192.0.0.0'), IPAddress('192.0.3.255'))
>>> ip.netmask, ip.hostmask
(IPAddress('255.255.252.0'), IPAddress('0.0.3.255'))
>>> ip.size
1024

از نظر درونی، هر شیء IPNetwork تنها ۳ مقدار را ذخیره می‌کند:

  • مقدار آدرس IP به صورت یک عدد صحیح بدون علامت (unsigned integer)
  • یک ارجاع به ماژول پروتکل IP برای نسخه IP نمایش‌داده‌شده
  • بیت‌ماسکِ (bitmask) پیشوند CIDR

سایر مقادیر در هنگام دسترسی به صورت درجا (on-the-fly) محاسبه می‌شوند.

تنظیم مقدار آدرس IP و پیشوند CIDR پس از نمونه‌سازی (instantiation) شیء امکان‌پذیر است.

>>> ip = IPNetwork('0.0.0.0/0')
>>> ip
IPNetwork('0.0.0.0/0')
>>> ip.value = 3221225985
>>> ip
IPNetwork('192.0.2.1/0')
>>> ip.prefixlen
0
>>> ip.prefixlen = 23
>>> ip
IPNetwork('192.0.2.1/23')

طول پیشوند (prefix length) را می‌توان با تعیین یک subnet mask نیز تغییر داد:

>>> ip = IPNetwork('192.168.1.0/24')
>>> ip.netmask = '255.255.0.0'
>>> ip
IPNetwork('192.168.1.0/16')
>>> ip = IPNetwork('fe80::dead:beef/64')
>>> ip.netmask = 'ffff:ffff::'
>>> ip
IPNetwork('fe80::dead:beef/32')

همچنین ویژگی‌ای (property) وجود دارد که به شما امکان دسترسی به آدرس CIDR واقعی را می‌دهد که تمامی بیت‌های میزبان (host bits) را بر اساس پیشوند زیرشبکه CIDR از آدرس شبکه حذف می‌کند.

>>> ip = IPNetwork('192.0.2.1/23')
>>> ip.cidr
IPNetwork('192.0.2.0/23')

این ویژگی برای تعیین دقیق و صحیح برخی پیکربندی‌های شبکه بسیار کاربردی است.

اگر می‌خواهید به اطلاعات مربوط به تک‌تک آدرس‌های IP تشکیل‌دهنده زیرشبکه دسترسی داشته باشید، این امر از طریق فراخوانی‌های مستقیم متدهای فرعی در هر شیء IPAddress امکان‌پذیر است.

برای مثال، اگر می‌خواهید نمایش ارقام دودویی (باینری) هر آدرس را مشاهده کنید، می‌توانید به صورت زیر عمل نمایید.

>>> ip.ip.bits()
'11000000.00000000.00000010.00000001'
>>> ip.network.bits()
'11000000.00000000.00000010.00000000'
>>> ip.netmask.bits()
'11111111.11111111.11111110.00000000'
>>> ip.broadcast.bits()
'11000000.00000000.00000011.11111111'

پشتیبانی کامل از IPv6 ارائه شده است. بیایید چند مثال را بررسی کنیم:

>>> ip = IPAddress(0, 6)
>>> ip
IPAddress('::')
>>> ip = IPNetwork('fe80::dead:beef/64')
>>> str(ip), ip.prefixlen, ip.version
('fe80::dead:beef/64', 64, 6)
>>> int(ip.ip) == 338288524927261089654018896845083623151
True
>>> hex(ip.ip)
'0xfe8000000000000000000000deadbeef'

خروجی به سبک بیتی برای چنین اعداد طویلی به اندازهٔ هگزادسیمال خوش‌خوان نیست، اما این اثبات کارکرد آن است!

>>> ip.ip.bits()
'1111111010000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000:1101111010101101:1011111011101111'

در اینجا برخی از جزئیات شبکه‌ای برای یک زیرشبکهٔ IPv6 آورده شده است.

>>> ip.network, ip.broadcast, ip.netmask, ip.hostmask
(IPAddress('fe80::'), IPAddress('fe80::ffff:ffff:ffff:ffff'), IPAddress('ffff:ffff:ffff:ffff::'), IPAddress('::ffff:ffff:ffff:ffff'))

با گسترش روزافزون IPv6، به احتمال زیاد مایل خواهید بود که بتوانید میان نشانی‌های IPv4 و IPv6 به‌صورت یکپارچه تعامل برقرار کنید.

در اینجا چند متد آورده شده است که به دستیابی به این هدف کمک می‌کنند.

>>> IPAddress('192.0.2.15').ipv4()
IPAddress('192.0.2.15')
>>> ip = IPAddress('192.0.2.15').ipv6()
>>> ip
IPAddress('::ffff:192.0.2.15')
>>> ip.is_ipv4_mapped()
True
>>> ip.is_ipv4_compat()
False
>>> IPAddress('192.0.2.15').ipv6(ipv4_compatible=True)
IPAddress('::192.0.2.15')
>>> IPAddress('192.0.2.15').ipv6(ipv4_compatible=True).is_ipv4_compat()
True
>>> IPAddress('192.0.2.15').ipv6(True)
IPAddress('::192.0.2.15')
>>> ip = IPNetwork('192.0.2.1/23')
>>> ip.ipv4()
IPNetwork('192.0.2.1/23')
>>> ip.ipv6()
IPNetwork('::ffff:192.0.2.1/119')
>>> ip.ipv6(ipv4_compatible=True)
IPNetwork('::192.0.2.1/119')

>>> IPNetwork('::ffff:192.0.2.1/119').ipv6()
IPNetwork('::ffff:192.0.2.1/119')
>>> IPNetwork('::ffff:192.0.2.1/119').ipv6(ipv4_compatible=True)
IPNetwork('::192.0.2.1/119')
>>> IPNetwork('::ffff:192.0.2.1/119').ipv4()
IPNetwork('192.0.2.1/23')
>>> IPNetwork('::192.0.2.1/119').ipv4()
IPNetwork('192.0.2.1/23')

توجه داشته باشید که شیء IP به‌طور پیش‌فرض نشانی‌های IPv4 از نوع "نگاشت‌شده" (mapped) را بر نشانی‌های "سازگار" (compatible) ترجیح داده و بازمی‌گرداند. این انتخاب هدفمند بوده است چرا که قالب دوم منسوخ شده است (برای جزئیات به RFC 4291 مراجعه کنید).

اگر با یک شیء IPNetwork به‌گونه‌ای رفتار کنید که گویی یک شیء فهرست استاندارد Python است، به شما امکان دسترسی به فهرستی از اشیاء نشانی IP مجزا را می‌دهد. این امر البته صوری است و آن‌ها تا زمانی که به آن‌ها دسترسی پیدا نکنید ایجاد نمی‌شوند.

>>> ip = IPNetwork('192.0.2.16/29')

دسترسی به یک شیء IP با استفاده از بافت list()، مولد پیش‌فرض را فرامی‌خواند که فهرستی از تمام اشیاء IP در محدودهٔ مشخص‌شده توسط زیرشبکهٔ شیء IP را بازمی‌گرداند.

>>> ip_list = list(ip)
>>> len(ip_list)
8
>>> ip_list
[IPAddress('192.0.2.16'), IPAddress('192.0.2.17'), ..., IPAddress('192.0.2.22'), IPAddress('192.0.2.23')]

طول آن فهرست ۸ نشانی IP مجزا است.

>>> len(ip)
8

می‌توانید از دسترسی استاندارد بر پایه اندیس برای نشانی‌های IP در زیرشبکه استفاده کنید.

>>> ip[0]
IPAddress('192.0.2.16')
>>> ip[1]
IPAddress('192.0.2.17')
>>> ip[-1]
IPAddress('192.0.2.23')

همچنین می‌توانید از برش‌های فهرست روی نشانی‌های IP در زیرشبکه استفاده کنید.

>>> ip[0:4]
<generator object ...>

برش یک تابع مولد (generator function) است. این کار برای صرفه‌جویی در زمان و منابع سیستم انجام شده است، زیرا برخی برش‌ها برای زیرشبکه‌های خاص ممکن است بسیار بزرگ شوند!

نحوه دسترسی به تمام عناصر موجود در یک برش به این صورت است:

>>> list(ip[0:4])
[IPAddress('192.0.2.16'), IPAddress('192.0.2.17'), IPAddress('192.0.2.18'), IPAddress('192.0.2.19')]

برش‌زدن گسترده (Extended slicing) نیز پشتیبانی می‌شود.

>>> list(ip[0::2])
[IPAddress('192.0.2.16'), IPAddress('192.0.2.18'), IPAddress('192.0.2.20'), IPAddress('192.0.2.22')]

معکوس‌سازی فهرست.

>>> list(ip[-1::-1])
[IPAddress('192.0.2.23'), IPAddress('192.0.2.22'), ..., IPAddress('192.0.2.17'), IPAddress('192.0.2.16')]

استفاده از مولدها تضمین می‌کند که کار با زیرشبکه‌های بزرگ IP بهینه و کارآمد است.

>>> for ip in IPNetwork('192.0.2.0/23'):
...    print('%s' % ip)
...
192.0.2.0
192.0.2.1
192.0.2.2
192.0.2.3
...
192.0.3.252
192.0.3.253
192.0.3.254
192.0.3.255

در شبکه‌های IPv4 معمولاً فقط نشانی‌های بین نشانی شبکه و نشانی پخش همگانی (broadcast) را به رابط‌های میزبان واقعی روی سیستم‌ها اختصاص می‌دهید.

تکرارکننده (iterator) ارائه‌شده برای دسترسی به این نشانی‌های IP به شرح زیر است:

>>> for ip in IPNetwork('192.0.2.0/23').iter_hosts():
...     print('%s' % ip)
...
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
...
192.0.3.251
192.0.3.252
192.0.3.253
192.0.3.254

مرتب‌سازی استاندارد و متعارف نشانی‌ها و شبکه‌های IP امری نسبتاً رایج و مفید است.

نحوه کارکرد مرتب‌سازی روی نشانی‌های مجزا بدین صورت است:

>>> import random
>>> ip_list = list(IPNetwork('192.0.2.128/28'))
>>> random.shuffle(ip_list)
>>> sorted(ip_list)
[IPAddress('192.0.2.128'), IPAddress('192.0.2.129'), ..., IPAddress('192.0.2.142'), IPAddress('192.0.2.143')]

جهت سهولت کار، می‌توانید زیرشبکه‌های IP را هم‌زمان با نشانی‌ها مرتب کنید و آن‌ها می‌توانند به‌طور هم‌زمان ترکیبی از نشانی‌های IPv4 و IPv6 باشند (نشانی‌ها و شبکه‌های IPv4 پیش از موارد IPv6 قرار می‌گیرند).

>>> ip_list = [
... IPAddress('192.0.2.130'),
... IPAddress('10.0.0.1'),
... IPNetwork('192.0.2.128/28'),
... IPNetwork('192.0.3.0/24'),
... IPNetwork('192.0.2.0/24'),
... IPNetwork('fe80::/64'),
... IPAddress('::')]
>>> random.shuffle(ip_list)
>>> ip_list.sort()
>>> pprint.pprint(ip_list)
[IPAddress('10.0.0.1'),
 IPNetwork('192.0.2.0/24'),
 IPNetwork('192.0.2.128/28'),
 IPAddress('192.0.2.130'),
 IPNetwork('192.0.3.0/24'),
 IPAddress('::'),
 IPNetwork('fe80::/64')]

توجه داشته باشید که چگونه زیرشبکه‌های هم‌پوشان نیز به ترتیب از بزرگ‌ترین به کوچک‌ترین مرتب می‌شوند..SS "خلاصه‌سازی فهرستی از نشانی‌ها و زیرشبکه‌ها (Summarizing list of addresses and subnets)"

یک عملیات مفید دیگر، قابلیت خلاصه‌سازی گروه‌هایی از زیرشبکه‌ها و نشانی‌های IP و ادغام آن‌ها با یکدیگر در صورت امکان، به منظور ایجاد کوچک‌ترین فهرست ممکن از زیرشبکه‌های CIDR است.

شما این کار را در netaddr با استفاده از تابع cidr_merge() انجام می‌دهید.

ابتدا فهرستی از اشیاء IP ایجاد می‌کنیم که شامل ترکیبی مناسب از نشانی‌ها و زیرشبکه‌های جداگانه، به همراه چند مقدار متنی نشانی IP برای اطمینان بیشتر است. برای جالب‌تر شدن ماجرا، چند نشانی IPv6 نیز اضافه شده است.

>>> ip_list = [ip for ip in IPNetwork('fe80::/120')]
>>> ip_list.append(IPNetwork('192.0.2.0/24'))
>>> ip_list.extend([str(ip) for ip in IPNetwork('192.0.3.0/24')])
>>> ip_list.append(IPNetwork('192.0.4.0/25'))
>>> ip_list.append(IPNetwork('192.0.4.128/25'))
>>> len(ip_list)
515
>>> cidr_merge(ip_list)
[IPNetwork('192.0.2.0/23'), IPNetwork('192.0.4.0/24'), IPNetwork('fe80::/120')]

مفید است، این‌طور نیست؟

بسیار معمول است که یک زیرشبکهٔ بزرگ CIDR داشته باشید و بخواهید آن را به چندین بلوک مؤلفهٔ کوچک‌تر تقسیم کنید تا تخصیص‌های شبکه، قوانین دیوار آتش (firewall) و غیره را بهتر مدیریت کنید؛ netaddr ابزارهای لازم برای این کار را در اختیارتان می‌گذارد.

در اینجا یک بلوک شبکهٔ بزرگ کلاس B خصوصی /16 را در نظر می‌گیریم و آن را به مجموعه‌ای از بلوک‌های کوچک‌تر با اندازهٔ ۵۱۲ تقسیم می‌کنیم.

>>> ip = IPNetwork('172.24.0.0/16')
>>> ip.subnet(23)
<generator object ...>

بار دیگر، این متد به دلیل احتمال وجود تعداد زیادی مقدار بازگشتی بسته به اندازهٔ زیرشبکهٔ مشخص‌شده، یک تکرارکننده (iterator) تولید می‌کند.

>>> subnets = list(ip.subnet(23))
>>> len(subnets)
128
>>> subnets
[IPNetwork('172.24.0.0/23'), IPNetwork('172.24.2.0/23'), IPNetwork('172.24.4.0/23'), ..., IPNetwork('172.24.250.0/23'), IPNetwork('172.24.252.0/23'), IPNetwork('172.24.254.0/23')]

همچنین می‌توان فهرست ابرشبکه‌هایی (supernets) را که یک نشانی IP یا زیرشبکهٔ مشخص به آن‌ها تعلق دارد دریافت کرد. شما همچنین می‌توانید یک حد اختیاری تعیین کنید.

>>> ip = IPNetwork('192.0.2.114')
>>> supernets = ip.supernet(22)
>>> pprint.pprint(supernets)
[IPNetwork('192.0.0.0/22'),
 IPNetwork('192.0.2.0/23'),
 IPNetwork('192.0.2.0/24'),
 IPNetwork('192.0.2.0/25'),
 IPNetwork('192.0.2.64/26'),
 IPNetwork('192.0.2.96/27'),
 IPNetwork('192.0.2.112/28'),
 IPNetwork('192.0.2.112/29'),
 IPNetwork('192.0.2.112/30'),
 IPNetwork('192.0.2.114/31')]

در اینجا، به جای یک تولیدکننده (generator)، یک فهرست بازگردانده می‌شود؛ زیرا فهرست مقادیر بالقوه اندازه‌ای قابل‌پیش‌بینی دارد (حداکثر ۳۱ زیرشبکه برای یک نشانی IPv4 و ۱۲۷ برای IPv6).

اگرچه CIDR روشی سودمند برای توصیف موجز شبکه‌ها است، اما غالباً (به‌ویژه در IPv4 که پیش از مشخصات CIDR معرفی شده بود) ضروری است که بتوان فهرستی از نشانی‌های IP با نشانی شروع و پایان دلخواه تولید کرد که دقیقاً منطبق بر مرزهای ماسک بیتی نیستند.

تابع iter_iprange() دقیقاً امکان انجام این کار را به شما می‌دهد.

>>> ip_list = list(iter_iprange('192.0.2.1', '192.0.2.14'))
>>> len(ip_list)
14
>>> ip_list
[IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), ..., IPAddress('192.0.2.13'), IPAddress('192.0.2.14')]

همچنین دانستن اینکه فهرست واقعی زیرشبکه‌های CIDR که این محدودهٔ غیرهم‌تراز نشانی‌ها را به‌درستی پوشش می‌دهند چیست، بسیار سودمند است.

در اینجا cidr_merge() بار دیگر به کمک می‌آید.

>>> cidr_merge(ip_list)
[IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/30'), IPNetwork('192.0.2.12/31'), IPNetwork('192.0.2.14/32')]

تا پیش از پیدایش مشخصهٔ CIDR، مرسوم بود که netmask یک نشانی IPv4 بر اساس نخستین octet آن و با استفاده از مجموعه‌ای از قوانین کلاس‌بندی‌شده (classful، که نخستین‌بار در RFC 791 تعریف شدند) استنتاج شود.

شما غالباً با ارجاعاتی به آن‌ها در RFCهای مختلف روبه‌رو می‌شوید و کتابخانه‌های نرم‌افزاری متعددی نیز به‌خوبی از آن‌ها پشتیبانی می‌کنند. برای حفظ جامعیت، به‌جای کنار گذاشتن این مجموعه قوانین مهم (اما اکنون تا حدی تاریخی)، از آن‌ها از طریق تابعی با نام رمزگونهٔ cidr_abbrev_to_verbose() پشتیبانی می‌شود.

در اینجا مثالی از این قوانین برای کل فضای نشانی IPv4 آورده شده است.

>>> cidrs = [cidr_abbrev_to_verbose(octet) for octet in range(0, 256)]
>>> pprint.pprint(cidrs)
['0.0.0.0/8',
...
 '127.0.0.0/8',
 '128.0.0.0/16',
...
 '191.0.0.0/16',
 '192.0.0.0/24',
...
 '223.0.0.0/24',
 '224.0.0.0/4',
...
 '239.0.0.0/4',
 '240.0.0.0/32',
...
 '255.0.0.0/32']
>>> len(cidrs)
256

نشانی‌های IP به چندین دسته تقسیم می‌شوند که همهٔ آن‌ها برای تخصیص به‌عنوان نشانی‌های میزبان (host) مناسب نیستند.

>>> IPAddress('192.0.2.1').is_unicast()
True
>>> IPAddress('fe80::1').is_unicast()
True

برای شناسایی گروه‌های چندپخشی استفاده می‌شود (برای اطلاعات بیشتر به RFC 2365 و 3171 مراجعه کنید).

>>> IPAddress('239.192.0.1').is_multicast()
True
>>> IPAddress('ff00::1').is_multicast()
True

نشانی‌های موجود در محدوده‌های رزروشده برای استفادهٔ عمومی در دسترس نیستند.

>>> IPAddress('253.0.0.1').is_reserved()
True

یک بیت‌ماسک که برای تقسیم یک نشانی IP به نشانی شبکه و نشانی میزبان به‌کار می‌رود.

>>> IPAddress('255.255.254.0').is_netmask()
True

مشابه با netmask است، با این تفاوت که تمام بیت‌های آن معکوس شده‌اند.

>>> IPAddress('0.0.1.255').is_hostmask()
True

این نشانی‌ها به‌صورت داخلی درون پشتهٔ شبکهٔ IP استفاده می‌شوند و بسته‌های ارسال‌شده به این نشانی‌ها از طریق یک اتصال شبکه فیزیکی توزیع نمی‌شوند.

>>> IPAddress('127.0.0.1').is_loopback()
True
>>> IPAddress('::1').is_loopback()
True

اشیاء IPAddress می‌توانند با یکدیگر مقایسه شوند. از آنجا که یک شیء IPAddress می‌تواند هم بیانگر یک نشانی IP تکی و هم یک شبکه ضمنی باشد، بهتر است برای جلوگیری از نتایج نامتعارف، پیش از مقایسه اطمینان حاصل کنید که هر دو طرف مقایسه در شرایط یکسانی قرار دارند.

در اینجا چند نمونه از مقایسه‌های نشانی‌های IP تکی برای شروع آورده شده است.

>>> IPAddress('192.0.2.1') == IPAddress('192.0.2.1')
True
>>> IPAddress('192.0.2.1') < IPAddress('192.0.2.2')
True
>>> IPAddress('192.0.2.2') > IPAddress('192.0.2.1')
True
>>> IPAddress('192.0.2.1') != IPAddress('192.0.2.1')
False
>>> IPAddress('192.0.2.1') >= IPAddress('192.0.2.1')
True
>>> IPAddress('192.0.2.2') >= IPAddress('192.0.2.1')
True
>>> IPAddress('192.0.2.1') <= IPAddress('192.0.2.1')
True
>>> IPAddress('192.0.2.1') <= IPAddress('192.0.2.2')
True

حال بیایید موردی کمی جالب‌تر را بررسی کنیم.

>>> IPNetwork('192.0.2.0/24') == IPNetwork('192.0.2.112/24')
True

همممم... کمی عجیب به نظر می‌رسد، این‌طور نیست؟ دلیلش این است که به صورت پیش‌فرض، اشیاء IP زیرشبکه‌های خود (یا مرزهای کران پایین و بالا) را با یکدیگر مقایسه می‌کنند نه مقادیر تک‌تک نشانی‌های IP را.

راه‌حل این وضعیت بسیار ساده است. با دانستن این رفتار پیش‌فرض، تنها کافی است با استفاده از ویژگی‌های مستقیم، صریحاً مشخص کنید که می‌خواهید دقیقاً کدام بخش از هر شیء IP مقایسه شود.

>>> IPNetwork('192.0.2.0/24').ip == IPNetwork('192.0.2.112/24').ip
False
>>> IPNetwork('192.0.2.0/24').ip < IPNetwork('192.0.2.112/24').ip
True

حالا شد! در صورت تمایل می‌توانید برای مقایسه شبکه‌ها نیز به همین شیوه صریح عمل کنید (اگرچه الزاماً ضروری نیست).

>>> IPNetwork('192.0.2.0/24').cidr == IPNetwork('192.0.2.112/24').cidr
True

با داشتن این اطلاعات، در ادامه چند نمونه از مقایسه‌های شبکه آورده شده است.

>>> IPNetwork('192.0.2.0/24') == IPNetwork('192.0.3.0/24')
False
>>> IPNetwork('192.0.2.0/24') < IPNetwork('192.0.3.0/24')
True

این موضوع ناگزیر پرسش‌هایی را در مورد مقایسه اشیاء IPAddress (اسکالر) و اشیاء IPNetwork (برداری) با یکدیگر به وجود می‌آورد (یا دست‌کم باید بیاورد).

در اینجا نحوه برخورد netaddr با این وضعیت نشان داده شده است.

>>> IPAddress('192.0.2.0') == IPNetwork('192.0.2.0/32')
False
>>> IPAddress('192.0.2.0') != IPNetwork('192.0.2.0/32')
True

یک شبکه یا زیرشبکه IP با یک نشانی IP تکی متفاوت است و بنابراین نمی‌توانند (به‌طور مستقیم) مقایسه شوند.

اگر می‌خواهید آن‌ها را با موفقیت مقایسه کنید، باید به طور صریح مشخص کنید که کدام جنبه از شبکه IP را می‌خواهید با نشانی IP مورد نظر مطابقت دهید.

چنانچه یک /32 باشد، می‌توانید مانند زیر از اندیس اولین یا آخرین نشانی استفاده کنید:

>>> IPAddress('192.0.2.0') == IPNetwork('192.0.2.0/32')[0]
True
>>> IPAddress('192.0.2.0') == IPNetwork('192.0.2.0/32')[-1]
True
>>> IPAddress('192.0.2.0') != IPNetwork('192.0.2.0/32')[0]
False

همچنین اگر قصد مقایسه نشانی پایه را دارید، می‌توانید از آن استفاده کنید:

>>> IPAddress('192.0.2.0') == IPNetwork('192.0.2.0/32').ip
True
>>> IPAddress('192.0.2.0') != IPNetwork('192.0.2.0/32').ip
False

گرچه ممکن است این رویکرد در ابتدا کمی بیهوده به نظر برسد، اما netaddr تلاش می‌کند تا ضمن مجزا نگه‌داشتن نشانی‌های IP و شبکه‌ها از یکدیگر، تعامل‌پذیری معقولی را نیز میان آن‌ها فراهم سازد..SS پشتیبانی از DNS

ایجاد جستجوهای معکوس IP برای DNS یک وظیفه مدیریتی متداول است. این کار به ویژه برای نشانی‌های IPv6 بسیار دشوار و زمان‌بر است.

در اینجا نحوه انجام این کار با استفاده از متد reverse_dns() در شیء IPAddress آورده شده است.

>>> IPAddress('172.24.0.13').reverse_dns
'13.0.24.172.in-addr.arpa.'
>>> IPAddress('fe80::feeb:daed').reverse_dns
'd.e.a.d.b.e.e.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa.'

توجه داشته باشید که از ip6.int استفاده نمی‌شود چرا که این دامنه منسوخ شده است (برای جزئیات RFC 3152 را ببینید).

با توجه به پیشینه طولانی نسخه ۴ پروتکل IP، روش CIDR پدیده‌ای نسبتاً جدید به شمار می‌رود؛ از این رو بسیار محتمل است با سیستم‌ها و مستنداتی برخورد کنید که به محدوده‌های نشانی IP در قالب‌هایی غیر از CIDR ارجاع می‌دهند. تبدیل این نوع محدوده‌های دلخواه به CIDR و برعکس، کار چندان خوشایندی نیست. خوشبختانه netaddr تلاش می‌کند با دو کلاس اختصاصی، این کار را برای شما آسان سازد.

شما می‌توانید یک محدوده دلخواه نشانی IP را با استفاده از نشانی‌های کران پایین و بالا در قالب یک شیء IPRange نمایش دهید.

>>> r1 = IPRange('192.0.2.1', '192.0.2.15')
>>> r1
IPRange('192.0.2.1', '192.0.2.15')

شما می‌توانید درست مانند یک شیء IPNetwork، روی این محدوده‌ها پیمایش کرده و آن‌ها را اندیس‌گذاری کنید.

نکته مهم این است که می‌توانید آن را به معادل CIDR آن نیز تبدیل کنید.

>>> r1.cidrs()
[IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/29')]

در ادامه نحوه مقایسه IPRange و IPNetwork منفرد نشان داده شده است.

>>> IPRange('192.0.2.0', '192.0.2.255') != IPNetwork('192.0.2.0/24')
False
>>> IPRange('192.0.2.0', '192.0.2.255') == IPNetwork('192.0.2.0/24')
True

ممکن است بخواهید یک محدوده IP را در برابر فهرستی از اشیاء IPAddress و IPNetwork مقایسه کنید.

>>> r1 = IPRange('192.0.2.1', '192.0.2.15')
>>> addrs = list(r1)
>>> addrs
[IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), IPAddress('192.0.2.3'), IPAddress('192.0.2.4'), IPAddress('192.0.2.5'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), IPAddress('192.0.2.8'), IPAddress('192.0.2.9'), IPAddress('192.0.2.10'), IPAddress('192.0.2.11'), IPAddress('192.0.2.12'), IPAddress('192.0.2.13'), IPAddress('192.0.2.14'), IPAddress('192.0.2.15')]
>>> r1 == addrs
False

اوه! دقیقاً آن چیزی نشد که دنبالش بودیم یا انتظار داشتیم.

راهکار انجام این کار این است که هر دو طرف عملیات مقایسه را به یک نوع و قالب یکسان تبدیل کنیم.

>>> list(r1) == addrs
True

حالا شد، این همان چیزی است که می‌خواستیم.

همین موضوع برای اشیاء IPNetwork نیز صدق می‌کند.

>>> subnets = r1.cidrs()
>>> subnets
[IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/29')]
>>> r1 == subnets
False
>>> r1.cidrs() == subnets
True

روش بالا زمانی پاسخ می‌دهد که فهرست مقایسه‌شده شامل یکی از این نوع‌ها باشد، اما اگر فهرستی ترکیبی از IPAddress، IPNetwork و نشانی‌های متنی داشته باشید چه؟

اکنون زمان عملیات‌های کمی قدرتمندتر فرا رسیده است. بیایید از یک کلاس جدید برای کار با گروه‌های نشانی‌های IP و زیرشبکه‌ها استفاده کنیم: کلاس IPSet.

>>> ips = [IPAddress('192.0.2.1'), '192.0.2.2/31', IPNetwork('192.0.2.4/31'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), '192.0.2.8', '192.0.2.9', IPAddress('192.0.2.10'), IPAddress('192.0.2.11'), IPNetwork('192.0.2.12/30')]
>>> s1 = IPSet(r1.cidrs())
>>> s2 = IPSet(ips)
>>> s2
IPSet(['192.0.2.1/32', '192.0.2.2/31', '192.0.2.4/30', '192.0.2.8/29'])
>>> s1 == s2
True

بیایید یکی از عناصر را از یکی از اشیاء IPSet حذف کنیم و ببینیم چه رخ می‌دهد.

>>> s2.pop()
IPNetwork('...')
>>> s1 == s2
False

شاید این یک مثال ساختگی به نظر برسد، اما برخی از قابلیت‌های ارائه شده را به نمایش می‌گذارد.

برای جزئیات بیشتر در مورد این کلاس، آموزش IPSet یعنی Tutorial 3: Working with IP sets <> را ببینید..SS محدوده‌های سراسری IP (IP Glob ranges)

بسته netaddr همچنین از یک شیوهٔ کاربرپسند برای مشخص کردن محدوده‌های آدرس IP با استفاده از ساختار دستوری سبک «glob» پشتیبانی می‌کند.

نکته:

در حال حاضر تنها الگوهای glob برای IPv4 پشتیبانی می‌شوند.
>>> IPGlob('192.0.2.*') == IPNetwork('192.0.2.0/24')
True
>>> IPGlob('192.0.2.*') != IPNetwork('192.0.2.0/24')
False

از آنجا که IPGlob یک زیرکلاس از IPRange است، تمام همان عملیات روی آن نیز اعمال‌پذیر هستند.

پیش از هر چیز لازم است کلاس‌ها و توابع مختلف مرتبط با MAC را به فضای‌نام (namespace) خود وارد کنید.

نکته:

این کار را صرفاً برای اهداف این بخش آموزشی انجام دهید. در کدهای خود، باید کلاس‌ها، توابع و ثابت‌هایی را که وارد می‌کنید به صورت صریح مشخص نمایید تا از تداخل نام‌ها (name clashes) جلوگیری شود.
>>> from netaddr import *

می‌توانید با اطمینان نسبتاً بالایی همه چیز را از فضای‌نام netaddr وارد کنید، چرا که دقت کافی به عمل آمده تا تنها کلاس‌ها، توابع و ثابت‌های ضروری صادر شوند.

در صورتی که در مورد تداخل‌های نام احتمالی نامطمئن هستید، همیشه وارد کردن موارد مورد نیاز را به‌صورت دستی و انتخابی انجام دهید.

نمونه‌های کلاس EUI برای نمایش آدرس‌های MAC استفاده می‌شوند.

>>> mac = EUI('00-1B-77-49-54-FD')

دسترسی استاندارد از طریق repr() یک عبارت پایتون برمی‌گرداند که در صورت اجرا در مفسر پایتون، می‌تواند شیء آدرس MAC را از نو بازسازی کند.

>>> mac
EUI('00-1B-77-49-54-FD')

دسترسی به شیء EUI در بستر متنی (رشته‌ای).

>>> str(mac)
'00-1B-77-49-54-FD'
>>> '%s' % mac
'00-1B-77-49-54-FD'

در اینجا چند ویژگی متداول دیگر آورده شده است.

>>> str(mac), str(mac.oui), mac.ei, mac.version
('00-1B-77-49-54-FD', '00-1B-77', '49-54-FD', 48)

می‌توانید یک آدرس MAC تکی را در قالب‌های عددی مختلف دیگری مشاهده کنید.

>>> int(mac) == 117965411581
True
>>> hex(mac)
'0x1b774954fd'
>>> oct(mac)
'0o1556722252375'
>>> mac.bits()
'00000000-00011011-01110111-01001001-01010100-11111101'
>>> mac.bin
'0b1101101110111010010010101010011111101'

بسیار رایج است که آدرس MAC در قالب‌های متعددی به‌جز استاندارد معمول IEEE EUI-48 مشاهده شود.

سازنده کلاس EUI از تمامی این قالب‌های رایج پشتیبانی می‌کند.

>>> EUI('00-1B-77-49-54-FD')
EUI('00-1B-77-49-54-FD')

قالب با حروف کوچک IEEE EUI-48

>>> EUI('00-1b-77-49-54-fd')
EUI('00-1B-77-49-54-FD')

قالب رایج UNIX

>>> EUI('0:1b:77:49:54:fd')
EUI('00-1B-77-49-54-FD')

قالب سه‌تایی هگزت (triple hextet) سیسکو (Cisco)

>>> EUI('001b:7749:54fd')
EUI('00-1B-77-49-54-FD')
>>> EUI('1b:7749:54fd')
EUI('00-1B-77-49-54-FD')
>>> EUI('1B:7749:54FD')
EUI('00-1B-77-49-54-FD')

آدرس‌های MAC خام (بدون جداکننده)

>>> EUI('001b774954fd')
EUI('00-1B-77-49-54-FD')
>>> EUI('01B774954FD')
EUI('00-1B-77-49-54-FD')

قالب PostgreSQL (یافت‌شده در مستندات)

>>> EUI('001B77:4954FD')
EUI('00-1B-77-49-54-FD')

همچنین می‌توان قالبی انتخابی را برای خروجی رشته‌ای MAC در قالب یک کلاس 'dialect' تعیین کرد. کاربرد آن مشابه کلاس dialect مورد استفاده در ماژول csv کتابخانه استاندارد Python است.

>>> mac = EUI('00-1B-77-49-54-FD')
>>> mac
EUI('00-1B-77-49-54-FD')
>>> mac.dialect = mac_unix
>>> mac
EUI('0:1b:77:49:54:fd')
>>> mac.dialect = mac_unix_expanded
>>> mac
EUI('00:1b:77:49:54:fd')
>>> mac.dialect = mac_cisco
>>> mac
EUI('001b.7749.54fd')
>>> mac.dialect = mac_bare
>>> mac
EUI('001B774954FD')
>>> mac.dialect = mac_pgsql
>>> mac
EUI('001b77:4954fd')

البته در صورتی که گزینه‌های استاندارد پاسخگوی نیازهای شما نباشند، می‌توانید کلاس‌های dialect سفارشی خود را برای تنظیم قالب‌بندی MAC بسازید.

در ادامه نمونه‌ای از یک dialect دست‌کاری‌شده UNIX برای MAC آمده است که اکتت‌ها (octets) را با حروف بزرگ و صفرهای پیشین تولید می‌کند.

>>> class mac_custom(mac_unix): pass
>>> mac_custom.word_fmt = '%.2X'
>>> mac = EUI('00-1B-77-49-54-FD', dialect=mac_custom)
>>> mac
EUI('00:1B:77:49:54:FD')

شیءهای EUI رابطی به پایگاه‌های دادهٔ ثبت OUI (شناسهٔ منحصربه‌فرد سازمانی یا Organisationally Unique Identifier) و IAB (بلاک آدرس فردی یا Individual Address Block) که توسط IEEE ارائه می‌شوند فراهم می‌کنند.

نحوهٔ پرس‌وجوی یک OUI با استفاده از رابط EUI در اینجا آمده است:

>>> mac = EUI('00-1B-77-49-54-FD')
>>> oui = mac.oui
>>> oui
OUI('00-1B-77')
>>> oui.registration().address
['Lot 8, Jalan Hi-Tech 2/3', 'Kulim  Kedah  09000', 'MY']
>>> oui.registration().org
'Intel Corporate'

همچنین می‌توانید بدون استفاده از رابط EUI، مستقیماً از شیءهای OUI بهره ببرید.

تعداد اندکی از رکوردهای OUI دارای چند مورد ثبت در برابر خود هستند. مشخص نیست که آیا این موضوع برای ثبت اطلاعات تاریخی است یا صرفاً رفتاری غریب در فرایند ثبت IEEE.

این مثال نشان می‌دهد که چگونه می‌توانید با مشخص کردن شمارهٔ اندیس، به‌صورت جداگانه به آن‌ها دسترسی پیدا کنید:

>>> oui = OUI(524336)   #   OUI constructor accepts integer values, too.
>>> oui
OUI('08-00-30')
>>> oui.registration(0).address
['2380 N. ROSE AVENUE', 'OXNARD  CA  93010', 'US']
>>> oui.registration(0).org
'NETWORK RESEARCH CORPORATION'
>>> oui.registration(0).oui
'08-00-30'
>>> oui.registration(1).address
['GPO BOX 2476V', 'MELBOURNE  VIC  3001', 'AU']
>>> oui.registration(1).org
'ROYAL MELBOURNE INST OF TECH'
>>> oui.registration(1).oui
'08-00-30'
>>> oui.registration(2).address
['CH-1211', 'GENEVE  SUISSE/SWITZ  023', 'CH']
>>> oui.registration(2).org
'CERN'
>>> oui.registration(2).oui
'08-00-30'
>>> for i in range(oui.reg_count):
...     str(oui), oui.registration(i).org
...
('08-00-30', 'NETWORK RESEARCH CORPORATION')
('08-00-30', 'ROYAL MELBOURNE INST OF TECH')
('08-00-30', 'CERN')

نحوهٔ پرس‌وجوی یک IAB با استفاده از رابط EUI در اینجا آمده است:

>>> mac = EUI('00-50-C2-00-0F-01')
>>> mac.is_iab()
True
>>> iab = mac.iab
>>> iab
IAB('00-50-C2-00-00-00')
>>> iab.registration()
{'address': ['1241 Superieor Ave E', 'Cleveland  OH  44114', 'US'],
 'iab': '00-50-C2-00-00-00',
 'idx': 84680704,
 ...
 'org': 'T.L.S. Corp.',
 'size': 537}

پیش از هر چیز باید کلاس‌ها و توابع مختلف netaddr را به فضای نام (namespace) خود وارد کنید.

نکته:

این کار را تنها برای مقاصد این آموزش انجام دهید. در کدهای خود، باید کلاس‌ها، توابع و ثابت‌های وارداتی را به صراحت مشخص کنید تا از تداخل نام‌ها جلوگیری شود.
>>> from netaddr import *

در اینجا نحوهٔ ایجاد مجموعه‌های IP آورده شده است.

یک مجموعهٔ خالی.

>>> IPSet()
IPSet([])
>>> IPSet([])
IPSet([])
>>> len(IPSet([]))
0

می‌توانید نشانی‌های IP و شبکه‌ها را به‌صورت رشته مشخص کنید. همچنین می‌توانید از اشیاء IPAddress، IPNetwork، IPRange یا سایر اشیاء IPSet استفاده کنید.

>>> IPSet(['192.0.2.0'])
IPSet(['192.0.2.0/32'])
>>> IPSet([IPAddress('192.0.2.0')])
IPSet(['192.0.2.0/32'])
>>> IPSet([IPNetwork('192.0.2.0')])
IPSet(['192.0.2.0/32'])
>>> IPSet(IPNetwork('1234::/32'))
IPSet(['1234::/32'])
>>> IPSet([IPNetwork('192.0.2.0/24')])
IPSet(['192.0.2.0/24'])
>>> IPSet(IPSet(['192.0.2.0/32']))
IPSet(['192.0.2.0/32'])
>>> IPSet(IPRange("10.0.0.0", "10.0.1.31"))
IPSet(['10.0.0.0/24', '10.0.1.0/27'])
>>> IPSet(IPRange('0.0.0.0', '255.255.255.255'))
IPSet(['0.0.0.0/0'])

می‌توانید روی تمامی نشانی‌های IP که عضو مجموعهٔ IP هستند پیمایش کنید.

>>> for ip in IPSet(['192.0.2.0/28', '::ffff:192.0.2.0/124']):
...     print(ip)
192.0.2.0
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
192.0.2.5
192.0.2.6
192.0.2.7
192.0.2.8
192.0.2.9
192.0.2.10
192.0.2.11
192.0.2.12
192.0.2.13
192.0.2.14
192.0.2.15
::ffff:192.0.2.0
::ffff:192.0.2.1
::ffff:192.0.2.2
::ffff:192.0.2.3
::ffff:192.0.2.4
::ffff:192.0.2.5
::ffff:192.0.2.6
::ffff:192.0.2.7
::ffff:192.0.2.8
::ffff:192.0.2.9
::ffff:192.0.2.10
::ffff:192.0.2.11
::ffff:192.0.2.12
::ffff:192.0.2.13
::ffff:192.0.2.14
::ffff:192.0.2.15

>>> s1 = IPSet()
>>> s1.add('192.0.2.0')
>>> s1
IPSet(['192.0.2.0/32'])
>>> s1.remove('192.0.2.0')
>>> s1
IPSet([])
>>> s1.add(IPRange("10.0.0.0", "10.0.0.255"))
>>> s1
IPSet(['10.0.0.0/24'])
>>> s1.remove(IPRange("10.0.0.128", "10.10.10.10"))
>>> s1
IPSet(['10.0.0.0/25'])

در اینجا یک بازه ساده و دلخواه از آدرس‌های IP آورده شده است.

>>> iprange = IPRange('192.0.1.255', '192.0.2.16')

می‌توانیم شبکه‌های CIDR موجود در این بازه تعریف‌شده را مشاهده کنیم.

>>> iprange.cidrs()
[IPNetwork('192.0.1.255/32'), IPNetwork('192.0.2.0/28'), IPNetwork('192.0.2.16/32')]

در اینجا یک مجموعه IP آورده شده است.

>>> ipset = IPSet(['192.0.2.0/28'])

اکنون بیایید روی آدرس‌های IP موجود در این بازه دلخواه پیمایش کنیم و بررسی کنیم که آیا درون مجموعه IP یافت می‌شوند یا خیر.

>>> for ip in iprange:
...     print(ip, ip in ipset)
192.0.1.255 False
192.0.2.0 True
192.0.2.1 True
192.0.2.2 True
192.0.2.3 True
192.0.2.4 True
192.0.2.5 True
192.0.2.6 True
192.0.2.7 True
192.0.2.8 True
192.0.2.9 True
192.0.2.10 True
192.0.2.11 True
192.0.2.12 True
192.0.2.13 True
192.0.2.14 True
192.0.2.15 True
192.0.2.16 False

مجموعه‌های IPSet خاص‌تر

>>> bigone = IPSet(['0.0.0.0/0'])
>>> IPAddress("10.0.0.1") in bigone
True
>>> IPAddress("0.0.0.0") in bigone
True
>>> IPAddress("255.255.255.0") in bigone
True
>>> IPNetwork("10.0.0.0/24") in bigone
True
>>> IPAddress("::1") in bigone
False
>>> smallone = IPSet(["10.0.0.42/32"])
>>> IPAddress("10.0.0.42") in smallone
True
>>> IPAddress("10.0.0.41") in smallone
False
>>> IPAddress("10.0.0.43") in smallone
False
>>> IPNetwork("10.0.0.42/32") in smallone
True
>>> IPNetwork("10.0.0.42/31") in smallone
False

در اینجا چند مثال از عملیات اجتماع انجام‌شده بر روی اشیاء IPSet آورده شده است.

>>> IPSet(['192.0.2.0'])
IPSet(['192.0.2.0/32'])
>>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1'])
IPSet(['192.0.2.0/31'])
>>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) | IPSet(['192.0.2.3'])
IPSet(['192.0.2.0/31', '192.0.2.3/32'])
>>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) | IPSet(['192.0.2.3/30'])
IPSet(['192.0.2.0/30'])
>>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) | IPSet(['192.0.2.3/31'])
IPSet(['192.0.2.0/30'])
>>> IPSet(['192.0.2.0/24']) | IPSet(['192.0.3.0/24']) | IPSet(['192.0.4.0/24'])
IPSet(['192.0.2.0/23', '192.0.4.0/24'])

در اینجا مثالی از به کارگیری هم‌زمان عملیات‌های اجتماع، اشتراک و تفاضل متقارن آورده شده است.

>>> adj_cidrs = list(IPNetwork('192.0.2.0/24').subnet(28))
>>> even_cidrs = adj_cidrs[::2]
>>> evens = IPSet(even_cidrs)
>>> evens
IPSet(['192.0.2.0/28', '192.0.2.32/28', '192.0.2.64/28', '192.0.2.96/28', '192.0.2.128/28', '192.0.2.160/28', '192.0.2.192/28', '192.0.2.224/28'])
>>> IPSet(['192.0.2.0/24']) & evens
IPSet(['192.0.2.0/28', '192.0.2.32/28', '192.0.2.64/28', '192.0.2.96/28', '192.0.2.128/28', '192.0.2.160/28', '192.0.2.192/28', '192.0.2.224/28'])
>>> odds = IPSet(['192.0.2.0/24']) ^ evens
>>> odds
IPSet(['192.0.2.16/28', '192.0.2.48/28', '192.0.2.80/28', '192.0.2.112/28', '192.0.2.144/28', '192.0.2.176/28', '192.0.2.208/28', '192.0.2.240/28'])
>>> evens | odds
IPSet(['192.0.2.0/24'])
>>> evens & odds
IPSet([])
>>> evens ^ odds
IPSet(['192.0.2.0/24'])

مجموعه‌های IP این امکان را فراهم می‌کنند که بررسی کنید آیا گروهی از بازه‌های آدرس در مجموعه گروه دیگری از بازه‌های آدرس جای می‌گیرند یا خیر.

>>> s1 = IPSet(['192.0.2.0/24', '192.0.4.0/24'])
>>> s2 = IPSet(['192.0.2.0', '192.0.4.0'])
>>> s1
IPSet(['192.0.2.0/24', '192.0.4.0/24'])
>>> s2
IPSet(['192.0.2.0/32', '192.0.4.0/32'])
>>> s1.issuperset(s2)
True
>>> s2.issubset(s1)
True
>>> s2.issuperset(s1)
False
>>> s1.issubset(s2)
False

در اینجا مثال کامل‌تری با استفاده از بازه‌های مختلف و شناخته‌شده آدرس IPv4 آورده شده است.

>>> ipv4_addr_space = IPSet(['0.0.0.0/0'])
>>> private = IPSet(['10.0.0.0/8', '172.16.0.0/12', '192.0.2.0/24', '192.168.0.0/16', '239.192.0.0/14'])
>>> reserved = IPSet(['225.0.0.0/8', '226.0.0.0/7', '228.0.0.0/6', '234.0.0.0/7', '236.0.0.0/7', '238.0.0.0/8', '240.0.0.0/4'])
>>> unavailable = reserved | private
>>> available = ipv4_addr_space ^ unavailable

بیایید ببینیم چه چیزی به دست آورده‌ایم:

>>> for cidr in available.iter_cidrs():
...     print(cidr, cidr[0], cidr[-1])
0.0.0.0/5 0.0.0.0 7.255.255.255
8.0.0.0/7 8.0.0.0 9.255.255.255
11.0.0.0/8 11.0.0.0 11.255.255.255
12.0.0.0/6 12.0.0.0 15.255.255.255
16.0.0.0/4 16.0.0.0 31.255.255.255
32.0.0.0/3 32.0.0.0 63.255.255.255
64.0.0.0/2 64.0.0.0 127.255.255.255
128.0.0.0/3 128.0.0.0 159.255.255.255
160.0.0.0/5 160.0.0.0 167.255.255.255
168.0.0.0/6 168.0.0.0 171.255.255.255
172.0.0.0/12 172.0.0.0 172.15.255.255
172.32.0.0/11 172.32.0.0 172.63.255.255
172.64.0.0/10 172.64.0.0 172.127.255.255
172.128.0.0/9 172.128.0.0 172.255.255.255
173.0.0.0/8 173.0.0.0 173.255.255.255
174.0.0.0/7 174.0.0.0 175.255.255.255
176.0.0.0/4 176.0.0.0 191.255.255.255
192.0.0.0/23 192.0.0.0 192.0.1.255
192.0.3.0/24 192.0.3.0 192.0.3.255
192.0.4.0/22 192.0.4.0 192.0.7.255
192.0.8.0/21 192.0.8.0 192.0.15.255
192.0.16.0/20 192.0.16.0 192.0.31.255
192.0.32.0/19 192.0.32.0 192.0.63.255
192.0.64.0/18 192.0.64.0 192.0.127.255
192.0.128.0/17 192.0.128.0 192.0.255.255
192.1.0.0/16 192.1.0.0 192.1.255.255
192.2.0.0/15 192.2.0.0 192.3.255.255
192.4.0.0/14 192.4.0.0 192.7.255.255
192.8.0.0/13 192.8.0.0 192.15.255.255
192.16.0.0/12 192.16.0.0 192.31.255.255
192.32.0.0/11 192.32.0.0 192.63.255.255
192.64.0.0/10 192.64.0.0 192.127.255.255
192.128.0.0/11 192.128.0.0 192.159.255.255
192.160.0.0/13 192.160.0.0 192.167.255.255
192.169.0.0/16 192.169.0.0 192.169.255.255
192.170.0.0/15 192.170.0.0 192.171.255.255
192.172.0.0/14 192.172.0.0 192.175.255.255
192.176.0.0/12 192.176.0.0 192.191.255.255
192.192.0.0/10 192.192.0.0 192.255.255.255
193.0.0.0/8 193.0.0.0 193.255.255.255
194.0.0.0/7 194.0.0.0 195.255.255.255
196.0.0.0/6 196.0.0.0 199.255.255.255
200.0.0.0/5 200.0.0.0 207.255.255.255
208.0.0.0/4 208.0.0.0 223.255.255.255
224.0.0.0/8 224.0.0.0 224.255.255.255
232.0.0.0/7 232.0.0.0 233.255.255.255
239.0.0.0/9 239.0.0.0 239.127.255.255
239.128.0.0/10 239.128.0.0 239.191.255.255
239.196.0.0/14 239.196.0.0 239.199.255.255
239.200.0.0/13 239.200.0.0 239.207.255.255
239.208.0.0/12 239.208.0.0 239.223.255.255
239.224.0.0/11 239.224.0.0 239.255.255.255
>>> ipv4_addr_space ^ available
IPSet(['10.0.0.0/8', '172.16.0.0/12', '192.0.2.0/24', '192.168.0.0/16', '225.0.0.0/8', '226.0.0.0/7', '228.0.0.0/6', '234.0.0.0/7', '236.0.0.0/7', '238.0.0.0/8', '239.192.0.0/14', '240.0.0.0/4'])

در راستای رویکرد عمل‌گرایانه netaddr، شما می‌توانید به دلخواه IPv4 و IPv6 را در یک ساختار داده یکسان ترکیب کنید.

>>> s1 = IPSet(['192.0.2.0', '::ffff:192.0.2.0', '192.0.2.2', '::ffff:192.0.2.2'])
>>> s2 = IPSet(['192.0.2.2', '::ffff:192.0.2.2', '192.0.2.4', '::ffff:192.0.2.4'])
>>> s1
IPSet(['192.0.2.0/32', '192.0.2.2/32', '::ffff:192.0.2.0/128', '::ffff:192.0.2.2/128'])
>>> s2
IPSet(['192.0.2.2/32', '192.0.2.4/32', '::ffff:192.0.2.2/128', '::ffff:192.0.2.4/128'])

>>> s1 | s2
IPSet(['192.0.2.0/32', '192.0.2.2/32', '192.0.2.4/32', '::ffff:192.0.2.0/128', '::ffff:192.0.2.2/128', '::ffff:192.0.2.4/128'])
>>> s2 | s1
IPSet(['192.0.2.0/32', '192.0.2.2/32', '192.0.2.4/32', '::ffff:192.0.2.0/128', '::ffff:192.0.2.2/128', '::ffff:192.0.2.4/128'])

>>> s1 & s2
IPSet(['192.0.2.2/32', '::ffff:192.0.2.2/128'])

>>> s1 - s2
IPSet(['192.0.2.0/32', '::ffff:192.0.2.0/128'])
>>> s2 - s1
IPSet(['192.0.2.4/32', '::ffff:192.0.2.4/128'])

>>> s1 ^ s2
IPSet(['192.0.2.0/32', '192.0.2.4/32', '::ffff:192.0.2.0/128', '::ffff:192.0.2.4/128'])

>>> s1 = IPSet(['192.0.2.0', '192.0.2.1', '192.0.2.2'])
>>> s2 = IPSet(['192.0.2.2', '192.0.2.3', '192.0.2.4'])
>>> s1 & s2
IPSet(['192.0.2.2/32'])
>>> s1.isdisjoint(s2)
False
>>> s1 = IPSet(['192.0.2.0', '192.0.2.1'])
>>> s2 = IPSet(['192.0.2.3', '192.0.2.4'])
>>> s1 & s2
IPSet([])
>>> s1.isdisjoint(s2)
True

همانند یک مجموعه معمولی در Python، می‌توانید یک مجموعه IP را نیز با محتویات مجموعه‌ای دیگر به‌روزرسانی کنید.

>>> s1 = IPSet(['192.0.2.0/25'])
>>> s1
IPSet(['192.0.2.0/25'])
>>> s2 = IPSet(['192.0.2.128/25'])
>>> s2
IPSet(['192.0.2.128/25'])
>>> s1.update(s2)
>>> s1
IPSet(['192.0.2.0/24'])
>>> s1.update(['192.0.0.0/24', '192.0.1.0/24', '192.0.3.0/24'])
>>> s1
IPSet(['192.0.0.0/22'])
>>> s2 = IPSet(['10.0.0.0/16'])
>>> s2.update(IPRange('10.1.0.0', '10.1.255.255'))
>>> s2
IPSet(['10.0.0.0/15'])
>>> s2.clear()
>>> s2
IPSet([])

حذف یک آدرس IP از یک IPSet، زیرشبکه‌های CIDR درون آن را به بخش‌های تشکیل‌دهنده‌شان تقسیم می‌کند.

در اینجا مجموعه‌ای ایجاد می‌کنیم که کل فضای آدرس IPv4 را نشان می‌دهد.

>>> s1 = IPSet(['0.0.0.0/0'])
>>> s1
IPSet(['0.0.0.0/0'])

سپس آخرین آدرس را حذف می‌کنیم.

>>> s1.remove('255.255.255.255')

که نتیجه به این صورت خواهد بود:

>>> s1
IPSet(['0.0.0.0/1', '128.0.0.0/2', ..., '255.255.255.252/31', '255.255.255.254/32'])
>>> list(s1.iter_cidrs())
[IPNetwork('0.0.0.0/1'), IPNetwork('128.0.0.0/2'), ..., IPNetwork('255.255.255.252/31'), IPNetwork('255.255.255.254/32')]
>>> len(list(s1.iter_cidrs()))
32

بیایید نتیجه را با استفاده از تابع cidr_exclude بررسی کنیم.

>>> list(s1.iter_cidrs()) == cidr_exclude('0.0.0.0/0', '255.255.255.255')
True

سپس، نخستین آدرس را از بازه اصلی حذف می‌کنیم.

>>> s1.remove('0.0.0.0')

این کار زیرشبکه‌های CIDR را بیش از پیش خرد می‌کند.

>>> s1
IPSet(['0.0.0.1/32', '0.0.0.2/31', ..., '255.255.255.252/31', '255.255.255.254/32'])
>>> len(list(s1.iter_cidrs()))
62

می‌توانید به این کار ادامه دهید، اما آگاه باشید که مجموعه‌های IP بزرگ در صورتی که شامل چندین هزار مدخل باشند، ممکن است حافظه زیادی را مصرف کنند.

بیایید مجموعه IP خردشده در بخش قبلی را با افزودن مجدد آدرس‌های IP حذف‌شده، ترمیم کنیم.

>>> s1.add('255.255.255.255')
>>> s1
IPSet(['0.0.0.1/32', '0.0.0.2/31', ..., '64.0.0.0/2', '128.0.0.0/1'])

بهتر شد.

>>> list(s1.iter_cidrs())
[IPNetwork('0.0.0.1/32'), IPNetwork('0.0.0.2/31'), ..., IPNetwork('64.0.0.0/2'), IPNetwork('128.0.0.0/1')]
>>> len(list(s1.iter_cidrs()))
32

آدرس IP دیگر را مجدداً اضافه می‌کنیم.

>>> s1.add('0.0.0.0')

و به آدرس اصلی خود بازمی‌گردیم.

>>> s1
IPSet(['0.0.0.0/0'])

گاهی اوقات ممکن است بخواهید یک IPSet را مجدداً به یک IPRange تبدیل کنید.

>>> s1 = IPSet(['10.0.0.0/25', '10.0.0.128/25'])
>>> s1.iprange()
IPRange('10.0.0.0', '10.0.0.255')

این کار تنها در صورتی امکان‌پذیر است که IPSet پیوسته باشد

>>> s1.iscontiguous()
True
>>> s1.remove('10.0.0.16')
>>> s1
IPSet(['10.0.0.0/28', '10.0.0.17/32', '10.0.0.18/31', '10.0.0.20/30', '10.0.0.24/29', '10.0.0.32/27', '10.0.0.64/26', '10.0.0.128/25'])
>>> s1.iscontiguous()
False
>>> s1.iprange()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: IPSet is not contiguous

اگر پیوسته نباشد، همچنان می‌توانید IPSet را تبدیل کنید، اما چندین IPRange دریافت خواهید کرد. >>> list(s1.iter_ipranges()) [IPRange('10.0.0.0', '10.0.0.15'), IPRange('10.0.0.17', '10.0.0.255')]

>>> s2 = IPSet(['0.0.0.0/0'])
>>> s2.iscontiguous()
True
>>> s2.iprange()
IPRange('0.0.0.0', '255.255.255.255')
>>> s3 = IPSet()
>>> s3.iscontiguous()
True
>>> s3.iprange()
>>> s4 = IPSet(IPRange('10.0.0.0', '10.0.0.8'))
>>> s4.iscontiguous()
True

مشابه تمام کلاس‌های دیگر netaddr، می‌توانید از pickle برای ماندگارسازی IP setها جهت استفاده‌های بعدی استفاده کنید.

>>> import pickle
>>> ip_data = IPSet(['10.0.0.0/16', 'fe80::/64'])
>>> buf = pickle.dumps(ip_data)
>>> ip_data_unpickled = pickle.loads(buf)
>>> ip_data == ip_data_unpickled
True

>>> x = IPSet(['fc00::/2'])
>>> y = IPSet(['fc00::/3'])
>>> x > y
True
>>> x < y
False
>>> x != y
True

صفحات این بخش به صورت دستورالعمل بوده و مراحلی را برای حل مشکلات و موارد استفاده رایج ارائه می‌دهند.

توزیع‌های مختلف لینوکس آن را از طریق مدیرهای بسته خود در دسترس قرار می‌دهند.

ساده‌ترین راه برای نصب netaddr استفاده از pip است.

آخرین نسخه را از PyPI دریافت و نصب کنید - https://pypi.org/project/pip و دستور زیر را اجرا نمایید:

pip install netaddr

اگر تجربه بهتری در پوسته تعاملی <#interactive-shell> می‌خواهید، می‌توانید وابستگی اضافی IPython را بدین صورت نصب کنید:

pip install 'netaddr[nicer-shell]'

یا مستقیماً IPython را نصب نمایید:

pip install ipython

توزیع‌های مختلف لینوکس netaddr را از طریق مدیرهای بسته خود ارائه می‌دهند.

نکته:

نسخه‌های netaddr ارائه‌شده توسط توزیع‌های لینوکس ممکن است قدیمی باشند.

برای دستورالعمل‌های نصب به مستندات توزیع خود مراجعه کنید.

دستورهای نمونه:

# Debian, Ubuntu
sudo apt install python3-netaddr
# Fedora
# Base installation
sudo dnf install python3-netaddr
# The CLI tool
sudo dnf install python3-netaddr-shell

آخرین فایل tarball/zip منتشرشده را دریافت کرده و آن را در یک دایرکتوری موقت استخراج کنید یا مخزن را در یک دایرکتوری کاری محلی کلون نمایید.

بسته محلی را نصب کنید:

pip install .

این کار فایل‌های مورد نیاز را به‌طور خودکار در دایرکتوری lib/site-packages از نسخه پایتونی که برای اجرای اسکریپت نصب استفاده کرده‌اید قرار می‌دهد؛ همچنین ممکن است بخشی از یک virtualenv یا مدیر محیط مشابه باشد..SH "مرجع (REFERENCE)"

صفحات این بخش شامل توصیف فنی بخش‌های گوناگون سازوکار netaddr است.

netaddr از نسخه‌های پایتون زیر (CPython و PyPy) پشتیبانی می‌کند:

  • 3.7
  • 3.8
  • 3.9
  • 3.10
  • 3.11
  • 3.12

پشتیبانی از نسخه‌های زیر در 1.0.0 حذف شده است:

  • 2.7
  • 3.5
  • 3.6

پشتیبانی منسوخ شده و برای حذف برنامه‌ریزی شده است در netaddr 2:

•
3.7

این کتابخانه مستقل از سیستم‌عامل است.

این کتابخانه مستقل از معماری سخت‌افزار است.

این صفحه API عمومی netaddr را مستند می‌کند. تنها مواردی که صراحتاً در این مستندات ذکر شده‌اند پشتیبانی می‌شوند و بخشی از API عمومی به شمار می‌روند.

هر یک از موارد زیر خصوصی و پشتیبانی‌نشده در نظر گرفته می‌شوند:

  • هر چیزی درون هر یک از زیرماژول‌های netaddr (from netaddr.X import Y)
  • هر چیزی با نامی که با یک زیرخط آغاز شود (_X)
  • هر چیزی که صراحتاً به‌عنوان بخشی از API عمومی مستند نشده باشد

در اینجا سلسله‌مراتب کلاس‌ها برای کلاس‌های مرتبط با IP آمده است:

+---------+                                                +---------+
| ipv4(M) |                                                | ipv6(M) |
+---------+                                                +---------+
     |                                                          |
  (HAS A)                                                    (HAS A)
     |                                                          |
     +-----+----------------+-----------------+                 |
           |       +--------|-------+---------|--------+--------+
           |       |        |       |         |        |
           |       |        |       |         |        |
           v       v        v       v         |        |
         +-----------+    +-----------+       |        |
         | IPAddress |    | IPNetwork |       |        |
         +-----------+    +-----------+       |        |
               |                |             |        |
            (HAS A)          (HAS A)          |        |
               |                |             v        v
               +-------+--------+           +------------+
                       |                    |  IPRange   |
                       |                    +-----------+
                       v                          |
                   +-------+                      |
                   | IPSet |                      v
                   +-------+                  +--------+
                                              | IPGlob |
                                              +--------+

ثابت‌های زیر توسط آرگومان‌های گوناگون flags در سازنده‌های کلاس netaddr به کار می‌روند.

استفاده از معناشناسی inet_pton() به جای inet_aton() هنگام تجزیهٔ IPv4.

برای جزئیات بیشتر به مستندات IPAddress.__init__() مراجعه کنید.

در نسخهٔ 1.0.0 تغییر کرد: رد کردن صفرهای ابتدایی صرف‌نظر از پلتفرم آغاز شد (قبلاً در برخی پلتفرم‌ها مجاز بود).

استفاده از معناشناسی inet_aton() هنگام تجزیهٔ IPv4.

برای جزئیات بیشتر به مستندات IPAddress.__init__() مراجعه کنید.

در نسخهٔ 0.10.0 اضافه شد.

حذف هرگونه صفر ابتدایی از اوکتت‌های نشانی IPv4 پیش از تجزیه.

برای جزئیات بیشتر به مستندات IPAddress.__init__() مراجعه کنید.

حذف هرگونه بیت‌های میزبان یافت‌شده در سمت راست پیشوند اعمال‌شدهٔ CIDR.

برای جزئیات بیشتر به مستندات IPNetwork.__init__() مراجعه کنید.

نشانی IP یک نشانی مجازی است که برای شناسایی مبدأ و مقصد بسته‌های (لایهٔ ۳) منتقل‌شده میان میزبان‌ها در یک شبکهٔ سوئیچ‌شده استفاده می‌شود. این کتابخانه به‌طور کامل از هر دو استاندارد IPv4 و استاندارد جدیدتر IPv6 پشتیبانی می‌کند.

کلاس IPAddress برای شناسایی نشانی‌های IP منفرد به کار می‌رود.

کلاس‌های گویش زیر می‌توانند با متد IPAddress.format استفاده شوند.

کلاس IPNetwork برای نمایش گروهی از نشانی‌های IP استفاده می‌شود که یک شبکه/زیرشبکه/VLAN شامل میزبان‌ها را تشکیل می‌دهند.

امروزه، شبکه‌های IP معمولاً با استفاده از قالب CIDR به همراه یک پیشوند مشخص‌کنندهٔ اندازهٔ netmask تعیین می‌شوند. در دنیای واقعی، روش‌های متعددی برای بیان یک "شبکه" وجود دارد و انعطاف‌پذیری سازندهٔ کلاس IPNetwork بازتاب‌دهندهٔ این موضوع است.

کتابخانهٔ netaddr طوری طراحی شده است تا روش‌های گوناگونی را که در آن‌ها گروه‌هایی از نشانی‌های IP و شبکه‌های IP مشخص می‌شوند پوشش دهد؛ نه تنها در پیکربندی‌های مسیریاب، بلکه در شکل‌های کمتر استاندارد اما خواناتر برای انسان که برای نمونه در فایل‌های پیکربندی یافت می‌شوند.

گزینه‌هایی که در حال حاضر در دسترس هستند در ادامه آمده‌اند.

یک محدودهٔ کران‌دار، گروهی از نشانی‌های IP است که با استفاده از یک نشانی آغازین و یک نشانی پایانی مشخص شده و یک بلوک پیوسته را تشکیل می‌دهند. هیچ مرز بیتی مفروض نیست، اما نشانی پایانی باید از نظر عددی بزرگ‌تر یا مساوی نشانی آغازین باشد.

روشی بسیار کاربردی برای نمایش شبکهٔ IP در فایل‌های پیکربندی و در خط فرمان برای کسانی که با CIDR آشنایی ندارند.

کلاس IPGlob برای نمایش تک‌تک محدوده‌های glob به کار می‌رود.

توانایی تبدیل بین محدوده‌های glob و محدوده‌های CIDR و IP نیز بسیار کاربردی است. تابع زیر این تبدیل‌های گوناگون را امکان‌پذیر می‌سازد.

ابزار nmap یک ابزار شناخته‌شدهٔ امنیت شبکه است. این ابزار روش انعطاف‌پذیر ویژه‌ای برای تعیین گروه‌بندی‌های نشانی IP دارد.

توابعی ارائه شده‌اند که امکان اعتبارسنجی و شمارش نشانی‌های IP مشخص‌شده در این قالب را فراهم می‌کنند.

هنگام کار با تعداد زیادی از نشانی‌ها و محدوده‌های IP، اغلب دستکاری آن‌ها به عنوان مجموعه مفید است تا بتوانید اشتراک، اجتماع و تفاضل میان گروه‌های گوناگون آن‌ها را محاسبه کنید.

کلاس IPSet مشخصاً برای همین هدف ساخته شده است.

موارد زیر مجموعه‌ای از توابع کمکی کاربردی مرتبط با قالب‌های گوناگون پشتیبانی‌شده در این کتابخانه هستند..SS آدرس‌های MAC و استاندارد IEEE EUI

یک آدرس MAC، یک آدرس سخت‌افزاری 48-بیتی مرتبط با یک رابط فیزیکی مشخص در یک میزبان شبکه‌ای است. آن‌ها در تمامی دستگاه‌های شبکه‌ای یافت می‌شوند و برای شناسایی فریم‌ها (در لایه ۲) در پشته شبکه به کار می‌روند.

از کلاس EUI برای نمایش آدرس‌های MAC (و همچنین نمونه‌های بزرگ‌تر و کمتر رایج 64-بیتی آن‌ها) استفاده می‌شود.

از گویش‌های زیر برای مشخص کردن قالب‌بندی آدرس‌های MAC استفاده می‌شود.

چه کسی گفته شبکه همیشه باید خشک و جدی باشد؟ همیشه خوب است که فضا را تلطیف کنیم و کمی سرگرمی داشته باشیم.

بیایید واقع‌بین باشیم؛ هیچ کتابخانه شبکهٔ درست‌وحسابی بدون پشتیبانی از RFC 1924 - http://www.ietf.org/rfc/rfc1924 کامل نخواهد بود :-)

بسته netaddr شامل یک برنامه خط فرمانی netaddr است.

نکته:

این ابزار برای استفاده کاربران انسانی در نظر گرفته شده است. رابط کاربری آن را نباید پایدار فرض کرد. هنگام استفاده از آن در هرگونه بستر برنامه‌نویسی (بخوانید: اسکریپت‌نویسی) احتیاط کنید.

اگر به یک رابط پایدار نیاز دارید از API برنامه‌نویسی <> استفاده کنید.

برای مشاهده نحوه استفاده:

% netaddr --help
               __            __    __
   ____  ___  / /_____ _____/ /___/ /____
  / __ \/ _ \/ __/ __ `/ __  / __  / ___/
 / / / /  __/ /_/ /_/ / /_/ / /_/ / /
/_/ /_/\___/\__/\__,_/\__,_/\__,_/_/
usage: netaddr [-h]
The netaddr CLI tool
options:
-h, --help  show this help message and exit
Share and enjoy!

فراخوانی netaddr بدون هیچ آرگومانی یک پوسته تعاملی را اجرا می‌کند.

این پوسته در صورت در دسترس بودن از IPython https://pypi.org/project/ipython و در غیر این صورت از REPL توکار Python استفاده می‌کند. REPL مربوط به IPython قابلیت‌های بیشتری دارد و در مجموع تجربه کاربری بهتری ارائه می‌دهد.

این پوسته تمام بخش‌های API مربوط به netaddr <> را از پیش وارد می‌کند (pre-imported) تا بتوانید بلافاصله و با کمترین زحمت با آن کار کنید:

% netaddr
               __            __    __
   ____  ___  / /_____ _____/ /___/ /____
  / __ \/ _ \/ __/ __ `/ __  / __  / ___/
 / / / /  __/ /_/ /_/ / /_/ / /_/ / /
/_/ /_/\___/\__/\__,_/\__,_/\__,_/_/
netaddr shell 1.0.0 - an interactive shell for the netaddr library
In [1]: '10.0.0.2' in IPNetwork('10.0.0.0/24')
Out[1]: True
In [2]:

تغییریافته در نسخه 1.2.0: وابستگی به IPython اختیاری شد..SS اطلاعات شبکه

برای نمایش اطلاعات یک شبکه IP، دستور netaddr info <network> را اجرا کنید:

% netaddr info 192.2.2.27/24
               __            __    __
   ____  ___  / /_____ _____/ /___/ /____
  / __ \/ _ \/ __/ __ `/ __  / __  / ___/
 / / / /  __/ /_/ /_/ / /_/ / /_/ / /
/_/ /_/\___/\__/\__,_/\__,_/\__,_/_/
IP network information
CIDR                     192.2.2.0/24
Network IP               192.2.2.0
Network IP (binary)      11000000.00000010.00000010.00000000
Network IP (decimal)     3221357056
Network IP (hex)         0xc0020200
Subnet mask              255.255.255.0
Subnet mask (binary)     11111111.11111111.11111111.00000000
Broadcast IP             192.2.2.255
Range                    192.2.2.0-192.2.2.255
Total addresses          256
Usable range             192.2.2.1-192.2.2.254
Usable addresses         254

مراجع زیر برای کتابخانه netaddr کاربرد دارند.

RFCهای زیر راهنمای مجموعه ویژگی‌ها و قابلیت‌های netaddr بوده‌اند.

داده‌های برگرفته از منابع زیر از طریق API بسته netaddr ارائه می‌شوند.

فهرست پروتکل‌های IANA
فضای نشانی IPv4
فضای نشانی IPv6
ثبت‌های چندپخشی (Multicast)
ثبت سازمان‌های IEEE (IEEE Organisation Registry)
ثبت‌های OUI (شناسه منحصربه‌فرد سازمانی)
ثبت‌های IAB (بلوک آدرس انفرادی)

در اینجا نحوه انتشار نسخه جدیدی از netaddr آورده شده است.

•
مطمئن شوید که وابستگی‌های لازم را نصب کرده‌اید:
pip install --upgrade wheel twine
  • آخرین مجموعه تغییرات را برای شاخه master دریافت کنید (pull).

    فرض بر این است که ساخت شاخه master سبز (موفق) است و همه‌چیز به درستی کار می‌کند (یک فرایند CI فعال وجود دارد).

  • بالاترین بخش فایل CHANGELOG.rst را با جزئیات تمام تغییرات مهم از زمان آخرین انتشار که هنوز در آنجا نیستند، به‌روزرسانی کنید.

    تاریخ انتشار را روی روز جاری تنظیم کنید.

  • مشخص کنید که شماره نسخه جدید چه باید باشد (بسته به تغییراتی که در این انتشار موجود خواهد بود):
  • رفع اشکالات – افزایش نسخه وصله (patch version bump)
  • قابلیت‌های جدید – افزایش نسخه فرعی (minor version bump)
  • تغییرات اساسی یا ناسازگار – افزایش نسخه اصلی (major version bump)
•
شماره‌های نسخه را در سراسر کد منبع به‌روزرسانی کنید. این شامل تغییر شماره نسخه فعلی در موارد زیر می‌شود:
  • netaddr/__init__.py
  • docs/source/conf.py

و جایگزین کردن تمام نمونه‌های NEXT_NETADDR_VERSION با نسخه جدید (البته به جز مواردی مانند این فایل).

  • تمام تغییرات را کامیت (commit) کنید.
  • بسته را بسازید و منتشر کنید:
make build-and-publish
•
انتشار را تگ (tag) بزنید و آن را با مخزن راه دور همگام‌سازی کنید:
git tag -a x.y.z -m 'Release version x.y.z'
make push_tags
•
یک GitHub Release بر اساس تگی که به‌تازگی push کرده‌اید در https://github.com/netaddr/netaddr/releases/new ایجاد کنید.

محتویات جدید CHANGELOG.rst را در آنجا قرار دهید و پیوند "Full changelog" را در انتها اضافه کنید (از انتشار قبلی کپی کرده و تطبیق دهید).

تاریخ: هنوز منتشر نشده است

تاریخ: 2024-05-28

افزوده‌شده:

•
افزودن بسط نشانی جزئی در IPNetwork از طریق سوئیچ expand_partial؛ این قابلیت امکان انتخاب اختیاری رفتار پیش از نسخهٔ 1.1.0 را فراهم می‌کند

برطرف‌شده:

  • رفع مشکل اجرای مجموعه آزمون‌ها روی سیستم‌های musl
  • اصلاح تجزیهٔ IPv6 در IPAddress هنگام فعال بودن ZEROFILL <#netaddr.ZEROFILL>
  • اصلاح مدیریت پرچم NOHOST <#netaddr.NOHOST> در سازندهٔ کپی IPNetwork

تاریخ: 2024-02-17

برطرف‌شده:

•
اصلاح بارگذاری اشتباه نسخهٔ 1.2.0 در PyPI – اکنون پس‌گرفته (yanked) شده است. بدون هیچ تغییری در بسته.

تاریخ: 2024-02-17

افزوده‌شده:

•
افزودن زیرفرمان ابزار CLI برای نمایش اطلاعات شبکه <#cli-network-info>.

تغییریافته:

•
پشتیبانی از اجرای شل تعاملی <#interactive-shell> بدون نیاز به نصب IPython.

برطرف‌شده:

•
ایجاد صریح خطای TypeError در صورت ارسال مقداری غیررشته‌ای به valid_ipv4() یا valid_ipv6().

تاریخ: 2024-02-15

افزوده‌شده:

برطرف‌شده:

  • اصلاح نتایج منفی کاذب در IPNetwork(...) in IPRange(...) (GH #157 https://github.com/netaddr/netaddr/issues/157).
  • اصلاح چند حالت حدی در برش‌زدن IPNetwork (GH #214 https://github.com/netaddr/netaddr/issues/214).
  • اصلاح پشتیبانی از نشانی‌های جزئی IP که تصادفاً در نسخهٔ 1.0.0 در IPNetwork باقی مانده بود.

    هنگام حذف سوئیچ implicit_prefix، این نکته نادیده مانده بود که مقداری بسط نشانی جزئی IPv4 به صورت بدون شرط اعمال می‌شد.

    اگر به رفتار پیشین نیاز دارید از expand_partial_ipv4_address() استفاده کنید.

    موضوع مرتبط در GH: #110 https://github.com/netaddr/netaddr/issues/110.

  • اصلاح دسته‌بند نادرست مجوز در فراداده‌های بسته.

    تاریخ: 2024-02-10

    حذف‌شده:

  • قطع پشتیبانی از نگارش‌های Python پایین‌تر از 3.7.
  • حذف نام‌های کوتاه پرچم‌ها: N، P و Z. به‌جای آن‌ها از NOHOST <#netaddr.NOHOST>، INET_PTON <#netaddr.INET_PTON> و ZEROFILL <#netaddr.ZEROFILL> استفاده کنید.
  • حذف پشتیبانی از قالب مختصر CIDR در IPNetwork (implicit_prefix=True)، در صورت نیاز به این رفتار از cidr_abbrev_to_verbose() استفاده کنید.
  • حذف متد IPAddress.is_private.

    جایگزین‌های دقیق‌تری برای زیرمجموعه‌ای از نشانی‌ها که پیش‌تر توسط is_private پردازش می‌شدند وجود دارد:

  • IPAddress.is_link_local()
  • IPAddress.is_ipv4_private_use()
  • IPAddress.is_ipv6_unique_local()
  • IPAddress.is_global()

بلوک‌های نشانی زیر که قبلاً توسط is_private پردازش می‌شدند فاقد متدهای کمکی اختصاصی هستند و باید آن‌ها را به صورت دستی مدیریت کنید یا درخواست افزودن متد بدهید:

  • 100.64.0.0/10 – فضای نشانی اشتراکی (Shared Address Space)
  • 192.0.0.0/24 – تخصیص‌های پروتکل IETF (دقت کنید – استثنائاتی در آن وجود دارد)
  • 198.18.0.0/15 – محک‌زنی (Benchmarking)
  • 239.0.0.0-239.255.255.255 – 240.0.0.0/4 رزرو شده است، 239.0.0.0/8 – نامشخص

تغییریافته:

  • توقف پذیرش صفرهای ابتدایی هنگام تجزیه نشانی‌های IPv4 در حالت INET_PTON <#netaddr.INET_PTON> (این ویژگی در برخی پلتفرم‌ها مجاز بود).

    اگر نیاز به مجاز دانستن و نادیده گرفتن صفرهای ابتدایی دارید از پرچم ZEROFILL <#netaddr.ZEROFILL> استفاده کنید.

    این تغییر بر تبدیل‌های ضمنی از str در تمامی زمینه‌های مرتبط اثر خواهد گذاشت. اگر نیاز به کنترل حالت تجزیه IPv4 دارید، اشیاء IPAddress را به صورت صریح بسازید.

  • توقف تجزیه مسامحه‌آمیز (مانند inet_aton()) نشانی‌های IPv4 به‌طور پیش‌فرض.

    حالت INET_PTON <#netaddr.INET_PTON> حالت پیش‌فرض است.

    اگر نیاز به رفتار مسامحه‌آمیز و تجزیه با استفاده از معناشناسی inet_aton() دارید، از پرچم INET_ATON <#netaddr.INET_ATON> استفاده کنید.

    این تغییر بر تبدیل‌های ضمنی از str در تمامی زمینه‌های مرتبط اثر خواهد گذاشت. اگر نیاز به کنترل حالت تجزیه IPv4 دارید، اشیاء IPAddress را به صورت صریح بسازید.

  • اعمال دو تغییر فوق روی valid_ipv4() نیز.
  • به‌روزرسانی پایگاه‌داده‌های نشانی به نگارش‌های 2024-02-10.

رفع‌شده:

  • بازگرداندن False به‌جای ایجاد خطای AddrFormatError هنگام ارسال یک رشته خالی به valid_ipv4() یا valid_ipv6().
  • رفع مشکل مدیریت dialect ارائه‌شده به EUI هنگام ساخت رونوشت (copy-construction).

تاریخ: 2024-01-02

رفع‌شده:

•
حذف برخی هشدارها

منسوخ‌شده:

  • منسوخ شدن نام‌های کوتاه پرچم‌ها: N، P و Z. به‌جای آن‌ها از NOHOST <#netaddr.NOHOST>، INET_PTON <#netaddr.INET_PTON> و ZEROFILL <#netaddr.ZEROFILL> استفاده کنید.
  • منسوخ شدن وارد کردن اشیاء از زیربسته‌های netaddr. تنها وارد کردن موارد از فضای نام سطح‌بالای netaddr پشتیبانی می‌شود و سایر موارد خصوصی در نظر گرفته می‌شوند.

    این موضوع از قبل نیز برقرار بوده است، اما نیاز به یادآوری داشت.

  • منسوخ شدن تجزیه مسامحه‌آمیز پیش‌فرض IPv4 در valid_ipv4(). معناشناسی inet_pton() (که در آن صفرهای ابتدایی همواره غیرمجاز هستند) پیش‌فرض خواهد شد. در صورت نیاز به رفتار قدیمی، از پرچم‌های INET_ATON <#netaddr.INET_ATON> و/یا ZEROFILL <#netaddr.ZEROFILL> استفاده کنید.

    تاریخ: 2023-12-31

    افزوده‌شده:

  • افزودن پرچم INET_ATON <#netaddr.INET_ATON> جهت درخواست صریح معناشناسی تجزیهٔ IPv4 به سبک inet_aton() از IPAddress.
  • افزودن متد کمکی IPAddress.is_ipv4_private_use().
  • افزودن متد کمکی IPAddress.is_global() جهت امکان تشخیص اینکه آیا یک نشانی در سطح سراسری در دسترس در نظر گرفته می‌شود یا خیر.
  • افزودن متد کمکی IPAddress.is_ipv6_unique_local().

برطرف‌شده:

•
بهبود سازگاری با Python 3.13، با تشکر از John Eckersberg.

منسوخ‌شده:

  • منسوخ شدن پشتیبانی از Python 3.7.
  • منسوخ شدن پشتیبانی از قالب CIDR کوتاه‌شده در IPNetwork (implicit_prefix=True).
  • منسوخ شدن پذیرش صفرهای پیشتاز هنگام تجزیهٔ نشانی‌های IPv4 در حالت INET_PTON <#netaddr.INET_PTON> (این مورد در برخی پلتفرم‌ها مجاز بود).

    اگر نیاز به مجاز دانستن و نادیده گرفتن صفرهای پیشتاز دارید، از پرچم ZEROFILL <#netaddr.ZEROFILL> استفاده کنید.

    این تغییر بر تبدیل‌های ضمنی از str در تمام زمینه‌های مرتبط تأثیر خواهد گذاشت. اگر نیاز دارید حالت تجزیهٔ IPv4 را کنترل کنید، اشیاء IPAddress را به‌طور صریح ایجاد نمایید.

  • منسوخ شدن تجزیهٔ آسان‌گیرانهٔ پیش‌فرض نشانی‌های IPv4 (مشابه inet_aton()).

    حالت INET_PTON <#netaddr.INET_PTON> به حالت پیش‌فرض تبدیل خواهد شد.

    اگر نیاز به رفتار آسان‌گیر و تجزیه با استفاده از معناشناسی inet_aton() دارید، از پرچم INET_ATON <#netaddr.INET_ATON> استفاده کنید.

    این تغییر بر تبدیل‌های ضمنی از str در تمام زمینه‌های مرتبط تأثیر خواهد گذاشت. اگر نیاز دارید حالت تجزیهٔ IPv4 را کنترل کنید، اشیاء IPAddress را به‌طور صریح ایجاد نمایید.

  • منسوخ شدن متد IPAddress.is_private. دستورالعمل‌های مهاجرت در مستندات آورده شده است.

سایر:

  • ایجاد استثنا در صورت ارسال پرچم‌های نامعتبر به IPAddress، IPNetwork یا IPRange.
  • بهبود اساسی و قابل توجه مستندات.
  • به‌روزرسانی فایل‌های DB به جدیدترین نسخه‌ها (2023-12-23).

تاریخ: 2023-09-18

افزوده‌شده:

•
افزودن قابلیت‌های درهم‌سازی (hash) به OUI (#225, amitmi704)

برطرف‌شده:

  • ناسازگار با نسخه‌های پیشین: پشتیبانی از نشانی‌های IPv6 در RFC 6164 (عدم رزرو اولین نشانی IP در زیرشبکه‌های نقطه-به-نقطه) ($267, Damien Claisse)
  • از نظر فنی ناسازگار با نسخه‌های پیشین: اصلاح رفتار is_loopback – در نظر گرفتن IPNetwork('::1/128') به عنوان لوپ‌بک (#222, #223, niels)
  • گنجاندن آموزش‌ها در توزیع‌های کد منبع (#215, Louis Sautier)
  • اصلاح یک غلط املایی در مستندات (#242, Wouter)
  • اصلاح نحو دستور print در مستندات جهت سازگاری با Python 3 (#221, François Magimel)
  • اصلاح نحو Sphinx در مستندات (#220, François Magimel)

سایر:

  • به‌روزرسانی پایگاه‌های داده (#266, Jakub Stasiak)
  • منسوخ شدن Python 3.6 (#263, Jakub Stasiak)
  • حذف فراخوانی‌های غیرضروری eval (#228, KOLANICH)

    تاریخ: 3 ژوئیه 2020

  • رفع مشکل پشتیبانی از ارجاع ضعیف (weak reference) در کلاس‌های دارای __slots__
  • افزودن متد __bytes__ به IPAddress برای استفاده شهودی، با تشکر از Michael Belousov.
  • افزودن تابع format() به EUI، با تشکر از Omer Anson.
  • افزودن تنظیم‌کننده ویژگی (property setter) برای IPNetwork.netmask، با تشکر از Naveen Nathan.
  • افزودن پشتیبانی از IABها در OUI با شناسه 40:D8:55، با تشکر از Brian Maissy.
  • بهینه‌سازی چشمگیر تابع spanning_cidr()، با تشکر از Brian Maissy.
  • اصلاح آزمون‌های "x.x.x.x/x" in IPNetwork، با تشکر از xpac1985.
  • افزودن پشتیبانی از ارسال تکرارپذیرهای IPRange به IPSet و cidr_merge()، بر اساس وصله‌ای از Henry Stern.

•
پیچیدگی N log N به‌جای خطی
•
ایجاد کارآمد یک IPSet بزرگ از فهرستی از IPRangeها؟
•
پشتیبانی از ارجاع ضعیف

•
انتشار بعدی (0.9.0) شامل یک تغییر ناسازگار با گذشته در رفتار IPNetwork خواهد بود. این مورد مربوط به مدیریت نشانی‌های IPv6 در RFC 6164 (پیشوندهای /127 و /128) است: IPNetwork.broadcast برای آن‌ها مقدار None بازخواهد گرداند و نشانی‌های نخست در شبکه‌ها دیگر هنگام پیمایش IPNetwork و IPNetwork.iter_hosts() نادیده گرفته نمی‌شوند. برای دیدن وصله واقعی، به https://github.com/netaddr/netaddr/pull/168 (یا کامیت 2984c0a40a70 که موقتاً در این مخزن بازگردانده شده است) مراجعه کنید.

تاریخ: 19 ژوئن 2020

  • اصلاح بازگشت از تکرارکننده در Python 3.7+، توسط Sergey Kozlov.
  • رفع هشدار نحوی (SyntaxWarning) در Python 3.8 هنگام استفاده از is not با رشته‌های لیترال، توسط Stefan Nordhausen.
  • رفع DeprecationWarnings با استفاده از رشته‌های خام (raw strings) برای نویسه‌های گریز در عبارت‌های باقاعده (regex)، توسط Sean McGinnis.
  • بهبود مستندات IPGlob، توسط obkmeta.
  • اصلاح ایجاد استثنا در حالت‌های خاص با ارسال صریح پارامترهای پیام خطا به‌صورت تاپل (tuple)، توسط Matthias Urlichs.
  • توقف جایگزینی دستی shebang در اسکریپت ضمیمه‌شده.
  • توقف استفاده از __file__ در تمامی کدهایی که انتظار می‌رود در محیط‌های فاقد پشتیبانی از آن اجرا شوند (مانند باینری‌های تولیدشده با PyOxidizer).
  • به‌روزرسانی تمامی پایگاه‌های داده موجود در بسته.

•
شکست آزمون test_ip_splitter_remove_prefix_larger_than_input_range در python 3.7
•
هشدار نحو ""is not" with a literal." SyntaxWarning
•
پایگاه‌های داده oui قدیمی هستند
•
اجتناب از استفاده از __file__
  • نسخه‌های Python 2 قدیمی‌تر از 2.7 و نسخه‌های Python 3 قدیمی‌تر از 3.5 باید پشتیبانی‌نشده در نظر گرفته شوند. تا جایی که می‌دانیم هیچ کد ناسازگاری اضافه نشده است، اما هیچ زیرساخت CI برای تأیید این موضوع وجود ندارد و در صورت بروز هرگونه مشکل در این نسخه‌ها، برطرف نخواهند شد.
  • در نتیجه، پشتیبانی از Python 2.7 و 3.5 باید منسوخ‌شده در نظر گرفته شود؛ چرا که دورهٔ عمر (end-of-life) نسخهٔ 2.7 پیش‌تر به پایان رسیده است و 3.5 نیز به‌زودی به آن خواهد رسید.
  • یک پیکربندی CI اضافه شده است که به ما امکان می‌دهد آزمایش‌ها را روی نسخه‌های گوناگون Python در تمامی سیستم‌عامل‌های Mac، Linux و Windows اجرا کنیم.

تاریخ: ۱۱ ژانویه ۲۰۱۷ (11 Jan 2017)

  • افزودن کلاس جدید SubnetSplitter برای کاربرانی که قصد تقسیم زیرشبکه‌ها را دارند. با تشکر از alanwill و RyPeck و مشارکت‌کنندگان در (Stack Overflow discussion).
  • حذف کد وابستگی گنجانده‌شدهٔ pytest برای "python setup.py test".
  • اسکریپت setup.py اکنون فقط از setuptools استفاده می‌کند (پایان استفاده از distutils) و setup_egg.py حذف شد.
  • پاک‌سازی و به‌روزرسانی مستندات INSTALL تا بسته‌بندی فعلی Python را به‌درستی منعکس کنند.
  • رفع اشکال تجزیه، تولید و خواندن فایل‌های شاخص IEEE هنگام جابه‌جایی میان Python 2.x و 3.x.

•
تقسیم یک شبکهٔ واحد به چندین شبکه با پیشوند (prefix)
•
اصلاح IPAddress().netmask_bits جهت بازگرداندن مقدار 0 برای آدرس‌های 0.0.0.0 و [::]
•
شکست در اجرای (python setup.py test) با python3 >= 3.5
•
خرابی ارجاع API در ReadTheDocs
•
تازه‌سازی پایگاه‌های دادهٔ همراهِ IANA و IEEE

•
خداحافظی با NYSE Euronext (دوران خوش)، سلام به Intercontinental Exchange ...

تاریخ: ۴ سپتامبر ۲۰۱۵ (4 Sep 2015)

  • الگوریتم cidr_merge() اکنون از مرتبهٔ O(n) بوده و بسیار سریع‌تر شده است. با تشکر از Anand Buddhdev (aabdnn) و Stefan Nordhausen (snordhausen).
  • پشتیبانی کامل از مشخصات هدف nmap شامل پیشوندهای CIDR در IPv4 و آدرس‌های IPv6.
•
nmap.py - اهداف CIDR
•
مشاهده: netaddr تحت pypy کندتر است

تاریخ: ۳۱ اوت ۲۰۱۵

•
رفع یک پس‌رفت در valid_mac به دلیل shadow import در ماژول netaddr.

•
netaddr.valid_mac('00-B0-D0-86-BB-F7')==False برای 0.7.16 اما True برای 0.7.15

تاریخ: ۳۰ اوت ۲۰۱۵

•
شبکه‌های IPv4 با netmaskهای /31 و /32 اکنون مطابق با
RFC 3021 مدیریت می‌شوند. با تشکر از kalombos و braaen.

•
شناسایی رجیستری تخصیص‌های unicast سراسری IPv6
•
بخشی از مستندات نامشخص است؟
•
به‌روزرسانی Eui64 (درخواست ادغام برای Issue 105)
•
پشتیبانی از dialectها برای آدرس‌های EUI-64
•
بسته tarball نسخه 0.7.15 فاقد آزمون‌ها است.
•
میزبان‌ها و برودکست‌های نادرست برای شبکه‌های /31 و /32.

تاریخ: ۲۹ ژوئن ۲۰۱۵

  • رفع کندی در IPSet.__contains__. با تشکر از novas0x2a برای گزارش آن.
  • نرمال‌سازی IPNetworkها هنگام افزوده شدن به یک IPSet
  • تبدیل مجموعه آزمون به py.test

رفع اشکال ۹۸: https://github.com/drkjam/netaddr/issues/98
•
تبدیل مجموعه آزمون به py.test
رفع اشکال ۹۴: https://github.com/drkjam/netaddr/issues/94
•
متد IPSet.__contains__ حدود ۴۰ برابر کندتر از IPRange معادل است
رفع اشکال ۹۵: https://github.com/drkjam/netaddr/issues/95
•
مدیریت ناسازگار آدرس‌ها در IPSet

تاریخ: ۳۱ مارس ۲۰۱۵

  • رفع شکست عجیب فرآیند ساخت در 0.7.13 (مسیر نادرست Python، پایگاه دادهٔ OUI نادرست).
اشیاء EUI، OUI و IAB اکنون با رشته‌ها قابل مقایسه‌اند. می‌توانید دستورهای زیر را اجرا کنید:
my_mac = EUI("11:22:33:44:55:66") my_mac == "11:22:33:44:55:66" و Python روی عملگر "==" مقدار True را بازمی‌گرداند.
•
پیاده‌سازی عملگر "!=" برای OUI و IAB در Python2. این عملگر از قبل
در Python3 کار می‌کرد.
•
شناسه‌های EUI ۶۴ بیتی قبلاً فقط از رشته‌هایی با جداکنندهٔ "-" ایجاد می‌شدند.
اکنون، ":" و بدون جداکننده نیز پشتیبانی می‌شوند، قابلیتی که پیش‌تر برای EUIهای ۴۸ بیتی فعال بود.

رفع اشکال ۸۰: https://github.com/drkjam/netaddr/pull/80
•
مقایسهٔ آدرس‌های L2 با نمایش آن‌ها
رفع اشکال ۸۱: https://github.com/drkjam/netaddr/issues/81
•
شکست آزمون‌های پایگاه دادهٔ OUI در 0.7.13
رفع اشکال ۸۴: https://github.com/drkjam/netaddr/issues/84
•
مسیر نادرست فایل اجرایی python در netaddr-0.7.13-py2.py3-none-any.whl
رفع اشکال ۸۷: https://github.com/drkjam/netaddr/pull/87
•
پشتیبانی از آدرس‌های eui64 با دونقطه (:) به عنوان جداکننده و بدون جداکننده.

تاریخ: 31 دسامبر 2014

•
اشیای IPAddress اکنون می‌توانند با یکدیگر جمع یا از یکدیگر تفریق شوند

رفع Issue 73: https://github.com/drkjam/netaddr/issues/73
•
جمع کردن نشانی‌های IP
رفع Issue 74: https://github.com/drkjam/netaddr/issues/74
•
محاسبه نشانی استاتیک گلوبال IPv6 از روی پیشوند شبکه و نشانی MAC
رفع Issue 75: https://github.com/drkjam/netaddr/issues/75
•
افزودن دسته‌بندی‌ها (classifiers) برای پشتیبانی از python 3.3 و 3.4

تاریخ: 6 ژوئیه 2014

  • متد IPSet.iter_ipranges() افزوده شد.
  • دستور bool(IPSet()) اکنون برای IPSetهای بزرگ کار می‌کند، مانند IPSet(['2405:8100::/32']).
  • متد IPNetwork.iter_hosts اکنون از نشانی anycast مربوط به subnet-router برای IPv6 صرف‌نظر می‌کند.
  • تابع fbsocket.inet_aton حذف شد زیرا بی‌استفاده و غیرضروری است

رفع Issue 69: https://github.com/drkjam/netaddr/issues/69
•
افزودن متد __nonzero__ به IPSet
رفع Pull Request 68: https://github.com/drkjam/netaddr/pull/68
•
رفع باگ مربوط به مجاز دانستن ::0 در حین iter_hosts برای v6
رفع Issue 67: https://github.com/drkjam/netaddr/issues/67
•
حذف تابع fbsocket.inet_aton
رفع Pull Request 66: https://github.com/drkjam/netaddr/pull/66
•
افزودن تابع جهت ایجاد فهرستی از IPRange برای IPSetهای غیرپیوسته

تاریخ: 19 مارس 2014

•
کارایی IPSet به طور چشمگیری افزایش یافت، پیاده‌سازی شده توسط
Stefan Nordhausen و Martijn van Oosterhout. به عنوان یک اثر جانبی، IPSet(IPNetwork("10.0.0.0/8")) اکنون به همان سرعتی است که انتظار دارید.
  • بهبودهای مختلف در کارایی در بخش‌های گوناگون.
  • بسته netaddr اکنون در PyPI میزبانی می‌شود و از طریق pip قابل نصب است.
  • عملیات "10.0.0.42" in IPNetwork("10.0.0.0/24") اکنون کار می‌کند.
  • کلاس IPSet دارای دو متد جدید شده است: iscontiguous() و iprange()، با تشکر از Louis des Landes.
  • افزودن مجدد متد IPAddress.netmask_bits() که تصادفاً حذف شده بود.
شبکه‌های 128.0.0.0/16، 191.255.0.0/16 و 223.255.255.0/24 دیگر به عنوان
نشانی‌های رزروشده IPv4 علامت‌گذاری نمی‌شوند. با تشکر از marnickv برای اشاره به این موضوع.
•
رفع باگ‌های مختلف با مشارکت Wilfred Hughes، 2*yo و Adam Goodman.

رفع مشکل 58: https://github.com/drkjam/netaddr/issues/58

•
foo.bar استثنای AddrFormatError را پرتاب نمی‌کند

رفع مشکل 57: https://github.com/drkjam/netaddr/issues/57

•
بسته‌های netaddr در PyPI میزبانی نشده‌اند

رفع مشکل 56: https://github.com/drkjam/netaddr/issues/56

•
اصلاح مقایسه با IPSet() بزرگ

رفع مشکل 55: https://github.com/drkjam/netaddr/pull/55

•
اصلاح smallest_matching_cidr و all_matching_cidrs

رفع مشکل 53: https://github.com/drkjam/netaddr/issues/53

•
مستثنی کردن 128.0.0.0/16 و احتمالاً موارد دیگر از مجموعه محدوده‌های رزروشده؟

رفع مشکل 51: https://github.com/drkjam/netaddr/issues/51

•
خطاهای کدگذاری در netaddr/eui/oui.txt

رفع مشکل 46: https://github.com/drkjam/netaddr/issues/46

•
شکست len(IPSet()) در python3

رفع مشکل 43: https://github.com/drkjam/netaddr/issues/43

•
متدی برای بررسی پیوسته بودن IPSet

رفع مشکل 38: https://github.com/drkjam/netaddr/issues/38

•
عدم وجود netmask_bits در IPAddress

رفع مشکل 37: https://github.com/drkjam/netaddr/issues/37

•
شکست آزمون‌ها با Python 3.3

تاریخ: ۶ سپتامبر ۲۰۱۲

  • مجموعه‌ای از رفع اشکالات در Python 3.x. با تشکر از Arfrever.
  • گسترش پشتیبانی از nmap برای پوشش کامل مشخصات هدف.

رفع Issue 36 - https://github.com/drkjam/netaddr/issues/36

•
هشدارهای ResourceWarnings در Python >=3.2

رفع Issue 35 - https://github.com/drkjam/netaddr/issues/35

•
netaddr-0.7.9: شکست در آزمون‌ها با Python 3

رفع Issue 34 - https://github.com/drkjam/netaddr/issues/34

•
عدم سازگاری netaddr.ip.iana.SaxRecordParser.endElement() با Python 3.1

رفع Issue 33 - https://github.com/drkjam/netaddr/issues/33

•
اسکریپت netaddr با Python 3 نصب نمی‌شود

رفع Issue 23 - https://github.com/drkjam/netaddr/issues/23

•
تابع valid_nmap_range() حالت‌های قالب nmap را اعتبارسنجی نمی‌کند.

رفع Issue 22 - https://github.com/drkjam/netaddr/issues/22

•
all_matching_cidrs: نادرست بودن مستندات

تاریخ: ۲۸ اوت ۲۰۱۲

•
انتشار مجدد برای اصلاح ساخت با حذف وابستگی به Sphinx.

تاریخ: ۲۸ اوت ۲۰۱۲

  • تجزیه‌کنندهٔ جدید SAX برای فایل‌های منبع دادهٔ IANA (مشارکت از سوی Andrew Stromnov)
  • رفع خطاهای مربوط به pickling در کلاس‌های EUI، OUI و IAB.

رفع Issue 31 - https://github.com/drkjam/netaddr/issues/31

•
مستثنی کردن شبکهٔ '39.0.0.0/8' از مجموعهٔ رزرو شده. با تشکر از Andrew Stromnov

رفع Issue 28 - https://github.com/drkjam/netaddr/issues/28

•
اصلاح الگوریتم در ipv6_link_local برای انطباق کامل با rfc4291. با تشکر از Philipp Wollermann

رفع Issue 25 - https://github.com/drkjam/netaddr/issues/25

•
آیا install_requires بیش از حد سخت‌گیرانه است؟ با تشکر از Adam Lindsay و سایر نظردهندگان.

رفع Issue 21 - https://github.com/drkjam/netaddr/issues/21

•
شکست deepcopy برای EUI. با تشکر از Ryan Nowakowski.

تاریخ: ۳۰ مه ۲۰۱۲

  • به‌روزرسانی جامع مستندات! تنها ۴ سال طول کشید تا بالاخره از Sphinx استفاده شود و می‌توانم تأیید کنم که کاملاً فوق‌العاده است!
  • رفع باگ‌های گوناگون
  • تازه‌سازی داده‌های IEEE OUI و IAB

رفع مشکل 24 - https://github.com/drkjam/netaddr/issues/24

•
رفع TypeError هنگام مقایسه نمونه BaseIP با اشیاء غیر BaseIP. با تشکر از pvaret

رفع مشکل 17 - https://github.com/drkjam/netaddr/issues/17

•
متد .subnet() برای شبکه‌های بزرگ ipv6 با شکست مواجه می‌شد. با تشکر از daveyss

رفع مشکل 20 - https://github.com/drkjam/netaddr/issues/20

•
شکست آزمون در Python 3. با تشکر از Arfrever

تاریخ: ۱۳ سپتامبر ۲۰۱۱

  • یک انتشار نقطه‌ای برای رفع اشکال
  • تازه‌سازی کش‌های داده‌های شخص ثالث (3rd party)
  • آزمایش‌شده در برابر Python 3.2.x و PyPy 1.6.x
  • رفع آزمون‌های واحد تحت Mac OSX

رفع مشکل 15 - https://github.com/drkjam/netaddr/issues/15

•
تولید glob نادرست و نامعتبر هنگامی که اکتت آخر * نباشد

رفع مشکل 13 - https://github.com/drkjam/netaddr/issues/13

•
افزودن پشتیبانی از تغییرات API در IPython 0.11. با تشکر از juliantaylor

رفع مشکل 11 - https://github.com/drkjam/netaddr/issues/11

•
فراخوانی valid_glob روی cidr موجب بروز خطای ValueError می‌شد. با تشکر از radicand

رفع مشکل 7 - https://github.com/drkjam/netaddr/issues/7

•
اشکال Unpickling در IPSet. با تشکر از LuizOz و labeneator

رفع مشکل 2 - https://github.com/drkjam/netaddr/issues/2

•
بروز خطای UnboundLocalError در سازنده IPNetwork. با تشکر از keesbos
•
آیا یک شرکت معروف نوشیدنی، ساخت NICهای اختصاصی خود را آغاز کرده است؟

تاریخ: ۵ اکتبر ۲۰۱۰

  • اکنون Python 3.x به‌طور کامل پشتیبانی می‌شود. رنگ این تغییرات هنوز خشک نشده است (بسیار تازه است)، بنابراین لطفاً در آزمودن آن کمک کنید و هنگام برخورد با هرگونه مشکل تیکت باگ ثبت نمایید! سامانهٔ جدید پیگیری مشکلات - https://github.com/drkjam/netaddr/issues
  • میزبانی کد به github منتقل شد. تاریخچه به لطف svn2git منتقل گردید. - (https://github.com/nirvdrum/svn2git)
  • اکنون تمام اشیای netaddr به دلیل استفاده از __slots__ در کلاس‌های سراسر پایه‌کد، تقریباً ۶۵٪ حافظهٔ کمتری مصرف می‌کنند. با تشکر از Stefan Nordhausen و مرشد پایتون او بابت این پیشنهاد!
  • بهینه‌سازی‌ها و افزایش سرعت‌های بسیاری در سراسر پایه‌کد اعمال شد.
  • رفتار سازندهٔ IPNetwork اصلاح شد، به طوری که اکنون به شیوه‌ای بسیار معقول‌تر و مطابق انتظار رفتار می‌کند (یعنی دیگر از معناشناسی inet_aton که برای آدرس‌های شبکه کاملاً نامأنوس بود، استفاده نمی‌کند).
  • یک تغییر رفتاری جزئی در این نسخه این است که ویژگی .value در اشیای IPAddress و IPNetwork دیگر از انتساب مقدار با استفاده از یک آدرس IP رشته‌ای پشتیبانی نمی‌کند. اکنون تنها انتساب مقادیر عدد صحیح معتبر است. تأثیر این تغییر برای اکثریت کاربران باید در کمترین حد ممکن باشد.

رفع مشکل ۴۹ - http://code.google.com/p/netaddr/issues/detail?id=49

•
تشخیص نادرست محدودهٔ IP در آدرس‌های IP دارای صفر پیشرو

رفع مشکل ۵۰ - http://code.google.com/p/netaddr/issues/detail?id=50

•
تجزیهٔ بلوک CIDR

رفع مشکل ۵۲ - http://code.google.com/p/netaddr/issues/detail?id=52

•
تطابق‌های ipv6 cidr به‌طور نادرست با ipv4 مطابقت داده می‌شوند [sic]

رفع مشکل ۵۳ - http://code.google.com/p/netaddr/issues/detail?id=53

•
خطا در مستندات برخط

رفع مشکل ۵۴ - http://code.google.com/p/netaddr/issues/detail?id=54

•
شکست در شناسایی IP

رفع مشکل ۵۵ - http://code.google.com/p/netaddr/issues/detail?id=55

•
پشتیبانی از Python 3.x

رفع مشکل ۵۶ - http://code.google.com/p/netaddr/issues/detail?id=56

•
بررسی IPAddress در IPNetwork

رفع مشکل ۵۷ - http://code.google.com/p/netaddr/issues/detail?id=57

•
اشیای netaddr قابلیت سریال‌سازی با pickle را ندارند

رفع مشکل ۵۸ - http://code.google.com/p/netaddr/issues/detail?id=58

•
عملیات‌های IPSet باید همان آرگومان‌های IPAddress را بپذیرند

رفع مشکل ۵۹ - http://code.google.com/p/netaddr/issues/detail?id=59

•
شکست در بارگذاری netaddr هنگام درون‌ریزی توسط یک هم‌روند (coprocess) در PowerDNS
  • خوش‌آمدگویی مجدد به standards.ieee.org که به نظر می‌رسید برای هفته‌ها از دسترس خارج شده بود!
  • خداحافظ Sun Microsystems و Merrill Lynch، سلام Oracle و Bank of America ...

تاریخ: ۲ دسامبر ۲۰۰۹

  • اعمال وصله‌های بهبود سرعت توسط S. Nordhausen
  • رفع ناهماهنگی میان رابط‌های EUI و IPAddress. تبدیل EUI.packed و EUI.bin به ویژگی (پیش‌تر متد بودند) و افزودن یک ویژگی words().

تاریخ: ۱۴ سپتامبر ۲۰۰۹

  • افزودن عملگرهای __add__، __radd__، __sub__ و __rsub__ به کلاس IPAddress.
  • افزودن پشتیبانی از اعتبارسنجی و پیمایش محدوده‌های سادهٔ IPv4 به سبک nmap (مطرح‌شده در Issue 46).
  • حذف برخی از ثابت‌های بلااستفاده از ماژول fallback socket.

رفع Issue 44 - http://code.google.com/p/netaddr/issues/detail?id=44

•
خطای نوع int/long

رفع Issue 46 - http://code.google.com/p/netaddr/issues/detail?id=46

•
پرسش در مورد محدوده‌های IPv4

رفع Issue 47 - http://code.google.com/p/netaddr/issues/detail?id=47

•
عدم امکان ارزیابی IPNetwork به عنوان مقدار بولی (boolean) هنگامی که اندازه بزرگی دارد

تاریخ: ۲۰ اوت ۲۰۰۹

رفع مشکل مرزی در تابع مولد iter_iprange()
و تمامی فراخوانی‌های مرتبط با آن در سراسر پایه‌کد، از جمله پوشش آزمون واحد و اصلاحات مربوطه.
  • جایگزینی عبارت‌های باقاعده در cidr_merge() با معادل‌های pre-compiled برای افزایش اندک سرعت.
  • اصلاحات در README مطرح‌شده توسط John Eckersberg.

    رفع شد: Issue 43 - http://code.google.com/p/netaddr/issues/detail?id=43

•
عدم امکان استفاده از IPNetwork('0.0.0.0/0') در حلقه for

تاریخ: ۱۴ اوت ۲۰۰۹

  • تغییر نام اسکریپت شل netaddr از 'nash' به 'netaddr' ساده. این کار برای جلوگیری از تداخل نام بالقوه ناخوشایند با یک ابزار مهم لینوکس با همین نام انجام شد.

    با تشکر از John Eckersberg برای تشخیص زودهنگام این مورد!

  • به‌روزرسانی فایل‌های داده‌های IANA و IEEE با آخرین نسخه‌ها.

رفع شد: Issue 42 - http://code.google.com/p/netaddr/issues/detail?id=42

•
باگ در تابع cidr_merge() هنگام ارسال CIDRهای 0.0.0.0/0 و/یا ::/0

تاریخ: ۱۱ اوت ۲۰۰۹

لطفاً توجه داشته باشید - این انتشار یک بازنگری اساسی در netaddr است. این تغییرات سازگاری عقبرو با نسخه‌های پیشین را می‌شکند. برای جزئیات کامل امکانات در دسترس، به مستندات API مراجعه کنید.

برخی از نکات برجسته تغییرات:-

  • ساختار سلسله‌مراتبی داخلی ماژول‌ها به‌طور کامل بازنگری و بازطراحی شده است. این امر بسیاری از ناسازگاری‌ها و مشکلات مربوط به واردسازی‌های وابسته به یکدیگر را برطرف می‌کند. تمام کلاس‌ها، اشیاء، توابع و ثابت‌های عمومی همچنان مانند نسخه‌های قبلی از طریق فضای نام اصلی ماژول netaddr در دسترس هستند.
  • حذف «ثابت‌های» AT_* و ST_*.
  • کلاس پایه Addr حذف شد. این امر پیوند بین قابلیت‌های EUI و IP را از بین می‌برد، بنابراین کتابخانه اکنون می‌تواند به سادگی به واحدهای متمایزی بدون وابستگی‌های متقابل زیاد میان عملکردهای لایه ۲ و لایه ۳ تقسیم شود.
  • استفاده از کلاس‌های توصیف‌گر سفارشی کاملاً متوقف شده است.
  • کلاس‌های استراتژی و اشیاء سینگلتون با گروهی از ماژول‌های استراتژی در فضای نام اختصاصی خود یعنی netaddr.strategy جایگزین شده‌اند. اکنون هر شیء آدرس IP یا EUI به جای یک شیء سینگلتون، ارجاعی به یک ماژول را نگهداری می‌کند.
  • بسیاری از عملیاتی که پیش‌تر متدهای ایستای کلاس بودند، اکنون به صورت توابع در ماژول‌های مربوطه ارائه می‌شوند. برای جزئیات به مستندات API مراجعه کنید.
  • کلاس‌های IP و CIDR به ترتیب با دو کلاس جدید به نام‌های IPAddress و IPNetwork جایگزین شده‌اند. این تغییر نام مهم است زیرا بخش IP در netaddr به‌طور کامل بازطراحی شده است. مفهوم یک آدرس IP تکی و یک شبکه یا زیرشبکه IP بسیار واضح‌تر شده است. اشیاء IPAddress اکنون مقادیر اسکالر واقعی هستند و در بستر لیست یا تاپل ارزیابی نمی‌شوند. آن‌ها همچنین از مفهوم netmask یا پیشوند CIDR پشتیبانی نمی‌کنند؛ این وظیفه اصلی شیء IPNetwork است.
  • محدوده‌های دلخواه IP همچنان پشتیبانی می‌شوند، اما بسیاری از عملکردهای آن‌ها از طریق توابع کاربردی نیز ارائه شده است.
  • روال‌های انطباق الگوی IP (که قبلاً با نام Wildcards شناخته می‌شدند) به زیرماژول اختصاصی خود منتقل شده‌اند.
  • کلاس جدید IPSet اضافه شده که به‌طور کامل مجموعه‌های تغییرپذیر پایتون را شبیه‌سازی می‌کند. این کلاس جایگزین بسیاری از کلاس‌های آزمایشی و ناقص در نسخه‌های 0.5.x و 0.6.x مانند IPRangeSet و CIDRGroup شده است. برای جزئیات به مستندات مراجعه کنید.
  • تمام متدها و ویژگی‌هایی که قبلاً از مشخصه قالب‌بندی 'fmt' استفاده می‌کردند یا از آن پشتیبانی می‌کردند، دیگر این کار را انجام نمی‌دهند. در تمام موارد، اشیاء اکنون به گونه‌ای بازگردانده می‌شوند که از فراخوانی‌های عبوری بدون عوارض جانبی پشتیبانی کنند. بر عهده کاربر است که در صورت نیاز، داده‌ها را با فرمت مناسب از اشیاء IPAddress بازگردانده‌شده استخراج کند.
  • آزمون‌های واحد برای پشتیبانی از آزمون‌های مبتنی بر docstring که در مجموعه‌های آزمون بسته‌بندی شده‌اند، کاملاً بازنویسی شده‌اند. این آزمون‌ها بسیار کاربردی هستند زیرا در ترکیب با نحو ویکی نقش مستندات را نیز ایفا می‌کنند. بررسی پوشش کد نیز با استفاده از coverage 3.x پیاده‌سازی شده است.
  • ابزار nash - یک ابزار شل نوپا برای کتابخانه netaddr (نیازمند IPython).
  • پشتیبانی از RFC 1924 اضافه شد ;-)

    رفع مسئله 13 - http://code.google.com/p/netaddr/issues/detail?id=13

•
جستجو برای تطابق در فهرستی از اشیاء CIDR

رفع مسئله 26 - http://code.google.com/p/netaddr/issues/detail?id=26

•
بازطراحی و حذف استفاده از isinstance()

رفع مسئله 28 - http://code.google.com/p/netaddr/issues/detail?id=28

•
افزودن پشتیبانی از عملیات بلوک شبکه

رفع مسئله 34 - http://code.google.com/p/netaddr/issues/detail?id=34

•
اشکال در عملیات جمع؟

تاریخ: 11 اوت 2009

رفع مسئله 40 - http://code.google.com/p/netaddr/issues/detail?id=40

•
ساخت RPM با "python setup.py bdist_rpm" با خطاهای متعددی شکست می‌خورد

تاریخ: 23 ژوئن 2009

  • اصلاح پایان خطوط (line endings) در تعدادی از فایل‌های جدید ایجادشده تحت Windows.
  • تنظیم ترتیب مقادیر در چندتایی (tuple) ارسال‌شده به تابع hash() در متد __hash__ کلاس‌های IP و IPRange، جهت یکسان‌سازی آن با مقادیر مورد استفاده در مقایسه‌های متد __eq__ (روش بهینه در Python).
  • افزودن تعدادی آزمون واحد (unit test) برای بهبود پوشش کد (code coverage).

رفع مسئله 33 - http://code.google.com/p/netaddr/issues/detail?id=33

•
تفریق CIDR برای اشیاء CIDR خارج از محدوده با خطا مواجه می‌شود

رفع مسئله 35 - http://code.google.com/p/netaddr/issues/detail?id=35

•
خطای نصب (در مفسرهای Python که در آن‌ها socket.has_ipv6 مقدار False دارد)

رفع مسئله 36 - http://code.google.com/p/netaddr/issues/detail?id=36

•
عدم موفقیت netaddr.CIDR در تجزیه CIDR مسیر پیش‌فرض (default route)

رفع مسئله 37 - http://code.google.com/p/netaddr/issues/detail?id=37

•
اشکال در عملگر بیتی AND برای نشانی‌های IP

رفع مسئله 38 - http://code.google.com/p/netaddr/issues/detail?id=38

•
درخواست ویژگی: Addr.__nonzero__

رفع مسئله 39 - http://code.google.com/p/netaddr/issues/detail?id=39

•
تابع CIDR.abbrev_to_verbose() قواعد ماسک شبکه کلاس‌بندی‌شده (classful netmask) ضمنی را به‌صورت یکپارچه اعمال نمی‌کند

تاریخ: ۱۳ آوریل ۲۰۰۹

•
تازه‌سازی فایل‌های داده‌ی IEEE و IANA با آخرین بازبینی‌ها از نشانی‌های اینترنتی مربوطه.
  • ثبت فضای آدرس IPv4 در IANA (آخرین به‌روزرسانی 2009-03-11)
  • آدرس‌های چندپخشی اینترنت (Internet Multicast Addresses) (آخرین به‌روزرسانی 2009-03-17)
  • فایل‌های OUI و IAB مربوط به IEEE (آخرین به‌روزرسانی 2009-04-13)
•
افزودن توابع get_latest_files() به هر دو ماژول netaddr.eui و netaddr.ip جهت کمک به خودکارسازی ساخت انتشارها.

رفع مشکل Issue 32 - http://code.google.com/p/netaddr/issues/detail?id=32

•
متد Addr.__ne__ پاسخ نادرست برمی‌گرداند

تاریخ: ۶ آوریل ۲۰۰۹

  • افزودن فایل COPYRIGHT به همراه جزئیات و انتساب مالکیت برای تمام فایل‌های شخص ثالث همراه با netaddr.
  • حداقل نسخه مورد نیاز Python اکنون از 2.3.x به 2.4.x تغییر یافته است.
  • کدهای سازگاری با Python 2.3 در بسیاری از بخش‌های کد حذف شده‌اند.
  • دکوراتورهای @property و @staticmethod اکنون در سرتاسر کد به همراه تکرارکننده‌های داخلی reversed() و sorted() استفاده می‌شوند.
  • بررسی مشخصی برای نسخه افزوده شده است که در صورت اجرای netaddr روی مفسر Python با نسخه < 2.4.x استثنای RuntimeError ایجاد می‌کند.
  • آدرس‌های عدد صحیح فرستاده‌شده به سازنده‌های IP() و EUI() در بیشتر موارد دیگر نیازی به آرگومان اجباری نوع دوم آدرس (AT_*) ندارند. این مورد اکنون تنها برای ابهام‌زدایی میان آدرس‌های IPv4/IPv6 با مقدار عددی یکسان ضروری است. همین رفتار برای شناسه‌های EUI-48/EUI-64 نیز صدق می‌کند. در صورت ارائه صریح آرگومان نوع دوم آدرس، بهبود اندکی در سرعت حاصل می‌شود.
  • آدرس‌های IPv6 بازگردانده‌شده توسط EUI.ipv6_link_local() اکنون همیشه دارای پیشوند زیرشبکه /64 هستند.
  • ترتیب مرتب‌سازی پیش‌فرض کلاس‌های تجمیعی (IPRange، CIDR و Wildcard) (مجدداً) تغییر کرد. آن‌ها اکنون ابتدا بر اساس اولین آدرس و سپس بر اساس اندازه بلوک شبکه از بزرگ‌ترین به کوچک‌ترین مرتب می‌شوند که طبیعی‌تر به نظر می‌رسد.
  • رفع یک باگ در متد ایستان CIDR.abbrev_to_verbose() که در آن به آدرس‌های IPv4 با ۴ بایت (یعنی آدرس‌های غیرجزئی) با استفاده از قوانین مختصر، پیشوند زیرشبکه اختصاص داده می‌شد. همه آدرس‌های کامل IPv4 در صورت عدم ارائه صریح، باید همواره پیشوند /32 دریافت کنند.
  • گسترش آدرس‌های مختصر در سازنده CIDR اکنون اختیاری است و می‌تواند توسط آرگومان بولی جدید 'expand_abbrev' کنترل شود.
  • افزودن متد ایستان جدید CIDR.summarize() که فهرست‌هایی از آدرس‌های IP و CIDRها را به فشرده‌ترین شکل ممکن تبدیل می‌کند. برای کوچک‌سازی فهرست‌های بزرگ و موردی آدرس‌ها عالی است!
  • افزودن متدهای previous() و next() به کلاس‌های CIDR که زیرشبکه‌های CIDR هم‌اندازه را در هر دو طرف یک CIDR مشخص بازمی‌گردانند. برای CIDR با مقدار 192.0.2.0/24، متد previous مقدار 192.0.1.0/24 و متد next مقدار 192.0.3.0/24 را بازمی‌گرداند. همچنین یک اندازه گام اختیاری را می‌پذیرد (پیش‌فرض 1 است).
  • افزودن متد supernet() به کلاس CIDR که مولدی از تمام زیرشبکه‌های دربرگیرنده CIDR فعلی را برمی‌گرداند که با کاهش مقدار prefixlen در هر مرحله تا رسیدن به صفر به دست می‌آیند.
  • تغییر نحوه عملکرد کد جایگزین (fallback) هنگامی که ماژول socket فاقد توابع و ثابت‌های مهم است.
  • حذف گزینه‌های حروف بزرگ (uppercase) از سازنده‌ها و بخش‌های درونی Strategy، زیرا این رفتار به‌راحتی با استفاده از گزینه word_fmt قابل بازتولید است و به کد کمتری نیاز دارد (word_fmt='%X').

    FIXED Issue 23 - http://code.google.com/p/netaddr/issues/detail?id=23

•
بهبود قالب‌بندی نشانی‌های IPv6 نگاشت‌شده/سازگار با IPv4

FIXED Issue 24 - http://code.google.com/p/netaddr/issues/detail?id=24

•
باگ در CIDR.subnet() هنگام استفاده از آرگومان fmt

FIXED Issue 29 - http://code.google.com/p/netaddr/issues/detail?id=29

•
آرگومان count متد CIDR.subnet طبق مستندات کار نمی‌کند

FIXED Issue 30 - http://code.google.com/p/netaddr/issues/detail?id=30

•
عدم سازگاری با Python 2.3

FIXED Issue 31 - http://code.google.com/p/netaddr/issues/detail?id=31

•
ترتیب بایت‌ها در مستندات گیج‌کننده یا نادرست بود

تاریخ: ۲۰ ژانویه ۲۰۰۹

•
تغییرات فضای نام (Namespace)

۳ زیرفضای نام جدید اضافه شده است:-

•
netaddr.eui

در حال حاضر شامل کلاس‌های IEEE OUI و IAB و کدهای جستجو (lookup) است.

•
netaddr.ip

در حال حاضر شامل کدهای جستجوی IPv4، IPv6 و چندپخشی (multicast) IPv4 متعلق به IANA است.

•
netaddr.core

در حال حاضر تنها شامل چند کلاس است که بین کدهای netaddr.eui و netaddr.ip به اشتراک گذاشته شده‌اند.

لطفاً توجه داشته باشید: این تغییر بخشی از یک بازسازی درونی دومرحله‌ای در netaddr است. در انتشار‌های آینده، قابلیت‌های لایه ۲ MAC/EUI از قابلیت‌های لایه ۳ IP، CIDR و Wildcard تفکیک خواهند شد. تمام کدهای مشترک به netaddr.core منتقل خواهند شد. پس از تکمیل این مهاجرت (که انتظار می‌رود در نسخه 0.7 انجام شود)، فضاهای نام netaddr.address و netaddr.strategy حذف خواهند شد. لطفاً تلاش کنید از این انتشار به بعد به تمام موارد مورد نیاز خود از طریق فضای نام سطح بالای netaddr دسترسی پیدا کنید. برای اطلاع از جزئیات مربوط به ثابت‌ها، اشیاء، کلاس‌ها و توابع در نظر گرفته‌شده برای رابط عمومی، netaddr.__all__ را بررسی کنید.

•
افزودن جستجوهای اطلاعاتی IEEE و IANA
  • کلاس‌های IP() و EUI() اکنون دارای یک متد info() اضافی هستند که از طریق آن می‌توان به اطلاعات زمینه‌ای درباره نشانی‌های خود دسترسی پیدا کرد. این داده‌ها به ترتیب توسط IANA و IEEE منتشر شده و مستقیماً از فایل‌های متنی گنجانده‌شده در netaddr (که به‌صورت عمومی برای دانلود آنلاین موجودند) خوانده می‌شوند. جزئیات بیشتر در docstring کلاس‌های تجزیه‌کننده مربوطه موجود است. در انتشار‌های بعدی netaddr تلاش خواهد شد تا همگام با هرگونه به‌روزرسانی در این فایل‌ها پیش برود.
  • کلاس EUI() با افزودن کلاس‌های OUI() و IAB() به‌روزرسانی شده است. آن‌ها دسترسی مبتنی بر شیء به داده‌های بازگردانده‌شده از طریق متد EUI.info() را فراهم می‌کنند. لطفاً برای جزئیات به مستندات API موجود در netaddr مراجعه کنید.
  • افزودن استثنای جدید NotRegisteredError که در صورت عدم تطابق یک EUI با هر یک از ورودی‌های ثبتی فعلی در فایل‌های رجیستری IEEE برانگیخته می‌شود.
•
حذف کلاس Addr() از رابط عمومی
•
این کلاس تنها برای استفاده داخلی در نظر گرفته شده بود و ممکن است استفاده از آن در آینده به نفع تبدیل شدن به یک کلاس پایه انتزاعی در انتشار‌های بعدی منسوخ شود.
•
حذف کلاس AddrRange()
•
با کلاس اختصاصی‌تر IPRange() جایگزین شد. AddrRange() در عمل چندان کاربردی نبود و زمان زیادی صرف توضیح مزایای نظری آن در برابر کارایی واقعی‌اش در استفاده‌های روزمره می‌شد.
•
افزودن کلاس جدید IPRange()
  • کلاس پایه جدید برای CIDR() و Wildcard().
  • یک «قابلیت فوق‌العاده» در این کلاس جدید، متدهای جدید iprange()، cidrs() و wildcard() هستند که امکان جابه‌جایی و استفاده آسان میان هر ۳ قالب را فراهم می‌کنند. IPRange('x', 'y').cidrs() به‌ویژه برای بازگرداندن تمامی CIDRهای میانی بین ۲ نشانی IP دلخواه بسیار سودمند است.
  • کلاس IPRange() بستر مناسبی برای ارائه چند متد جدید در دسترسِ زیرکلاس‌ها است؛ شامل متدهای issupernet()، issubnet()، adjacent() و overlaps().
  • متد قبلی با نام data_flavour() (مجدداً) به نام مناسب‌تر format() تغییر نام یافته است.
•
به‌روزرسانی‌های کلاس IP()
  • متدهای is_netmask() و is_hostmask() بهینه‌سازی شده‌اند و اکنون هر دو حدود ۴ برابر سریع‌تر از قبل عمل می‌کنند!
  • افزودن متدهای wildcard() و iprange() که اشیاء از پیش مقداردهی‌شده از آن کلاس‌ها را بر پایه netmask / پیشوند زیرشبکه فعلی بازمی‌گردانند.
  • متدهای کپی سازنده (copy constructor) شامل ipv4() و ipv6() اکنون مقدار ویژگی prefixlen را حفظ می‌کنند و همچنین از گزینه‌های IPv6 برای بازگرداندن نشانی‌های IPv6 نگاشت‌شده به IPv4 یا سازگار با IPv4 پشتیبانی می‌کنند.
  • افزودن متدهای جدید is_loopback()، is_private()، is_link_local()، is_ipv4_mapped() و is_ipv4_compat() که همگی عملکردی واضح و مشخص دارند.
  • افزودن یک متد bin() که یک نشانی IP را در همان قالب نوع توکار bin() در استاندارد پایتون ('0bxxx') ارائه می‌دهد که اکنون در Python 2.6.x و بالاتر در دسترس است.
  • افزودن یک متد packed() که یک نشانی IP را در قالب رشته باینری بسته‌بندی‌شده، مناسب برای ارسال مستقیم به فراخوانی‌های سوکت پایتون، فراهم می‌کند.
•
به‌روزرسانی‌های تابع مولد nrange()
•
این تابع اکنون به‌طور پیش‌فرض به جای اشیاء Addr()، اشیاء IP() را بازمی‌گرداند.
•
به‌روزرسانی‌های کلاس CIDR()
  • گزینه 'strict_bitmask' در سازنده کلاس CIDR تغییر نام داده و اکنون تنها 'strict' است (نیاز کمتر به تایپ).
  • پشتیبانی از پیشوندهای سبک Cisco ACL (ماسک میزبان یا hostmask). این قابلیت برای کلاس IP() نیز فراهم شده است. آن‌ها پیش از اعمال روی نشانی پایه، به معادل‌های netmask خود تبدیل می‌شوند.
یک متد مولد (generator) جدید subnet() اضافه شد که تکرارکننده‌هایی به CIDRهای زیرشبکه موجود در مرزهای شیء CIDR فعلی بازمی‌گرداند؛ برای نمونه یک CIDR با /24 می‌تواند نشانی‌هایی با پیشوندهای زیرشبکه بین /25 و /32 ارائه دهد.
  • یک متد جدید span() اضافه شد که فهرستی از IP، IPRange، CIDR و/یا Wildcardها را دریافت کرده و یک CIDR واحد بازمی‌گرداند که کمترین و بیشترین نشانی‌های مرزی را پوشش می‌دهد ('spans'). ویژگی مهم این کلاس آن است که تنها یک CIDR واحد بازگردانده می‌شود و این‌که (احتمالاً) با نشانی‌های آغاز و پایان هم‌پوشانی دارد. مهم‌ترین جنبه‌ی این متد آن است که چپ‌ترین مجموعه‌ی بیت‌های مشترک در میان تمام نشانی‌های ارائه‌شده را شناسایی می‌کند. این همان ساختار زیربنایی است که باعث کارکرد درست بسیاری از قابلیت‌های دیگر می‌شود.
  • اگرچه IPv6 از مفهوم نشانی پخش همگانی (broadcast address) پشتیبانی نمی‌کند، پس از کمی تأمل تصمیم گرفتم متدهای network() و broadcast() را به کلاس CIDR اضافه کنم. این یک رفتار خاص در رابط است که کاربران انتظار آن را دارند، بنابراین جهت سهولت در استفاده افزوده شده است.
  • متدهای network()، broadcast()، hostmask() و netmask() در فراخوانی‌های توکار property() کپسوله‌سازی شده‌اند تا به صورت ویژگی‌های فقط‌خواندنی (read-only) نمایش داده شوند.
•
اکنون نمایش‌های رشته‌ای بسیار بیشتری از نشانی‌های MAC و IPv4 پشتیبانی می‌شوند
•
بهبودهایی در هر دو کلاس EUI و IP ایجاد شده است. آن‌ها اکنون قالب‌های نشانی معتبر بسیار بیشتری را نسبت به گذشته می‌پذیرند. با تشکر از تمامی گزارش‌های باگ ارسال‌شده.
•
تغییر رفتار متد __repr__()
•
در استفاده از repr() اکنون فرض می‌شود که پیش از اجرای آن‌ها، دستور from netaddr import * را اجرا کرده‌اید. آن‌ها دیگر فضای نام مبدأ اشیاء را مشخص نمی‌کنند، چرا که تا حدی غیرضروری بود و به خواندن متن زیادی روی صفحه می‌انجامید. به هر حال، آن‌ها به‌زودی درون فضای نام جابه‌جا خواهند شد، بنابراین بهتر است فرض نشود که در جایی غیر از زیرمجموعهٔ مستقیم خود netaddr قرار دارند.
•
تغییر نام ویژگی 'klass' به 'fmt' (format)
•
اکنون به عنوان ویژگی 'format callable' شناخته می‌شود؛ تغییری ناخوشایند اما ضروری. 'klass' در ابتدا انتخاب نام نامناسبی بود، زیرا اغلب حتی به یک شیء کلاس اشاره نمی‌کرد و در عین حال از ارجاع به انواع Python، توابع توکار و موارد فراخوانی‌شدنی (callables) تعریف‌شده توسط کاربر نیز پشتیبانی می‌کرد.
•
بازنویسی کامل و یکپارچه‌سازی آزمون‌های واحد (unit tests).
  • اکنون بیش از ۱۰۰ آزمون، تمام جنبه‌های عملکردی API و کتابخانه را پوشش می‌دهند.
  • انتقال تمام آزمون‌ها به یک فایل واحد. آزمون‌های اضافی متعددی به همراه بررسی‌های رابط افزوده شده‌اند تا اطمینان حاصل شود که netaddr در تمامی انتشارها همواره مجموعه‌ای قابل پیش‌بینی از ویژگی‌ها و متدها را ارائه می‌دهد.
•
پشتیبانی نوپا از eggهای Python و setuptools.
•
برای آزمایش این مورد به کمک نیاز است، زیرا شخصاً از آن استفاده نمی‌کنم.

•
سرانجام الگوریتم فشرده‌سازی نشانی رشته‌ای IPv6 اصلاح شد تا اکنون با فراخوانی‌های inet_ntop() و inet_pton() ماژول socket سازگار باشد (روی تمام پلتفرم‌ها در دسترس نیست).

•
افزودن عملگرهای بیتی (bitwise) به کلاس IP
•
دقیقاً همان کاری را می‌کند که از نامش برمی‌آید. تأثیری بر مقدار خود شیء IP نمی‌گذارد، بلکه پس از اعمال عملیات، یک IP جدید را بازمی‌گرداند.
•
کلاس IPRangeSet() اضافه شد (آزمایشی).
  • هدف از این کلاس این است که به شما امکان دهد مجموعه‌هایی از اشیاء منحصربه‌فرد IP()، IPRange()، CIDR() و Wildcard() ایجاد کنید. این کلاس امکان پیمایش روی IPهای درون مجموعه و همچنین چندین عملیات مبتنی بر عضویت نظیر any_match()، all_matches()، min_match() و max_match() را فراهم می‌آورد.
  • کارهای بسیار بیشتری در اینجا برای انجام باقی مانده است. لطفاً در صورت مشاهده، باگ‌ها و درخواست‌های قابلیت‌های جدید را برای آن گزارش کنید. بهبودهایی برای این بخش در نسخه 0.7 ارائه خواهد شد.

تاریخ: ۲۹ سپتامبر ۲۰۰۸

  • رفع مسئلهٔ شماره ۱۵ در سامانهٔ رهگیری باگ. اعتبارسنجی و تبدیل نادرست مقادیر آدرس‌های IPv6 نگاشت‌شده به IPv4 در کلاس IPv6Strategy. با آزمون‌های واحد (unit test) پوشش داده شد.
  • کلاس PrefixLenDescriptor() به‌روزرسانی شد تا تغییرات مشخصهٔ CIDR.prefixlen، مقادیر CIDR.first و CIDR.last را نیز به‌روزرسانی کرده و آن‌ها را همگام نگه دارد. با آزمون‌های واحد پوشش داده شد.
  • متد IP.hostname() هنگام شکست در جستجوی DNS مقدار None را بازمی‌گرداند.

تاریخ: ۲۳ سپتامبر ۲۰۰۸

  • سازندهٔ کلاس CIDR برای آدرس‌های معتبر رشته‌ای یونیکد که در نسخه‌های قبلی کار می‌کردند، خطای TypeError برمی‌انگیخت. رفع شد و با یک آزمون واحد پوشش داده شد.
  • متدهای CIDR.netmask() و CIDR.hostmask() حاوی خطاهای کدی بودند که باعث شکست آن‌ها می‌شد. مشکل برطرف و با آزمون واحد پوشش داده شد.

تاریخ: ۱۹ سپتامبر ۲۰۰۸

عمومی

  • دسترسی به تمامی مشخصه‌های مهم اشیاء در تمامی کلاس‌های netaddr اکنون از طریق کلاس‌های سفارشی پروتکل توصیف‌گر (descriptor) پایتون صورت می‌گیرد. این امر منطق درونی کلاس را بسیار ساده کرده و تغییر مشخصه‌های بیرونی را بسیار ایمن‌تر و کم‌خطاتر ساخته است. همچنین کلاس‌های تجمیعی مانند CIDR و Wildcard را که تا پیش از این انتشار فقط‌خواندنی بودند، عملاً به خواندنی-نوشتنی تبدیل کرده است.
  • نحوهٔ محاسبهٔ ترتیب مرتب‌سازی برای نمونه‌های (زیر)کلاس Addr و AddrRange اصلاح شد تا علاوه بر مقدار عددی آدرس یا محدودهٔ آدرس، نوع آدرس نیز لحاظ شود. ترتیب مرتب‌سازی صعودی به صورت IPv4، IPv6، EUI-48 و EUI-64 است. اکنون توالی‌های نمونه‌های (زیر)کلاس AddrRange به درستی مرتب می‌شوند!
  • مقایسهٔ میان نمونه‌های (زیر)کلاس‌های Addr و AddrRange اکنون به جای برانگیختن AttributeError، مقدار False را بازمی‌گرداند.
  • بررسی‌ها و کدهای دورزدن مشکل (workaround) برای محیط‌های زمان اجرای پایتونی که از باگ بدنام inet_aton('255.255.255.255') در ماژول socket رنج می‌بردند اضافه شد. این مشکل اخیراً در Python 2.4.x روی معماری PowerPC در سیستم‌عامل MacOS X شناسایی شد. این راه‌حل در مواردی که ماژول socket در دسترس نیست (برای نمونه در Google App Engine) نیز اعمال می‌شود.
  • تمام موارد برانگیختن عمومی Exception در ماژول strategy با استثناهای مشخص‌تر، عمدتاً ValueError جایگزین شد (این موارد ناخواسته از انتشار 0.4 جا مانده بودند).
  • عملیات‌های __hash__() برای کلاس‌های Addr و AddrStrategy پیاده‌سازی شدند. این امکان را فراهم می‌کند تا از اشیاء IP، CIDR و Wildcard به عنوان کلید در دیکشنری‌ها و به عنوان عنصر در مجموعه‌ها (sets) استفاده کنید. لطفاً توجه داشته باشید - این ویژگی در حال حاضر آزمایشی است و ممکن است در انتشار‌های بعدی تغییر کند.
  • عملیات __ne__() به کلاس‌های Addr و AddrRange اضافه شد.
  • با پیروی از «قانون دیمیتر» ('Law of Demeter')، به نوع آدرس نمونه‌های (زیر)کلاس Addr و AddrRange می‌توان مستقیماً با استفاده از مشخصه دسترسی داشت:-
obj.addr_type # 0.5 onwards

به جای اینکه نیاز باشد از طریق شیء strategy عمل کرد:-

obj.strategy.addr_type # 0.4 and earlier
•
نام دیکشنری جستجوی AT_DESCR به AT_NAMES تغییر یافت. واردسازی‌های (imports) نامعتبر و تکراری از تمام ماژول‌ها حذف شدند.

تغییرات کلاس Addr

•
متد setvalue() از کلاس Addr حذف شد و تمام موارد استفاده از __setattr__() با توصیف‌گرهای سفارشی در سراسر کد جایگزین شد.

تغییرات کلاس IP

  • ابهام موجود در مشخصه‌های masklen و prefixlen در کلاس IP برطرف شد. اکنون prefixlen نشان‌دهندهٔ تعداد بیت‌هایی است که netmask را برای یک آدرس IP مشخص می‌کنند. متد جدید netmask_bits() در صورتی که متد is_netmask() مقدار True را بازگرداند، تعداد بیت‌های غیرصفر را در یک شیء IP برمی‌گرداند. مقدار prefixlen غیر از /32 برای آدرسی که is_netmask() برای آن مقدار True برمی‌گرداند نامعتبر است و استثنای ValueError برمی‌انگیزد.
  • متد family() از کلاس IP حذف شد؛ زیرا اطلاعاتی را تکرار می‌کرد که اکنون توسط مشخصهٔ prefixlen ارائه می‌شود.
  • کلاس IP دارای چندین متد جدید است. متدهای is_multicast() و is_unicast() به سرعت دستهٔ آدرس IP را مشخص می‌کنند و متدهای ipv4() و ipv6() بسته به زمینه، به عنوان تبدیل‌های IPv4 <-> IPv6 یا سازنده‌های رونوشت (copy constructors) عمل می‌کنند.
  • ورودی‌های جستجوی معکوس DNS اکنون یک نویسهٔ نقطه (.) پایانی در سطح بالا دارند که به آن‌ها افزوده شده است.
  • متد hostname() به نمونه‌های IP اضافه شد که یک جستجوی معکوس DNS انجام می‌دهد.
  • متد __str__() در کلاس IP اکنون پیشوند زیرشبکه را حذف می‌کند؛ این پیشوند برای آدرس‌های IPv4 با مقدار /32 و آدرس‌های IPv6 با مقدار /128 ضمنی است. پیشوند زیرشبکه در مقدار بازگشتی برای تمامی مقادیر دیگر حفظ می‌شود.

تغییرات کلاس AddrRange

  • کلاس AddrRange دیگر نمونه‌های (زیر)کلاس‌های Addr را برای آدرس‌های اول و آخر محدوده ذخیره نمی‌کند. متغیرهای نمونهٔ self.start_addr و self.stop_addr به self.first و self.last تغییر نام یافته و متدهای obj.first() و obj.last() حذف شده‌اند.

    در عوض، self.first و self.last حاوی مقادیر عدد صحیح هستند و ارجاعی به یک شیء strategy ذخیره می‌شود. انجام این کار برای پیاده‌سازی منطق درونی بسیار کاربردی‌تر و تمیزتر است.

    برای دریافت اشیاء (زیر)کلاس Addr (یا رشته‌ها، هگزادسیمال و غیره هنگام کار با مشخصهٔ klass)، از مقادیر اندیس obj[0] و obj[-1] به ترتیب به عنوان جایگزینی برای obj.first() و obj.last() استفاده کنید.

  • نمونه‌های (زیر)کلاس AddrRange اکنون عملگرهای افزایش، __iadd__()، و کاهش، __isub__()، را تعریف می‌کنند. این قابلیت به شما امکان می‌دهد CIDRها و Wildcardها را بر اساس اندازهٔ بلوک آن‌ها به بالا و پایین بلغزانید ('slide').
  • متد _retval() اکنون به data_flavour() تغییر نام یافته است - بله، با املای بریتانیایی ;-) لازم نیست خیلی نگران این موضوع باشید زیرا بیشتر برای استفادهٔ درونی است. نام مناسبی به آن دادم چرا که نیازی واقعی برای پنهان کردن این قابلیت، در صورتی که کاربران خواهان آن باشند، ندیدم.

تغییرات کلاس CIDR

  • سخت‌گیری سازندهٔ کلاس CIDR در رابطه با بیت‌های غیرصفر پس از اعمال ماسک بیتی پیشوند را می‌توان با استفاده از آرگومان اختیاری strict_bitmask=False غیرفعال کرد. این مقدار به صورت پیش‌فرض True (سخت‌گیری فعال) است.
  • رفع یک باگ در تبدیل خلاصه‌شدهٔ CIDR. پیشوند زیرشبکه برای آدرس چندپخشی 224.0.0.0 اکنون به جای /8 برابر با /4 است.
  • کلاس CIDR اکنون از تفریق میان دو شیء CIDR پشتیبانی می‌کند و فهرستی از باقی‌مانده را برمی‌گرداند. لطفاً توجه داشته باشید که شیء CIDR بزرگ‌تر باید در سمت چپ عبارت باشد، در غیر این صورت یک فهرست خالی بازگردانده می‌شود. متأسفیم، شما مجاز به ایجاد CIDRهای منفی نیستید ;-)
  • تابع abbrev_to_cidr() تغییر نام یافته و به متد ایستای CIDR.abbrev_to_verbose() تبدیل شده است. تغییر عمده‌ای در منطق آن ایجاد نشده است.

تغییرات کلاس Wildcard

•
کلاس Wildcard اکنون متد ایستای Wildcard.is_valid() را تعریف می‌کند که به شما امکان می‌دهد بدون نمونه‌سازی کامل یک شیء Wildcard، آزمون‌های اعتبارسنجی را روی رشته‌های wildcard انجام دهید.

تاریخ: ۷ اوت ۲۰۰۸

  • تمام برانگیختن‌های عمومی Exception با استثناهای مشخص‌تر مانند TypeError و ValueError و با افزودن دو کلاس استثنای سفارشی، یعنی AddrFormatError و AddrConversionError جایگزین شده‌اند.
  • کلاس IP اکنون پیشوند زیرشبکه (subnet prefix) را می‌پذیرد. برخلاف کلاس CIDR (پایین را ببینید)، این کلاس در مورد بیت‌های غیرصفر در سمت راست ماسک زیرشبکه ضمنی سخت‌گیر نیست.
  • کلاس CIDR اکنون در مورد بیت‌های غیرصفر در سمت راست نت‌ماسک زیرشبکه ضمنی کاملاً سخت‌گیر است و در صورت وجود آن‌ها، با ارائه یک راهنمایی کاربردی درباره CIDR صحیحی که بر اساس پیشوند زیرشبکه ارائه‌شده باید استفاده شود، یک ValueError برمی‌انگیزد.
  • کلاس CIDR اکنون از محدوده‌های اختصاری CIDR نیز پشتیبانی می‌کند و در صورتی که پیشوند زیرشبکه به‌صراحت مشخص نشده باشد، از قوانین قدیمی‌تر نشانی شبکه باکلاس (classful) برای تعیین آن استفاده می‌کند. شکل‌های پشتیبانی‌شده اکنون شامل 10، 10/8 و 192.168/16 هستند. در حال حاضر این گزینه‌ها فقط برای محدوده‌های نشانی CIDR در IPv4 پشتیبانی می‌شوند.
  • متدهای __repr__() برای همه کلاس‌ها در ماژول netaddr تعریف شده‌اند که دستورهای پایتون قابل اجرایی تولید می‌کنند که می‌توان از آن‌ها برای بازسازی وضعیت هر شیء استفاده کرد.
  • کلاس‌های CIDR و Wildcard اکنون دارای متدهایی هستند که از تبدیل بین این دو نوع تجمیعی پشتیبانی می‌کنند:-
  • CIDR -> Wildcard
  • Wildcard -> CIDR

  • بازبینی و مرتب‌سازی گسترده docstring با گنجاندن نحو اختصاصی epydoc برای بهبود مستندات خودکار تولیدشده API.
  • بازبینی دقیق کد با استفاده از pylint.
  • ماژول netaddr اکنون متغیر ویژه __version__ را تعریف کرده است که توسط setup.py نیز ارجاع داده می‌شود.
  • برخی تغییرات جزئی در setup.py و MANIFEST.in.
  • ثابت‌ها و کلاس‌های سفارشی Exception از strategy.py به __init__.py منتقل شدند.
  • یک __all__ سازگار با * import برای فضای نام netaddr تعریف شده است که نیاز به کاوش بیش از حد در زیرماژول‌های address و strategy را برطرف می‌سازد.
  • رفع چندین مشکل پایان خط (line-ending) در چند فایل.

در اینجا اعلان‌های حق نشر قابل اعمال بر کتابخانه netaddr آورده شده است.

حق نشر (c) 2008 David P. D. Moss بخش‌هایی حق نشر (c) 2020 مشارکت‌کنندگان netaddr

تحت مجوز BSD منتشر شده است. برای جزئیات به فایل LICENSE مراجعه کنید.

پروژه netaddr توسط IANA پشتیبانی مالی یا تأیید نشده است.

استفاده از داده‌های IANA (مرجع واگذاری اعداد اینترنتی) مشمول حق نشر بوده و با اجازه کتبی قبلی ارائه شده است.

فایل‌های داده IANA که همراه netaddr گنجانده شده‌اند، به هیچ وجه تغییر نیافته‌اند، بلکه تجزیه شده و از طریق یک API در دسترس کاربران نهایی قرار گرفته‌اند.

برای نشانی‌های اینترنتی مربوط به آخرین نسخه‌های فایل‌های مربوطه، فایل README و کد منبع را ببینید..SS "IEEE (مؤسسه مهندسان برق و الکترونیک)"

netaddr توسط IEEE حمایت مالی یا تأیید نشده است.

استفاده از داده‌های IEEE (مؤسسه مهندسان برق و الکترونیک) مشمول حق نشر (کپی‌رایت) است. برای جزئیات به نشانی اینترنتی زیر مراجعه کنید:

http://www.ieee.org/web/publications/rights/legal.html

فایل‌های دادهٔ IEEE گنجانده‌شده در netaddr به هیچ وجه دستکاری نشده‌اند، بلکه تجزیه شده و از طریق یک API در دسترس کاربران نهایی قرار گرفته‌اند. هیچ تضمینی وجود ندارد که فایل‌های ارجاع‌شده منسوخ نشده باشند.

برای نشانی‌های اینترنتی آخرین نسخه‌های فایل‌های مربوطه، فایل README و کد منبع را ببینید.

در اینجا مجوزهای مربوط به استفاده از کتابخانهٔ netaddr آورده شده است.

حق نشر و مجوز (COPYRIGHT AND LICENSE)

Copyright (c) 2008 David P. D. Moss Portions Copyright (c) 2020 netaddr contributors

توزیع مجدد و استفاده در قالب‌های سورس و باینری، با یا بدون تغییر، مجاز است به شرطی که شرایط زیر برآورده شوند:

  • توزیع‌های مجدد کد منبع باید اعلان حق نشر بالا، این فهرست شرایط و سلب مسئولیت زیر را در خود حفظ کنند.
  • توزیع‌های مجدد در قالب باینری باید اعلان حق نشر بالا، این فهرست شرایط و سلب مسئولیت زیر را در مستندات و/یا سایر موارد ارائه‌شده همراه با توزیع بازتولید نمایند.
  • نه نام David P. D. Moss و نه نام‌های مشارکت‌کنندگان نمی‌توانند برای تأیید یا تبلیغ محصولات مشتق‌شده از این نرم‌افزار بدون اجازهٔ کتبی و مشخص قبلی استفاده شوند.

این نرم‌افزار توسط دارندگان حق نشر و مشارکت‌کنندگان به‌صورت «همان‌گونه که هست» ("AS IS") ارائه می‌شود و هرگونه ضمانت صریح یا ضمنی، از جمله، اما نه محدود به، ضمانت‌های ضمنی قابلیت خرید و فروش و تناسب برای یک هدف خاص، سلب می‌شود. تحت هیچ شرایطی، دارندهٔ حق نشر یا مشارکت‌کنندگان در قبال هرگونه خسارت مستقیم، غیرمستقیم، اتفاقی، خاص، نمونه‌ای، یا تبعی (از جمله، اما نه محدود به، تهیهٔ کالاها یا خدمات جایگزین؛ از دست دادن استفاده، داده‌ها یا سود؛ یا وقفه در کسب‌وکار) به هر نحوی که ایجاد شده باشد و بر پایهٔ هر تئوری مسئولیت، خواه قراردادی، مسئولیت مطلق یا شبه‌جرم (از جمله سهل‌انگاری یا موارد دیگر) که به هر نحوی از استفاده از این نرم‌افزار ناشی شود، مسئولیتی نخواهند داشت، حتی در صورتی که احتمال وقوع چنین خسارتی تذکر داده شده باشد.

  • David P. D. Moss (نویسنده، نگه‌دارنده) <drkjam@gmail.com>
  • Stefan Nordhausen (نگه‌دارنده) <stefan.nordhausen@immobilienscout24.de>
  • Jakub Stasiak (نگه‌دارنده) <jakub@stasiak.at>

تحت مجوز BSD منتشر شده است (برای جزئیات به بخش مجوز <> مراجعه کنید).

netaddr توسط David P. D. Moss نوشته شده و در حال حاضر توسط Jakub Stasiak نگه‌داری می‌شود.

این پروژه تحت مجوز BSD منتشر شده است.

افراد بسیاری با گزارش مشکلات، پیشنهاد بهبودهای گوناگون یا ارسال کدهای واقعی به netaddr کمک کرده‌اند. در اینجا فهرستی از این افراد (به ترتیب حروف الفبا) آورده شده است. به ما در کامل و بدون خطا نگه‌داشتن آن کمک کنید.

Vincent Bernat <bernat AT debian.org>

Sebastien Douche <sdouche AT gmail.com>

John Eckersberg <john DOT eckersberg AT gmail.com>

Yi-Jheng Lin <yzlin AT cs.nctu.edu.tw>

Clay McClure <clay AT daemons.net>

Duncan McGreggor <duncan DOT mcgreggor AT gmail.com>

Stefan Nordhausen <stefan DOT nordhausen AT axiros.com>

Brian F. Peters <brianfpeters AT gmail.com>

James William Pye <jwp AT gmail.com>

Chaitan Rogers <chaitan DOT rogers AT gmail.com>

Victor Stinner <victor DOT stinner AT haypocalc.com>

Andrew Stromnov <stromnov AT gmail.com>

با سپاس از همهٔ اعضای لیست پستی netaddr، کسانی که گزارش باگ ارسال کردند و همهٔ کسانی که به‌طور مستقیم و غیرمستقیم، توسعه و توزیع این کتابخانه را راهنمایی کرده و تحت تأثیر قرار دادند.

همچنین با تشکر به خاطر استفاده از مشارکت‌های کد زیر:-

دستور ۱۸.۱۱ از Python Cookbook با عنوان: "Formatting Integers as Binary Strings"
Python Cookbook 2d ed. (O'Reilly Media 2005) ISBN 0596-00797-3 Alex Martelli, Anna Martelli Ravenscroft and David Ascher
دستور ۴۶۶۲۸۶ در ASPN Cookbook با عنوان: "Integer set type" اثر Heiko Wundram

و در پایان اما با همان اهمیت، تشکر از Guido van Rossum برای سخنان دلگرم‌کننده‌اش و برای هدیه دادن Python به همه ما..SH "نمایه‌ها و جدول‌ها (INDICES AND TABLES)"

  • نمایه <>
  • صفحهٔ جستجو <>

David P. D. Moss

2008 David P. D. Moss، ۲۰۲۰ مشارکت‌کنندگان netaddr

December 14, 2025 1.3.0