IP Address Fields

IP Addresses

class pcapkit.corekit.fields.ipaddress.IPv4AddressField(default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function IPv4AddressField.<lambda>>)[source]

Bases: _IPAddressField[IPv4Address]

IPv4 address value for protocol fields.

Parameters:
property version: Literal[4]

IP version number.

class pcapkit.corekit.fields.ipaddress.IPv6AddressField(default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function IPv6AddressField.<lambda>>)[source]

Bases: _IPAddressField[IPv6Address]

IPv6 address value for protocol fields.

Parameters:
property version: Literal[6]

IP version number.

IP Interface

class pcapkit.corekit.fields.ipaddress.IPv4InterfaceField(default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function IPv4InterfaceField.<lambda>>)[source]

Bases: _IPInterfaceField[IPv4Interface]

IPv4 interface value for protocol fields.

Parameters:
property version: Literal[4]

IP version number.

pre_process(value, packet)[source]

Process field value before packing.

Parameters:
Return type:

bytes

Returns:

Processed field value.

Raises:

FieldValueError – If value is a bool (c.f. _reject_bool()), is not a valid IP interface, or is the wrong IP version for this field.

post_process(value, packet)[source]

Process field value after parsing (unpacking).

Parameters:
Return type:

IPv4Interface

Returns:

Processed field value.

Raises:

FieldValueError – If the trailing four octets are not a valid dotted netmask, or if the resulting interface is the wrong IP version for this field. The leading four octets cannot actually fail here – they are always exactly 4 octets, fixed by this field’s length, and any such octet string is a valid address – but the conversion is still wrapped for consistency with the rest of this module.

Notes

The trailing four octets are a dotted netmask, as written by pre_process() – not a prefix length as in IPv6InterfaceField.post_process().

class pcapkit.corekit.fields.ipaddress.IPv6InterfaceField(default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function IPv6InterfaceField.<lambda>>)[source]

Bases: _IPInterfaceField[IPv6Interface]

IPv6 interface value for protocol fields.

Parameters:
property version: Literal[6]

IP version number.

pre_process(value, packet)[source]

Process field value before packing.

Parameters:
Return type:

bytes

Returns:

Processed field value.

Raises:

FieldValueError – If value is a bool (c.f. _reject_bool()), is not a valid IP interface, or is the wrong IP version for this field.

post_process(value, packet)[source]

Process field value after parsing (unpacking).

Parameters:
Return type:

IPv6Interface

Returns:

Processed field value.

Raises:

FieldValueError – If the trailing octet is not a valid IPv6 prefix length, i.e. greater than 128, or if the resulting interface is the wrong IP version for this field. Neither the leading sixteen octets nor the final ipaddress.ip_interface() call can actually fail here – the former is always exactly 16 octets, fixed by this field’s length, and any such octet string is a valid address; the latter is only ever reached once the prefix length has already been checked above, and any prefix length in 0..128 is valid. Both conversions are still wrapped for consistency with the rest of this module.

Notes

The trailing octet is the prefix length as a binary integer, as written by pre_process() – not a dotted netmask as in IPv4InterfaceField.post_process().

Construction Helpers

pcapkit.corekit.fields.ipaddress.parse_ip_address(value, description, version=None)[source]

Convert a caller-supplied address on the construction path.

Parameters:
  • value (IPv4Address | IPv6Address | bytes | int | str) – Address as the caller gave it – an ipaddress object, which is returned unchanged, or anything ipaddress accepts.

  • description (str) – Human-readable description of what value is, used to build the FieldValueError message. Callers in a protocol should carry their usual context into it, e.g. f'{self.alias}: [OptNo {type}] care-of address'.

  • version (int | None) – IP version to demand, 4 or 6, or None to take whichever family value describes. Pass it where the wire format fixes the family, so that an int is widened to the right one – 258 is ::102 for version=6 but 0.0.1.2 for ipaddress.ip_address().

Return type:

IPv4Address | IPv6Address

Returns:

The converted address.

Raises:

