r'''
        Parse the given packet and update properties accordingly

        >>> data_hex = ('13000001ae92b5574f849cd00001ac10'
        ...             '1f0300015cfe1cbd00200001ac101f01')
        >>> data = data_hex.decode('hex')
        >>> message = ControlMessage.from_bytes(data)
        >>> message.message_type
        1
        >>> message.authoritative
        False
        >>> message.probe
        True
        >>> message.smr
        True
        >>> message.pitr
        False
        >>> message.smr_invoked
        False
        >>> message.nonce
        '\xae\x92\xb5WO\x84\x9c\xd0'
        >>> message.source_eid
        IPv4Address(u'172.16.31.3')
        >>> message.itr_rlocs
        [IPv4Address(u'92.254.28.189')]
        >>> message.eid_prefixes
        [IPv4Network(u'172.16.31.1/32')]
        >>> message.map_reply

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

        >>> data_hex = ('13000001ae92b5574f849cd00001ac10'
        ...             '1f0300015cfe1cbd00200001ac101f01')
        >>> data = data_hex.decode('hex')
        >>> message = ControlMessage.from_bytes(data)
        >>> message.message_type
        1
        >>> message.authoritative
        False
        >>> message.probe
        True
        >>> message.smr
        True
        >>> message.pitr
        False
        >>> message.smr_invoked
        False
        >>> message.nonce
        '\xae\x92\xb5WO\x84\x9c\xd0'
        >>> message.source_eid
        IPv4Address(u'172.16.31.3')
        >>> message.itr_rlocs
        [IPv4Address(u'92.254.28.189')]
        >>> message.eid_prefixes
        [IPv4Network(u'172.16.31.1/32')]
        >>> message.map_reply
        '''
        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 message 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.authoritative,
         map_data_present,
         packet.probe,
         packet.smr,
         packet.pitr,
         packet.smr_invoked) = bitstream.readlist('6*bool')

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

        # Save the IRC until we reach the actual data
        irc = bitstream.read('uint:5')

        # Save the record count until we reach the actual data
        record_count = bitstream.read('uint:8')

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

        # Read the source EID
        packet.source_eid = read_afi_address_from_bitstream(bitstream)

        # Read the ITR RLOCs
        for dummy in range(irc + 1):
            itr_rloc = read_afi_address_from_bitstream(bitstream)
            packet.itr_rlocs.append(itr_rloc)

        # Read the EIDs
        for dummy in range(record_count):
            # A records begins with 8 reserved bits: skip
            bitstream.read(8)

            # Read 8 bits for the prefix length
            prefix_len = bitstream.read('uint:8')

            # Then an AFI style prefix
            eid_prefix = read_afi_address_from_bitstream(bitstream, prefix_len)
            packet.eid_prefixes.append(eid_prefix)

        # Read the map-reply record if present
        if map_data_present:
            packet.map_reply = MapReplyRecord.from_bytes(bitstream)

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

        return packet