Netlink - Linux Netlink Socket Framing¶
pcapkit.protocols.link.netlink contains
Netlink
only, which implements the extractor for the struct nlmsghdr framing of
Linux’s own kernel/user IPC transport, as seen on a
LINKTYPE_LINUX_SLL/LINKTYPE_LINUX_SLL2 capture whose arphrd_type
is ARPHRD_NETLINK (an nlmon interface). Its structure is described as
below:
Octets |
Bits |
Name |
Description |
|---|---|---|---|
0 |
0 |
|
Message Length (header included) |
4 |
32 |
|
Message Type |
6 |
48 |
|
Message Flags |
8 |
64 |
|
Sequence Number |
12 |
96 |
|
Sender Port ID |
Only this fixed 16-octet header is dissected; per-family message payloads and
multiple messages packed into one capture are out of scope for this first
cut – see the module docstring’s Scope section. The byte order the header
was written in is ambiguous (Netlink [*] is kernel/userspace IPC, not wire
format) and is guessed by nlmsg_byteorder(); either way it is kept as
netlink.byteorder.
- class pcapkit.protocols.link.netlink.Netlink(file=None, length=None, **kwargs)[source]¶
-
This class implements Linux Netlink socket framing.
Every message’s payload is kept as
Rawunless itsnlmsg_typeis registered – see the module docstring’s Scope section for why.self.__proto__ships empty, so thatregister()works the same way every otherLinksubclass’s does.- read(length=None, *, byteorder=None, **kwargs)[source]¶
Read Linux Netlink socket framing.
Structure of the
nlmsghdrthis class dissects, the first message in the frame:0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nlmsg_len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nlmsg_type | nlmsg_flags | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nlmsg_seq | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nlmsg_pid | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Parameters:
byteorder (
Literal['big','little'] |None) – Byte order to read the header in, ahead of guessing it fromnlmsg_byteorder().make()is handed the oneinfoholds byfrom_data, and it reaches here too, so a rebuild reads the header as it was parsed rather than guessing again.**kwargs (
Any) – Arbitrary keyword arguments.
- Return type:
- Returns:
Parsed packet data.
- Raises:
ProtocolError – If
byteorderis neither'big'nor'little'.
- make(nlmsg_type=0, nlmsg_flags=0, nlmsg_seq=0, nlmsg_pid=0, nlmsg_len=None, byteorder=sys.byteorder, payload=b'', **kwargs)[source]¶
Make (construct) packet data.
- Parameters:
nlmsg_type (
int) – Message type.nlmsg_flags (
int) – Message flags.nlmsg_seq (
int) – Sequence number.nlmsg_pid (
int) – Sender port ID.nlmsg_len (
int|None) – Message length, header included; computed from the header andpayloadwhen omitted.byteorder (
Literal['big','little']) – Byte order to write the header in, by default this host’s, as a genuine capture is written in the capturing host’s own order.payload (
bytes|ProtocolBase|Schema) – Payload data.**kwargs (
Any) – Arbitrary keyword arguments.
- Return type:
- Returns:
Constructed packet data.
- Raises:
ProtocolError – If
byteorderis neither'big'nor'little'; ifnlmsg_typeornlmsg_flagsis not anint(aboolincluded) or does not fit in 16 bits; ifnlmsg_seqornlmsg_pidis not anint(aboolincluded) or does not fit in 32 bits; or ifnlmsg_lenis given and does not fit in 32 bits.
- classmethod register(code, protocol)[source]¶
Register a new protocol class for a message type.
Notes
The fully qualified class name of the new protocol class should be
{protocol.module}.{protocol.name}.- Parameters:
code (
int) –nlmsg_typeof the dissected messageprotocol (
ModuleDescriptor[ProtocolBase] |Type[ProtocolBase]) – module descriptor or aProtocolBasesubclass
Important
This overrides
Link.registerbecauseself.__proto__is keyed bynlmsg_typerather than by EtherType.- Raises:
pcapkit.utilities.exceptions.RegistryError – If
protocolis not a class, or not aProtocolBasesubclass.- Warns:
pcapkit.utilities.warnings.RegistryWarning– If this message type is already registered and the incumbent differs from the replacement; seeProtocol.registerfor the guard.
- classmethod __index__()[source]¶
Numeral registry index of the protocol.
- Return type:
- Returns:
Numeral registry index of the protocol in Linux ARP hardware types, the
arphrd_typethatLinuxSLL.__proto__dispatches here.
- __proto__: DefaultDict[int, ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]]¶
Protocol index mapping for decoding next layer, keyed by
nlmsg_type. Deliberately empty – see the class docstring – so every unregistered key resolves through thedefaultdictfallback toRaw.
- pcapkit.protocols.link.netlink.nlmsg_byteorder(nlmsg_len, length)[source]¶
Guess the byte order a Netlink message header was written in.
- Parameters:
nlmsg_len (
bytes) – The 4 raw octets ofnlmsg_len.length (
int) – Octets available from the start of this header to the end of the frame –nlmsg_lencounts the header itself (RFC 3549 Section 2.3.2: “the length of the message in bytes, including the header”), so this is the quantity to compare against, not the payload alone.
- Return type:
Literal['big','little']- Returns:
'big'or'little', whichever reading ofnlmsg_lencomes closer tolength; ties favour'little', the overwhelmingly common case (x86/ARM hosts).
Note
This is the heuristic Wireshark’s own netlink dissector uses (
packet-netlink.c,dissect_netlink()): a genuine message length is normally well under the size either misreading of 4 arbitrary octets would imply, so the reading closer to the octets actually on hand is overwhelmingly likely to be the real one.
Header Schemas¶
- class pcapkit.protocols.schema.link.netlink.Netlink(nlmsg_len=NO_VALUE, nlmsg_type=NO_VALUE, nlmsg_flags=NO_VALUE, nlmsg_seq=NO_VALUE, nlmsg_pid=NO_VALUE, payload=NO_VALUE, *, __packet__=None, **kwargs)[source]¶
Bases:
SchemaHeader schema for Linux Netlink socket framing (
nlmsghdr).
Data Models¶
- class pcapkit.protocols.data.link.netlink.Netlink(nlmsg_len, nlmsg_type, nlmsg_flags, nlmsg_seq, nlmsg_pid, byteorder)[source]¶
Bases:
ProtocolData model for Linux Netlink socket framing (
nlmsghdr).- nlmsg_len: int¶
Message length, in octets, including this 16-octet header – as written, in whichever byte order
byteorderrecords.
- nlmsg_type: int¶
Message type;
1-4are the generic control values (NLMSG_NOOP/NLMSG_ERROR/NLMSG_DONE/NLMSG_OVERRUN) shared by every Netlink family,16and above are family-specific and not interpreted by this class.
Footnotes