Ejemplo n.º 1
0
def unpack(packet):
    """Unpack the OpenFlow Packet and returns a message.

    Returns:
        GenericMessage: Message unpacked based on openflow packet.

    Raises:
        UnpackException: if the packet can't be unpacked.

    """
    validate_packet(packet)

    version = packet[0]
    try:
        pyof_lib = PYOF_VERSION_LIBS[version]
    except KeyError:
        raise UnpackException('Version not supported')

    try:
        header = pyof_lib.common.header.Header()
        header.unpack(packet[:header.get_size()])
        message = pyof_lib.common.utils.new_message_from_header(header)

        binary_data = packet[header.get_size():]
        binary_data_size = header.length - header.get_size()

        if binary_data and len(binary_data) == binary_data_size:
            message.unpack(binary_data)
        return message
    except (UnpackException, ValueError) as exception:
        raise UnpackException(exception)
Ejemplo n.º 2
0
def unpack(packet):
    """Unpack the OpenFlow Packet and returns a message.

    Args:
        packet: buffer with the openflow packet.

    Returns:
        GenericMessage: Message unpacked based on openflow packet.

    Raises:
        UnpackException: if the packet can't be unpacked.

    """
    validate_packet(packet)

    version = packet[0]
    try:
        pyof_lib = PYOF_VERSION_LIBS[version]
    except KeyError:
        raise UnpackException('Version not supported')

    try:
        message = pyof_lib.common.utils.unpack_message(packet)
        return message
    except (UnpackException, ValueError) as exception:
        raise UnpackException(exception)
Ejemplo n.º 3
0
def unpack(packet):
    """Unpacks the OpenFlow packet and returns a message."""
    version = _unpack_int(packet[0])
    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:
            message.unpack(binary_data)
        return message
    except (UnpackException, ValueError) as e:
        log.info('Could not unpack message: %s', packet)
        raise UnpackException(e)
Ejemplo n.º 4
0
def validate_packet(packet):
    """Check if packet is valid OF packet.

    Raises:
        UnpackException: If the packet is invalid.

    """
    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')
Ejemplo n.º 5
0
 def _unpack_attribute(self, name, obj, buff, begin):
     attribute = deepcopy(obj)
     setattr(self, name, attribute)
     if not buff:
         size = 0
     else:
         try:
             attribute.unpack(buff, begin)
             size = attribute.get_size()
         except UnpackException as exception:
             child_cls = type(self).__name__
             msg = '{}.{}; {}'.format(child_cls, name, exception)
             raise UnpackException(msg)
     return size
Ejemplo n.º 6
0
    def unpack(self, buff, offset=0):
        """Unpack a binary struct into this object's attributes.

        Return the values instead of the lib's basic types.
        Check if the protocols involved are Ethernet and IPv4. Other protocols
        are currently not supported.

        Args:
            buff (bytes): Binary buffer.
            offset (int): Where to begin unpacking.

        Raises:
            :exc:`~.exceptions.UnpackException`: If unpack fails.

        """
        super().unpack(buff, offset)
        if not self.is_valid():
            raise UnpackException("Unsupported protocols in ARP packet")
Ejemplo n.º 7
0
    def unpack(self, buff, offset=0):
        """Unpack *buff* into this object.

        This method will convert a binary data into a readable value according
        to the attribute format.

        Args:
            buff (bytes): Binary buffer.
            offset (int): Where to begin unpacking.

        Raises:
            :exc:`~.exceptions.UnpackException`: If unpack fails.
        """
        try:
            self._value = struct.unpack_from(self._fmt, buff, offset)[0]
            if self.enum_ref:
                self._value = self.enum_ref(self._value)
        except (struct.error, TypeError, ValueError) as e:
            msg = '{}; fmt = {}, buff = {}, offset = {}.'.format(
                e, self._fmt, buff, offset)
            raise UnpackException(msg)
Ejemplo n.º 8
0
    def unpack(self, buff, offset=0):
        """Unpack the buffer into a OxmTLV.

        Args:
            buff (bytes): The binary data to be unpacked.
            offset (int): If we need to shift the beginning of the data.

        """
        super().unpack(buff, offset)
        # Recover field from field_and_hasmask.
        try:
            self.oxm_field = self._unpack_oxm_field()
        except ValueError as exception:
            raise UnpackException(exception)

        # The last bit of field_and_mask is oxm_hasmask
        self.oxm_hasmask = (self.oxm_field_and_mask & 1) == 1  # as boolean

        # Unpack oxm_value that has oxm_length bytes
        start = offset + 4  # 4 bytes: class, field_and_mask and length
        end = start + self.oxm_length
        self.oxm_value = buff[start:end]