# -*- coding: utf-8 -*-
# pylint: disable=wrong-import-position
"""IPX Packet Types
======================
.. module:: pcapkit.vendor.ipx.packet
This module contains the vendor crawler for **IPX Packet Types**,
which is automatically generating :class:`pcapkit.const.ipx.packet.Packet`.
"""
###############################################################################
# NOTE: fix duplicated name of ``socket``; restored in ``finally``, so a failed
# import does not lose the entry (#2589).
import sys
path = sys.path.pop(0)
try:
import collections
from typing import TYPE_CHECKING
from pcapkit.vendor.default import Vendor
if TYPE_CHECKING:
from collections import Counter
finally:
sys.path.insert(0, path)
###############################################################################
__all__ = ['Packet']
###############################################################################
# NOTE: maintained by hand, not crawled (#518, as #507): the Wikipedia table is gone
# from the live article, and IPX packet types are a closed Novell registry.
###############################################################################
#: IPX packet type registry, transcribed from the last revision of the Wikipedia
#: article that still carried the table,
#: https://en.wikipedia.org/w/index.php?title=Internetwork_Packet_Exchange&oldid=1368657333
#:
#: Maps a packet type to the enumeration name it takes and the comment rendered
#: above it. Names go through :meth:`~Vendor.rename`, so the generated member is
#: the :meth:`~Vendor.safe_name` of the first element; comments are stored as the
#: scrape rendered them, reStructuredText markup and all, since no Wikipedia
#: cell text remains for a scraping ``process()`` to rework.
#:
#: Every value below is independently corroborated by Wireshark's IPX dissector,
#: ``epan/dissectors/packet-ipx.h`` (fetched 2026-09-19), which defines
#: ``IPX_PACKET_TYPE_IPX 0``, ``_RIP 1``, ``_ECHO 2``, ``_ERROR 3``, ``_PEP 4``,
#: ``_SPX 5``, ``_NCP 17`` and ``_WANBCAST 20`` -- the same values in the
#: same order. Types 1-5 are inherited from Xerox XNS IDP, which IPX was derived
#: from, and -- type 4 apart -- no RFC assigns them. The note on each row below
#: says which sources do and do not carry its number.
DATA = {
# NOTE: no protocol assignment but the ``type`` field's default; "Unknown" is
# the archived revision's word alone, and Wireshark's is ``IPX``.
0: ('Unknown', 'Unknown'),
# :rfc:`1582` ("Extensions to RIP to Support Demand Circuits", 1994) and
# :rfc:`2091` ("Triggered Extensions to RIP to Support Demand Circuits",
# 1997) are the citation the article itself carried, and they do describe
# IPX RIP -- "the Routing Information Protocol (RIP) which runs over the
# Internetwork Packet Exchange (IPX) protocol using socket number 453h".
# Note honestly that they extend IPX RIP rather than assign it packet type
# 1; for the assignment they defer to Novell, "IPX Router Specification",
# Version 1.10, October 1992, which :rfc:`1582` lists as reference [3].
1: ('RIP', '``RIP``, Routing Information Protocol ([:rfc:`1582`], [:rfc:`2091`])'),
# XNS IDP inheritances. The archived revision is the only source found for
# these two names: no RFC and no reachable Novell document lists
# either against a packet-type number. Wireshark corroborates the values as
# ``ECHO 2`` and ``ERROR 3``.
2: ('Echo Packet', 'Echo Packet'),
3: ('Error Packet', 'Error Packet'),
# NOTE: the best-sourced row: :rfc:`1362`, :rfc:`1551`, :rfc:`1634`, :rfc:`1791`
# and :rfc:`1132` all give packet type 4.
4: ('PEP', '``PEP``, Packet Exchange Protocol, used for SAP (Service Advertising Protocol)'),
# :rfc:`1553` names the protocol -- "The Sequenced Packet Exchange (SPX) is
# the reliable connection-based transport protocol commonly used by
# applications" -- but not its packet-type number, which rests on Wireshark
# and the archived revision.
5: ('SPX', '``SPX``, Sequenced Packet Exchange'),
# :rfc:`1553` names this one too -- "the Netware Core Protocol (NCP), which
# is used for file server access" -- and again without the number. 17
# (0x11) rests on Wireshark and the archived revision.
17: ('NCP', '``NCP``, NetWare Core Protocol'),
# NOTE: :rfc:`1132` assigns 0x14; ``[4]`` is Wikipedia's footnote marker, kept verbatim,
# as renaming :attr:`~pcapkit.const.ipx.packet.Packet.Broadcast_4` breaks it (#518).
20: ('Broadcast[4]', 'Broadcast[4]'),
} # type: dict[int, tuple[str, str]]
[docs]
class Packet(Vendor):
"""IPX Packet Types"""
#: Value limit checker.
FLAG = 'isinstance(value, int) and 0 <= value <= 255'
def request(self) -> 'dict[int, tuple[str, str]]': # type: ignore[override] # pylint: disable=arguments-differ
"""Fetch registry data.
Returns:
Registry data (:data:`~pcapkit.vendor.ipx.packet.DATA`).
"""
return DATA
def count(self, data: 'dict[int, tuple[str, str]]') -> 'Counter[str]': # type: ignore[override]
"""Count field records.
Args:
data: Registry data.
Returns:
Field recordings.
"""
return collections.Counter(self.safe_name(name) for name, _ in data.values())
def process(self, data: 'dict[int, tuple[str, str]]') -> 'tuple[list[str], list[str]]': # type: ignore[override]
"""Process registry data.
Args:
data: Registry data.
Returns:
Enumeration fields and missing fields.
"""
enum = [] # type: list[str]
miss = [
"return cls._unregistered_member(value, 'Unassigned')",
]
for code, (name, desc) in data.items():
pval = str(code)
renm = self.rename(name, pval)
enum.append(f'#: {self.wrap_comment(desc)}\n {renm} = {pval}')
return enum, miss
if __name__ == '__main__':
sys.exit(Packet()) # type: ignore[arg-type]