docs: def from_bytes(cls, bitstream, decode_payload=True):
          r'''
          Parse the given packet and update properties accordingly
  
          >>> data_hex = ('c033d3c10000000745c0005835400000'
          ...             'ff06094a254d38204d45d1a30016f597'
          ...             'a1c3c7406718bf1b50180ff0793f0000'
          ...             'b555e59ff5ba6aad33d875c600fd8c1f'
          ...             'c5268078f365ee199179fbd09d09d690'
          ...             '193622a6b70bcbc7bf5f20dda4258801')
          >>> data = data_hex.decode('hex')
          >>> message = DataPacket.from_bytes(data)
          >>> message.echo_nonce_request
          False
          >>> message.nonce
          '3\xd3\xc1'
          >>> message.source_map_version
          >>> message.destination_map_version
          >>> message.lsb
          ... # doctest: +ELLIPSIS
          [True, True, True, False, False, ..., False, False, False, False]
          >>> message.instance_id
          >>> bytes(message.payload)
          ... # doctest: +ELLIPSIS
          'E\xc0\x00X5@\x00\x00\xff\x06\tJ%M8...\xdd\xa4%\x88\x01'
          '''
          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 flags
          (nonce_present,
           lsb_enabled,
           packet.echo_nonce_request,
           map_version_present,
           instance_id_present) = bitstream.readlist('5*bool')
  
          # Skip over reserved bits
          bitstream.read(3)
  
          # Parse nonce or map versions
          if nonce_present:
              # Nonce: yes, versions: no
              packet.nonce = bitstream.read('bytes:3')
              packet.source_map_version = None
              packet.destination_map_version = None
          elif map_version_present:
              # Nonce: no, versions: yes
              packet.nonce = None
              (packet.source_map_version,
               packet.destination_map_version) = bitstream.readlist('2*uint:12')
          else:
              # Nonce: no, versions: no
              packet.nonce = None
              packet.source_map_version = None
              packet.destination_map_version = None
  
              # Skip over the nonce/map-version bits
              bitstream.read(24)
  
          # Parse instance-id
          if instance_id_present:
              packet.instance_id = bitstream.read('uint:24')
  
              # 8 bits remaining for LSB
              lsb_bits = 8
          else:
              # 32 bits remaining for LSB
              lsb_bits = 32
  
          # Parse LSBs
          if lsb_enabled:
              packet.lsb = bitstream.readlist('%d*bool' % lsb_bits)
  
              # Reverse for readability: least significant locator-bit first
              packet.lsb.reverse()
          else:
              # Skip over the LSBs
              bitstream.read(lsb_bits)
  
          # The rest of the packet is payload
          remaining = bitstream[bitstream.pos:]
  
          # Parse IP packet
          if len(remaining):
              ip_version = remaining.peek('uint:4')
              if ip_version == 4:
                  packet.payload = IPv4Packet.from_bytes(remaining, decode_payload=decode_payload)
              elif ip_version == 6:
                  packet.payload = IPv6Packet.from_bytes(remaining, decode_payload=decode_payload)
              else:
                  packet.payload = remaining.bytes
  
          # Verify that the properties make sense
          packet.sanitize()
  
          return packet