From e9842dc6bec50adcfc5277f4425cb52e0dfb2953 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Fri, 7 Jul 2017 16:51:06 -0300 Subject: [PATCH 1/2] introduce general unpack method (comes from of_core.utils) --- pyof/utils.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 pyof/utils.py diff --git a/pyof/utils.py b/pyof/utils.py new file mode 100644 index 000000000..a71d8945d --- /dev/null +++ b/pyof/utils.py @@ -0,0 +1,37 @@ +"""General Unpack utils for python-openflow.""" +import pyof.v0x01.common.header +import pyof.v0x01.common.utils +import pyof.v0x04.common.header +import pyof.v0x04.common.utils +from pyof.foundation.exceptions import UnpackException + +pyof_version_libs = {0x01: pyof.v0x01, + 0x04: pyof.v0x04} + + +def unpack(packet): + """Unpack the OpenFlow Packet and returns a message.""" + try: + version = packet[0] + except IndexError: + raise UnpackException('null packet') + + try: + pyof_lib = pyof_version_libs[version] + except KeyError: + raise UnpackException('Version not supported') + + try: + header = pyof_lib.common.header.Header() + header.unpack(packet[:8]) + message = pyof_lib.common.utils.new_message_from_header(header) + binary_data = packet[8:] + if binary_data: + if len(binary_data) == header.length - 8: + message.unpack(binary_data) + else: + raise UnpackException( + 'packet size does not match packet length field') + return message + except (UnpackException, ValueError) as e: + raise UnpackException(e) From a2d4480810f5ae4a96b8a5f372d5b41b827f2642 Mon Sep 17 00:00:00 2001 From: Erick Vermot Date: Fri, 14 Jul 2017 15:17:14 -0300 Subject: [PATCH 2/2] separate packet validation from unpack --- pyof/utils.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/pyof/utils.py b/pyof/utils.py index a71d8945d..179e2c2cf 100644 --- a/pyof/utils.py +++ b/pyof/utils.py @@ -9,13 +9,30 @@ 0x04: pyof.v0x04} +def validate_packet(packet): + """Check if packet is valid OF packet.""" + if not isinstance(packet, bytes): + raise UnpackException('invalid packet') + + packet_length = len(packet) + + if packet_length < 8 or packet_length > 2**16: + raise UnpackException('invalid packet') + + if packet_length != int.from_bytes(packet[2:4], + byteorder='big'): + raise UnpackException('invalid packet') + + version = packet[0] + if version == 0 or version >= 128: + raise UnpackException('invalid packet') + + def unpack(packet): """Unpack the OpenFlow Packet and returns a message.""" - try: - version = packet[0] - except IndexError: - raise UnpackException('null packet') + validate_packet(packet) + version = packet[0] try: pyof_lib = pyof_version_libs[version] except KeyError: @@ -27,11 +44,7 @@ def unpack(packet): message = pyof_lib.common.utils.new_message_from_header(header) binary_data = packet[8:] if binary_data: - if len(binary_data) == header.length - 8: - message.unpack(binary_data) - else: - raise UnpackException( - 'packet size does not match packet length field') + message.unpack(binary_data) return message except (UnpackException, ValueError) as e: raise UnpackException(e)