Miscellaneous Fields

Conditional Fields

class pcapkit.corekit.fields.misc.SwitchField[_TC](selector=lambda _: ...)[source]

Bases: FieldBase[_TC]

Conditional type-switching field for protocol schema.

Parameters:

selector (Callable[[dict[str, Any]], FieldBase[_TC]]) – Callable function to select field type, which should accept the current packet as its only argument and return a field instance.

property name: str

Field name.

property default: _TC | NoValueType

Field default value.

property template: str

Field template.

property length: int

Field size.

property optional: bool

Field is optional.

property field: FieldBase[_TC]

Field instance.

__call__(packet)[source]

Call field.

Parameters:

packet (dict[str, Any]) – Packet data.

Return type:

SwitchField[_TC]

Returns:

New field instance.

This method will return a new instance of SwitchField instead of updating the current instance.

pre_process(value, packet)[source]

Process field value before construction (packing).

Parameters:
  • value (_TC) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

Any

Returns:

Processed field value.

pack(value, packet)[source]

Pack field value into bytes.

Parameters:
  • value (_TC | None) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

bytes

Returns:

Packed field value.

post_process(value, packet)[source]

Process field value after parsing (unpacking).

Parameters:
  • value (Any) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

_TC

Returns:

Processed field value.

unpack(buffer, packet)[source]

Unpack field value from bytes.

Parameters:
Return type:

_TC

Returns:

Unpacked field value.

class pcapkit.corekit.fields.misc.ConditionalField[_TC](field, condition)[source]

Bases: FieldBase[_TC]

Conditional value for protocol fields.

Parameters:
  • field (FieldBase[_TC]) – Field instance.

  • condition (Callable[[dict[str, Any]], bool]) – Field condition function (this function should return a bool value and accept the current packet data as its only argument).

property name: str

Field name.

property default: _TC | NoValueType

Field default value.

property template: str

Field template.

property length: int

Field size.

property optional: bool

Field is optional.

property field: FieldBase[_TC]

Field instance.

__call__(packet)[source]

Update field attributes.

Parameters:

packet (dict[str, Any]) – Packet data.

Return type:

Self

Returns:

Updated field instance.

This method will return a new instance of ConditionalField instead of updating the current instance.

pre_process(value, packet)[source]

Process field value before construction (packing).

Parameters:
  • value (_TC) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

Any

Returns:

Processed field value.

pack(value, packet)[source]

Pack field value into bytes.

Parameters:
  • value (_TC | None) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

bytes

Returns:

Packed field value.

post_process(value, packet)[source]

Process field value after parsing (unpacking).

Parameters:
  • value (Any) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

_TC

Returns:

Processed field value.

unpack(buffer, packet)[source]

Unpack field value from bytes.

Parameters:
Return type:

_TC

Returns:

Unpacked field value.

test(packet)[source]

Test field condition.

Parameters:

packet (dict[str, Any]) – Current packet.

Returns:

Test result.

Return type:

bool

class pcapkit.corekit.fields.misc.ForwardMatchField[_TC](field)[source]

Bases: FieldBase[_TC]

Schema field for non-capturing forward matching.

Parameters:

field (FieldBase[_TC]) – Field to forward match.

property name: str

Field name.

property default: _TC | NoValueType

Field default value.

property template: str

Field template.

property length: int

Field size.

property optional: bool

Field is optional.

property field: FieldBase[_TC]

Field instance.

__call__(packet)[source]

Update field attributes.

Parameters:

packet (dict[str, Any]) – Packet data.

Return type:

Self

Returns:

Updated field instance.

This method will return a new instance of ForwardMatchField instead of updating the current instance.

pack(value, packet)[source]

Pack field value into bytes.

Parameters:
  • value (_TC | None) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

bytes

Returns:

Packed field value.

unpack(buffer, packet)[source]

Unpack field value from bytes.

Parameters:
Return type:

_TC

Returns:

Unpacked field value.

Generic Data Fields

class pcapkit.corekit.fields.misc.SchemaField[_TS: Schema](length=lambda _: ..., schema=None, default=NO_VALUE, packet=None, callback=lambda *_: ...)[source]

Bases: FieldBase[_TS]

Schema field for protocol schema.

Parameters:
  • length (int | Callable[[dict[str, Any]], int]) – Field size (in bytes); if a callable is given, it should return an integer value and accept the current packet as its only argument.

  • schema (Type[_TS] | None) – Field schema.

  • default (_TS | NoValueType | bytes) – Default value for field.

  • packet (dict[str, Any] | None) – Optional packet data for unpacking and/or packing purposes.

  • callback (Callable[[Self, dict[str, Any]], None]) – Callback function to process field value, which should accept the current field and the current packet as its arguments.

property length: int

Field size.

property optional: bool

Field is optional.

property schema: Type[_TS]

Field schema.

__call__(packet)[source]

Update field attributes.

Parameters:

packet (dict[str, Any]) – Packet data.

Return type:

Self

Returns:

New field instance.

This method will return a new instance of SchemaField instead of updating the current instance.

pack(value, packet)[source]

Pack field value into bytes.

Parameters:
Return type:

bytes

Returns:

Packed field value.

Notes

