def from_bytes(cls, bitstream):
        '''
        Parse the given packet and update properties accordingly
        '''
        packet = cls()

        # Convert to ConstBitStream (if not already provided)
        if not isinstance(bitstream, ConstBitStream):
            if isinstance(bitstream, Bits):
                bitstream = ConstBitStream(auto=bitstream)
            else:
                bitstream = ConstBitStream(bytes=bitstream)

        # Read the type
        type_nr = bitstream.read('uint:4')
        if type_nr != packet.message_type:
            msg = 'Invalid bitstream for a {0} packet'
            class_name = packet.__class__.__name__
            raise ValueError(msg.format(class_name))

        # Read the flags
        (packet.probe,
         packet.enlra_enabled,
         packet.security) = bitstream.readlist('3*bool')

        # Skip reserved bits
        packet._reserved1 = bitstream.read(17)

        # Store the record count until we need it
        record_count = bitstream.read('uint:8')

        # Read the nonce
        packet.nonce = bitstream.read('bytes:8')

        # Read the records
        for dummy in range(record_count):
            record = MapReplyRecord.from_bytes(bitstream)
            packet.records.append(record)

        # If the security flag is set then there should be security data left
        # TODO: deal with security flag [LISP-Security]
        if packet.security:
            raise NotImplementedError('Handling security data is not ' +
                                      'implemented yet')

        # Verify that the properties make sense
        packet.sanitize()

        return packet