FieldValueError – If value is a bool (c.f. _reject_bool()), is not a valid IP address, or is not of version.

Notes

This is the sanctioned way for a _make_* method to turn a caller-supplied address into an ipaddress object, and it exists because doing it with ipaddress.ip_address() directly is what #508 turned out to be: a _make_* that has to know the address family before it can build the schema – to size an option whose length is the only thing on the wire that carries the family – must convert the argument itself, and that conversion happens before the schema, so it launders a bool into an IPv4Address that #500’s guard in _IPAddressField.pre_process() can then only see as a legitimate address. Seven such call sites took True / False without complaint as 0.0.0.1 / 0.0.0.0 – or ::1 / :: where the wire format fixes the family as IPv6 – and six of them went on to pack those octets. The seventh, TCP._make_mptcp_addaddr, built an equally corrupt schema and is only stopped from packing it by an unrelated defect of its own.

Routing every one of them through here rather than giving each its own isinstance() check is the whole point: #481 added exactly such a check to MH._make_opt_mn_id, and #491 was the same defect surviving at every site that had not been thought of. A guard that has to be remembered per call site is a guard that will be forgotten at the next one.

The bool rejection is the first statement here, ahead of any dispatch on the value’s type, for the placement reason #481 gives and _reject_bool() repeats.

This raises FieldValueError and not ProtocolError, which is deliberate even though two sibling guards for the same mistake – MH._make_opt_mn_id from #481 and ESP's SecurityAssociation from #491 – raise the latter. The layer decides: this is a field-level conversion, so it answers with what _IPAddressField.pre_process() answers with for the identical value, and a caller sees one exception whether the bool reached the field through the schema or through a _make_*. The two protocol-level guards answer for the option, alongside siblings that are not about addresses at all – _make_opt_mn_id refuses a bool for all eight MN-ID subtypes, only one of which is address-typed – so neither can route through here without losing the subtype-aware message that is the point of it. Both exception classes derive from BaseError and ValueError, so the difference is invisible to except BaseError and except ValueError, and nothing in the library catches either one specifically.

Internal Definitions

class pcapkit.corekit.fields.ipaddress._IPField(length, default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function Field.<lambda>>)[source]

Bases: Field[_T], Generic[_T]

Internal IP related value for protocol fields.

Parameters:
abstract property version: int

IP version number.

class pcapkit.corekit.fields.ipaddress._IPAddressField(length, default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function Field.<lambda>>)[source]

Bases: _IPField[_AT]

Internal IP address value for protocol fields.

Parameters:
pre_process(value, packet)[source]

Process field value before packing.

Parameters:
Return type:

bytes

Returns:

Processed field value.

Raises:

FieldValueError – If value is a bool (c.f. _reject_bool()), is not a valid IP address, or is the wrong IP version for this field.

post_process(value, packet)[source]

Process field value after parsing (unpacking).

Parameters:
Return type:

TypeVar(_AT, IPv4Address, IPv6Address)

Returns:

Processed field value.

Raises:

FieldValueError – If value is the wrong IP version for this field. value cannot actually fail the underlying ipaddress.ip_address() conversion here – it is always exactly 4 or 16 octets, fixed by this field’s length, and any such octet string is a valid address – but the conversion is still wrapped for consistency with the rest of this module.

class pcapkit.corekit.fields.ipaddress._IPInterfaceField(length, default=<pcapkit.corekit.fields.field.NoValueType object>, callback=<function Field.<lambda>>)[source]

Bases: _IPField[_IT]

Internal IP interface value for protocol fields.

Parameters:

Type Variables

pcapkit.corekit.fields.ipaddress._T: ipaddress.IPv4Address | ipaddress.IPv6Address | ipaddress.IPv4Interface | ipaddress.IPv6Interface
pcapkit.corekit.fields.ipaddress._AT: ipaddress.IPv4Address | ipaddress.IPv6Address
pcapkit.corekit.fields.ipaddress._IT: ipaddress.IPv4Interface | ipaddress.IPv6Interface