From 28b3d95a2577b3edb75d46044c12c9a0d2c33483 Mon Sep 17 00:00:00 2001 From: Dmitriy Bogun Date: Sun, 12 Jun 2022 00:56:15 +0300 Subject: [PATCH] Exclude end option during packet parsing Exclude END option(code==255) during packet parsing. As result options list in produced packet will not include the END option and as result .append() method will not append new options behind End option. So adding new option will not lead to producing malfolmed packet. --- dhcppython/packet.py | 35 ++++++++++++++++++++++++++--------- tests/test_packet.py | 4 ++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/dhcppython/packet.py b/dhcppython/packet.py index 6579de0..77f97b9 100644 --- a/dhcppython/packet.py +++ b/dhcppython/packet.py @@ -135,19 +135,36 @@ def from_bytes(cls, packet: bytes): options_list = options.OptionList() read_pos = cls.cookie_offset_end - code = 0 - while read_pos < len(packet) and code != 255: - code = packet[read_pos] - if code in [0, 255]: - data_read_size = 1 - else: - length = packet[read_pos + 1] + end_maker = False + while read_pos < len(packet): + if end_maker: + raise MalformedPacketError("Data after END option/marker") + + option_bytes = code = packet[read_pos] + if code == options.End.code: + end_maker = True + read_pos += 1 + continue + + if code != options.Pad.code: + try: + length = packet[read_pos + 1] + except IndexError: + length = 0 data_read_size = 1 + 1 + length + option_bytes = packet[read_pos:read_pos + data_read_size] + if data_read_size < len(option_bytes): + raise MalformedPacketError( + "Insufficient data, attempt to read {} bytes at offset " + "{}, but got only {}".format( + data_read_size, read_pos, len(option_bytes))) - option_bytes = packet[read_pos : read_pos + data_read_size] options_object = OPTIONS_INTERFACE.bytes_to_object(option_bytes) options_list.append(options_object) - read_pos += data_read_size + read_pos += len(option_bytes) + + if not end_maker and len(options_list): + raise MalformedPacketError("Missing END option") decoded_packet.append(options_list) # Decode the op code diff --git a/tests/test_packet.py b/tests/test_packet.py index 30a2020..55d2cb2 100644 --- a/tests/test_packet.py +++ b/tests/test_packet.py @@ -50,6 +50,10 @@ def test_parse_ack1(self): ack_linux ) + def test_parse_exclude_end_option(self): + parsed_packet = packet.DHCPPacket.from_bytes(discover_linux) + self.assertIsNone(parsed_packet.options.by_code(255)) + request_android: List[int] = [ 0x01, 0x01, 0x06, 0x00, 0xea, 0xbe,