Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pcapkit/protocols/internet/hip.py
Original file line number Diff line number Diff line change
Expand Up @@ -3450,7 +3450,9 @@ def _make_locator(locator: 'Optional[Data_Locator]' = None, *,
ip=value.ip.packed,
)
else:
raise ProtocolError(f'HIPv{version}: [ParamNo {code}] invalid format')
raise ProtocolError(f'HIPv{version}: [ParamNo {code}] invalid locator: '
f'must be an ipaddress.IPv6Address or a LocatorData, '
f'not {value!r}')

traffic = locator.traffic
type = locator.type
Expand Down
40 changes: 35 additions & 5 deletions pcapkit/protocols/internet/mh.py
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,12 @@ def make(self,
Returns:
Constructed packet data.

Raises:
ProtocolError: If ``data`` is none of the forms this maker reads --
raw :obj:`bytes`, a :obj:`dict` of message arguments, an
:class:`~pcapkit.protocols.data.internet.mh.MH` data model or a
:class:`~pcapkit.protocols.schema.internet.mh.Packet` schema.

.. versionchanged:: 1.5.0

Takes ``reserved`` ahead of ``chksum`` (:issue:`1329`), which shifts
Expand Down Expand Up @@ -1483,7 +1489,8 @@ def make(self,
elif isinstance(data, Schema_Packet):
data_val = data
else:
raise ProtocolError(f'MH: [Type {type_val}] invalid format')
raise ProtocolError(f'MH: [Type {type_val}] invalid data: must be bytes, a dict, '
f'an MH data model or a Packet schema, not {data!r}')

# NOTE: The header has to be a multiple of 8 octets, so the message data
# needs padding until ``len(data) + 6`` is aligned. Rounding ``length`` up
Expand Down Expand Up @@ -7903,6 +7910,11 @@ def _make_opt_pad(self, type: 'Enum_Option', option: 'Optional[Data_PadOption]'
Returns:
Constructed option schema.

Warns:
ProtocolWarning: If ``length`` is non-zero for a ``Pad1``, which
has no ``Option Length`` field to carry it; the option is made
as a ``PadN`` instead.

Note:
:attr:`Data_PadOption.length
<pcapkit.protocols.data.internet.mh.Option.length>` counts the
Expand All @@ -7921,7 +7933,8 @@ def _make_opt_pad(self, type: 'Enum_Option', option: 'Optional[Data_PadOption]'
data = getattr(option, 'data', b'')

if type == Enum_Option.Pad1 and length != 0:
warn(f'{self.alias}: [OptNo {type}] invalid format', ProtocolWarning)
warn(f'{self.alias}: [OptNo {type}] invalid length: must be 0 for a Pad1 option, '
f'not {length!r}; making a PadN', ProtocolWarning)
type = Enum_Option.PadN # type: ignore[assignment]

return Schema_PadOption(
Expand Down Expand Up @@ -8024,12 +8037,18 @@ def _make_opt_bad(self, type: 'Enum_Option', option: 'Optional[Data_Authorizatio
Returns:
Constructed option schema.

Raises:
ProtocolError: If ``data`` is not a multiple of eight octets, the
length :meth:`_read_opt_bad` accepts for an :rfc:`6275`
authenticator.

"""
if option is not None:
data = option.data

if len(data) % 8 != 0:
raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid format')
raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid data: '
f'must be a multiple of eight octets, not {data!r}')

return Schema_AuthorizationDataOption(
type=type,
Expand Down Expand Up @@ -8349,6 +8368,11 @@ def _make_opt_auth(self, type: 'Enum_Option', option: 'Optional[Data_AuthOption]
Returns:
Constructed option schema.

Raises:
ProtocolError: If ``data`` is not two octets more than a multiple of
four, which is the only length leaving an ``Option Length`` of
``5 + len(data)`` that :meth:`_read_opt_auth` accepts.

"""
if option is not None:
subtype_val = option.subtype
Expand All @@ -8359,7 +8383,8 @@ def _make_opt_auth(self, type: 'Enum_Option', option: 'Optional[Data_AuthOption]
reversed=subtype_reversed, pack=False)

if (len(data) + 6) % 4 != 0:
raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid format')
raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid data: must be two octets '
f'more than a multiple of four, not {data!r}')

return Schema_AuthOption(
type=type,
Expand Down Expand Up @@ -8611,6 +8636,10 @@ def _make_opt_badf(self, type: 'Enum_Option', option: 'Optional[Data_BADFOption]
Returns:
Constructed option schema.

Raises:
ProtocolError: If ``data`` is empty, since the ``length`` field then
reads as ``0``, which :meth:`_read_opt_badf` rejects.

Note:
The ``length`` field counts the authenticator only, excluding the
SPI, see :meth:`_read_opt_badf`.
Expand All @@ -8621,7 +8650,8 @@ def _make_opt_badf(self, type: 'Enum_Option', option: 'Optional[Data_BADFOption]
data = option.data

if not data:
raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid format')
raise ProtocolError(f'{self.alias}: [OptNo {type}] invalid data: '
f'must be at least one octet, not {data!r}')

return Schema_BADFOption(
type=type,
Expand Down
9 changes: 8 additions & 1 deletion pcapkit/protocols/misc/pcapng.py
Original file line number Diff line number Diff line change
Expand Up @@ -4882,6 +4882,12 @@ def _make_block_dsb(self, block: 'Optional[Data_DecryptionSecretsBlock]' = None,
Returns:
Constructed block schema.

Raises:
ProtocolError: If ``secrets_data`` is none of the forms this maker
reads -- raw :obj:`bytes`, a :obj:`dict` of secrets arguments, a
:class:`~pcapkit.protocols.data.misc.pcapng.DSBSecrets` data
model or a :class:`~pcapkit.protocols.schema.schema.Schema`.

"""
declared = None # type: Optional[int]
if block is not None:
Expand Down Expand Up @@ -4921,7 +4927,8 @@ def _make_block_dsb(self, block: 'Optional[Data_DecryptionSecretsBlock]' = None,
elif isinstance(secrets_data, Schema):
secrets_data_val = secrets_data
else:
raise ProtocolError(f'PCAP-NG: [DSB] secrets {secrets_type_val} invalid format')
raise ProtocolError(f'PCAP-NG: [DSB] invalid secrets_data: must be bytes, a dict, '
f'a DSBSecrets data model or a Schema, not {secrets_data!r}')
# NOTE: Secrets Length excludes the padding to the next 32-bit boundary,
# which ``padding_data`` writes and the block length has to include.
if block is not None and isinstance(secrets_data_val, Schema):
Expand Down
42 changes: 28 additions & 14 deletions pcapkit/protocols/transport/sctp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,8 @@ def _make_chunk_donone(self, code: 'Enum_Chunk', chunk: 'Optional[Data_UnknownCh
value = chunk.value

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

return Schema_UnknownChunk(
type=code,
Expand Down Expand Up @@ -1965,7 +1966,8 @@ def _make_chunk_data(self, code: 'Enum_Chunk', chunk: 'Optional[Data_DATAChunk]'
data = chunk.data

if not data:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid data: '
f'must be at least one octet, not {data!r}')

return Schema_DATAChunk(
type=code,
Expand Down Expand Up @@ -2028,7 +2030,8 @@ def _make_chunk_init(self, code: 'Enum_Chunk', chunk: 'Optional[Data_INITChunk]'
parameters = chunk.parameters

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

if parameters is not None:
parameters_value = self._make_sctp_parameters(parameters)
Expand Down Expand Up @@ -2089,7 +2092,8 @@ def _make_chunk_init_ack(self, code: 'Enum_Chunk', chunk: 'Optional[Data_INITACK
parameters = chunk.parameters

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

if parameters is not None:
parameters_value = self._make_sctp_parameters(parameters)
Expand Down Expand Up @@ -2150,7 +2154,8 @@ def _make_chunk_sack(self, code: 'Enum_Chunk', chunk: 'Optional[Data_SACKChunk]'
dup_tsn = list(chunk.dup_tsn)

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

blocks = [] # type: list[Schema_GapAckBlock]
for block in gap_blocks or []:
Expand Down Expand Up @@ -2200,7 +2205,8 @@ def _make_chunk_heartbeat(self, code: 'Enum_Chunk', chunk: 'Optional[Data_Heartb
parameters = chunk.parameters

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

if parameters is not None:
parameters_value = self._make_sctp_parameters(parameters)
Expand Down Expand Up @@ -2241,7 +2247,8 @@ def _make_chunk_heartbeat_ack(self, code: 'Enum_Chunk', chunk: 'Optional[Data_He
parameters = chunk.parameters

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

if parameters is not None:
parameters_value = self._make_sctp_parameters(parameters)
Expand Down Expand Up @@ -2323,7 +2330,8 @@ def _make_chunk_shutdown(self, code: 'Enum_Chunk', chunk: 'Optional[Data_Shutdow
cum_tsn_ack = chunk.cum_tsn_ack

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

return Schema_ShutdownChunk(
type=code,
Expand Down Expand Up @@ -2354,7 +2362,8 @@ def _make_chunk_shutdown_ack(self, code: 'Enum_Chunk', chunk: 'Optional[Data_Shu
flags = chunk.flags

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

return Schema_ShutdownACKChunk(
type=code,
Expand Down Expand Up @@ -2387,7 +2396,8 @@ def _make_chunk_error(self, code: 'Enum_Chunk', chunk: 'Optional[Data_ErrorChunk
error = chunk.error

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

if error is not None:
error_value = self._make_sctp_causes(error)
Expand Down Expand Up @@ -2429,7 +2439,8 @@ def _make_chunk_cookie_echo(self, code: 'Enum_Chunk', chunk: 'Optional[Data_Cook
cookie = chunk.cookie

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

return Schema_CookieEchoChunk(
type=code,
Expand Down Expand Up @@ -2460,7 +2471,8 @@ def _make_chunk_cookie_ack(self, code: 'Enum_Chunk', chunk: 'Optional[Data_Cooki
flags = chunk.flags

if len(flags) != 1:
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Chunk {code}] invalid flags: '
f'must be one octet, not {flags!r}')

return Schema_CookieACKChunk(
type=code,
Expand Down Expand Up @@ -3018,7 +3030,8 @@ def _make_param_hostname(self, code: 'Enum_Parameter', param: 'Optional[Data_Hos
if param is not None:
name = param.name
elif not name.endswith(b'\x00'):
raise ProtocolError(f'{self.alias}: [Param {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Param {code}] invalid name: '
f'must be NUL-terminated, not {name!r}')

return Schema_HostNameAddressParameter(
type=code,
Expand Down Expand Up @@ -3583,7 +3596,8 @@ def _make_cause_invalid_stream(self, code: 'Enum_CauseCode', cause: 'Optional[Da
reserved = cause.reserved

if len(reserved) != 2:
raise ProtocolError(f'{self.alias}: [Cause {code}] invalid format')
raise ProtocolError(f'{self.alias}: [Cause {code}] invalid reserved: '
f'must be two octets, not {reserved!r}')

return Schema_InvalidStreamIdentifierCause(
code=code,
Expand Down
8 changes: 6 additions & 2 deletions pcapkit/protocols/transport/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2971,10 +2971,14 @@ def _make_mptcp_capable(self, subtype: 'Enum_MPTCPOption', opt: 'Optional[Data_M
dl_len = opt.dl_len
checksum = opt.checksum

names = ('skey', 'rkey', 'dl_len', 'checksum')
fields = (skey, rkey, dl_len, checksum)
present = fields.index(None) if None in fields else len(fields)
if any(field is not None for field in fields[present:]):
raise ProtocolError(f'{self.alias}: [OptNo {Enum_Option.Multipath_TCP}] invalid format')
for index in range(present, len(fields)):
if fields[index] is not None:
raise ProtocolError(
f'{self.alias}: [OptNo {Enum_Option.Multipath_TCP}] invalid {names[index]}: '
f'must be None when {names[present]} is None, not {fields[index]!r}')

return Schema_MPTCPCapable(
kind=cast('Enum_Option', Enum_Option.Multipath_TCP),
Expand Down
Loading
Loading