packet is reachable from the nested schema’s own field callbacks both under a __packet__ key and, for a name the nested schema does not itself declare, directly – see nested_packet_context().

unpack(buffer, packet)[source]

Unpack field value from bytes.

Parameters:
Return type:

_TS

Returns:

Unpacked field value.

Notes

packet is reachable from the nested schema’s own field callbacks both under a __packet__ key and, for a name the nested schema does not itself declare, directly – see nested_packet_context().

pcapkit.corekit.fields.misc.nested_packet_context(packet)[source]

Build the packet context handed to a nested schema’s field callbacks.

Parameters:

packet (dict[str, Any]) – The enclosing schema’s own packet data.

Return type:

dict[str, Any]

Returns:

A plain dict holding a shallow copy of packet’s own names, plus the reserved __packet__ key bound to packet itself.

Notes

A nested schema’s field callbacks are written exactly like a top-level schema’s – length=lambda pkt: pkt['length'] – so a name the nested schema does not itself declare has to resolve to the enclosing schema’s value rather than raise KeyError. Copying the enclosing names in is what gives that, with no lookup protocol to implement: every mapping operation is dict’s own, so pkt[key], key in pkt, get(), setdefault(), pop(), ==, iteration and dict(**pkt) all behave exactly as a caller reading the code would expect, and none of them needs an override.

The enclosing schema is also reachable unconditionally under the reserved __packet__ key, for a callback that needs to name the outer schema specifically rather than whichever schema happens to declare a given field – see pcapkit.corekit.schema.byteorder.packet_byteorder() and post_process() for why that distinction matters; both hand-roll this exact fallback themselves rather than route through this function.

Nothing written through the returned mapping reaches packet, because the returned mapping is a copy: a nested schema can set – or shadow – a name also declared by the enclosing schema without the write ever touching the enclosing schema’s own data, and without the write silently disappearing either. That matters concretely rather than hypothetically: CGAExtension declares its own length while the option enclosing it declares length too, so handing a nested schema the enclosing mapping itself would let the inner length overwrite the outer one mid-pack.

Its being a copy rather than a live view has consequences, each deliberate and none reached by any call site in this package. A name deleted from the returned mapping is simply gone, rather than reverting to the enclosing schema’s value. And the copy is taken when this function is called, so a later mutation of packet is not observed through it – __packet__ remains bound to the live enclosing mapping for any callback that needs the current value.

No dedicated class and no ChainMap. A plain dict satisfies every packet: 'dict[str, Any]' annotation on the rest of the field classes natively, so no cast() is needed at the call site, and it cannot interact with ABCMeta at all because dict is not an ABCMeta-based class. That also settles a suspicion, raised on #439, that a ChainMap here would corrupt the ABCMeta cache Schema subclasses shared on CPython <= 3.10. The suspicion is probably wrong, and this code cannot test it: the cache keys on the exact type queried, so asking about a ChainMap instance caches lookups for ChainMap and not for dict, the poisoning observed in #439 came from ordinary code asking isinstance() about a plain dict, and #439 is fixed directly – every Schema subclass gets its own _abc_impl. Against that, on CPython 3.10 choosing between a ChainMap and a plain literal here was observed to flip test_pcapng_remaining_constructor_branches_and_custom_dispatch between passing and failing, in both directions; the likeliest reading is that the choice changes which types flow through unrelated isinstance() calls rather than causing the corruption. It does not affect correctness either way.

class pcapkit.corekit.fields.misc.PayloadField[_TP: ProtocolBase](length=lambda _: ..., default=NO_VALUE, protocol=None, callback=lambda *_: ...)[source]

Bases: FieldBase[_TP]

Payload value for protocol fields.

Parameters:
property template: str

Field template.

property length: int

Field size.

property optional: bool

Field is optional.

property protocol: Type[_TP]

Payload protocol.

Setter accepts:

Type[_TP] | str

__call__(packet)[source]

Update field attributes.

Parameters:

packet (dict[str, Any]) – Packet data.

Return type:

Self

Returns:

Updated field instance.

This method will return a new instance of PayloadField instead of updating the current instance.

pack(value, packet)[source]

Pack field value into bytes.

Parameters:
Return type:

bytes

Returns:

Packed field value.

unpack(buffer, packet)[source]

Unpack field value from bytes.

Parameters:
Return type:

_TP

Returns:

Unpacked field value.

class pcapkit.corekit.fields.misc.NoValueField[_TN: NoValueType](*args, **kwargs)[source]

Bases: FieldBase[_TN]

Schema field for no value type (or None).

property template: str

Field template.

property length: int

Field size.

pack(value, packet)[source]

Pack field value into bytes.

Parameters:
  • value (_TN | None) – Field value.

  • packet (dict[str, Any]) – Packet data.

Return type:

bytes

Returns:

Packed field value.

unpack(buffer, packet)[source]

Unpack field value from bytes.

Parameters:
Return type:

_TN

Returns:

Unpacked field value.

Type Variables

pcapkit.corekit.fields.misc._TC: Any
pcapkit.corekit.fields.misc._TS: pcapkit.protocols.schema.Schema
pcapkit.corekit.fields.misc._TP: pcapkit.protocols.protocol.ProtocolBase
pcapkit.corekit.fields.misc._TN: pcapkit.corekit.sentinels.NoValueType