コード例 #1
0
    def test_one_participant(self):
        """
        Test a simple protocol with
        preamble, sync and length field (8 bit) and some random data

        :return:
        """
        mb = MessageTypeBuilder("simple_address_test")
        mb.add_label(FieldType.Function.PREAMBLE, 8)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 16)

        num_messages_by_data_length = {8: 5, 16: 10, 32: 15}
        pg = ProtocolGenerator([mb.message_type],
                               syncs_by_mt={mb.message_type: "0x9a9d"},
                               participants=[self.alice])
        for data_length, num_messages in num_messages_by_data_length.items():
            for i in range(num_messages):
                pg.generate_message(data=pg.decimal_to_bits(
                    22 * i, data_length),
                                    source=self.alice)

        #self.save_protocol("address_one_participant", pg)

        self.clear_message_types(pg.protocol.messages)
        ff = FormatFinder(pg.protocol.messages)

        address_engine = AddressEngine(ff.hexvectors, ff.participant_indices)
        address_dict = address_engine.find_addresses()

        self.assertEqual(len(address_dict), 0)
コード例 #2
0
    def test_sync_word_finding_common_prefix(self):
        """
        Messages are very similar (odd and even ones are the same)
        However, they do not have two different sync words!
        The algorithm needs to check for a common prefix of the two found sync words

        :return:
        """
        sync = "0x1337"
        num_messages = 10

        alice = Participant("Alice", address_hex="dead01")
        bob = Participant("Bob", address_hex="beef24")

        mb = MessageTypeBuilder("protocol_with_one_message_type")
        mb.add_label(FieldType.Function.PREAMBLE, 72)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 24)
        mb.add_label(FieldType.Function.DST_ADDRESS, 24)
        mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 16)

        pg = ProtocolGenerator([mb.message_type],
                               syncs_by_mt={mb.message_type: "0x1337"},
                               preambles_by_mt={mb.message_type: "10" * 36},
                               participants=[alice, bob])

        random.seed(0)
        for i in range(num_messages):
            if i % 2 == 0:
                source, destination = alice, bob
                data_length = 8
            else:
                source, destination = bob, alice
                data_length = 16
            pg.generate_message(data=pg.decimal_to_bits(
                random.randint(0, 2**(data_length - 1)), data_length),
                                source=source,
                                destination=destination)

        preprocessor = Preprocessor([
            np.array(msg.plain_bits, dtype=np.uint8)
            for msg in pg.protocol.messages
        ])
        possible_syncs = preprocessor.find_possible_syncs()
        #self.save_protocol("sync_by_common_prefix", pg)
        self.assertEqual(len(possible_syncs), 1)

        # +0000 is okay, because this will get fixed by correction in FormatFinder
        self.assertIn(possible_syncs[0], [
            ProtocolGenerator.to_bits(sync),
            ProtocolGenerator.to_bits(sync) + "0000"
        ])
コード例 #3
0
    def test_medium_protocol(self):
        """
        Protocol with two message types. Length field only present in one of them

        :return:
        """
        mb1 = MessageTypeBuilder("data")
        mb1.add_label(FieldType.Function.PREAMBLE, 8)
        mb1.add_label(FieldType.Function.SYNC, 8)
        mb1.add_label(FieldType.Function.LENGTH, 8)
        mb1.add_label(FieldType.Function.SEQUENCE_NUMBER, 8)

        mb2 = MessageTypeBuilder("ack")
        mb2.add_label(FieldType.Function.PREAMBLE, 8)
        mb2.add_label(FieldType.Function.SYNC, 8)

        pg = ProtocolGenerator([mb1.message_type, mb2.message_type],
                               syncs_by_mt={
                                   mb1.message_type: "11110011",
                                   mb2.message_type: "11110011"
                               })
        num_messages_by_data_length = {8: 5, 16: 10, 32: 5}
        for data_length, num_messages in num_messages_by_data_length.items():
            for i in range(num_messages):
                pg.generate_message(data=pg.decimal_to_bits(
                    10 * i, data_length),
                                    message_type=mb1.message_type)
                pg.generate_message(message_type=mb2.message_type, data="0xaf")

        #self.save_protocol("medium_length", pg)

        self.clear_message_types(pg.protocol.messages)
        ff = FormatFinder(pg.protocol.messages)

        ff.perform_iteration()
        self.assertEqual(len(ff.message_types), 2)
        length_mt = next(mt for mt in ff.message_types
                         if mt.get_first_label_with_type(
                             FieldType.Function.LENGTH) is not None)
        length_label = length_mt.get_first_label_with_type(
            FieldType.Function.LENGTH)

        for i, sync_end in enumerate(ff.sync_ends):
            self.assertEqual(sync_end, 16, msg=str(i))

        self.assertEqual(16, length_label.start)
        self.assertEqual(8, length_label.length)
コード例 #4
0
    def __prepare_example_protocol(self) -> ProtocolAnalyzer:
        alice = Participant("Alice", "A", address_hex="1234")
        bob = Participant("Bob", "B", address_hex="cafe")

        mb = MessageTypeBuilder("data")
        mb.add_label(FieldType.Function.PREAMBLE, 8)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.TYPE, 8)
        mb.add_label(FieldType.Function.DST_ADDRESS, 16)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 16)
        mb_ack = MessageTypeBuilder("ack")
        mb_ack.add_label(FieldType.Function.PREAMBLE, 8)
        mb_ack.add_label(FieldType.Function.SYNC, 16)
        mb_ack.add_label(FieldType.Function.LENGTH, 8)
        mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16)

        num_messages = 50

        pg = ProtocolGenerator([mb.message_type, mb_ack.message_type],
                               syncs_by_mt={
                                   mb.message_type: "0x6768",
                                   mb_ack.message_type: "0x6768"
                               },
                               participants=[alice, bob])

        random.seed(0)
        for i in range(num_messages):
            if i % 2 == 0:
                source, destination = alice, bob
                data_length = 8
            else:
                source, destination = bob, alice
                data_length = 16
            pg.generate_message(data=pg.decimal_to_bits(
                random.randint(0, 2**(data_length - 1)), data_length),
                                source=source,
                                destination=destination)
            pg.generate_message(data="",
                                message_type=mb_ack.message_type,
                                destination=source,
                                source=destination)

        #self.save_protocol("labeled_protocol", pg)

        return pg.protocol
コード例 #5
0
    def build_protocol_generator(preamble_syncs: list, num_messages: tuple,
                                 data: tuple) -> ProtocolGenerator:
        message_types = []
        preambles_by_mt = dict()
        syncs_by_mt = dict()

        assert len(preamble_syncs) == len(num_messages) == len(data)

        for i, (preamble, sync_word) in enumerate(preamble_syncs):
            assert isinstance(preamble, str)
            assert isinstance(sync_word, str)

            preamble, sync_word = map(ProtocolGenerator.to_bits,
                                      (preamble, sync_word))

            mb = MessageTypeBuilder("message type #{0}".format(i))
            mb.add_label(FieldType.Function.PREAMBLE, len(preamble))
            mb.add_label(FieldType.Function.SYNC, len(sync_word))

            message_types.append(mb.message_type)
            preambles_by_mt[mb.message_type] = preamble
            syncs_by_mt[mb.message_type] = sync_word

        pg = ProtocolGenerator(message_types,
                               preambles_by_mt=preambles_by_mt,
                               syncs_by_mt=syncs_by_mt)
        for i, msg_type in enumerate(message_types):
            for j in range(num_messages[i]):
                if callable(data[i]):
                    msg_data = pg.decimal_to_bits(data[i](j), num_bits=8)
                else:
                    msg_data = data[i]

                pg.generate_message(message_type=msg_type, data=msg_data)

        return pg
コード例 #6
0
    def test_two_participants(self):
        mb = MessageTypeBuilder("address_two_participants")
        mb.add_label(FieldType.Function.PREAMBLE, 8)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 16)
        mb.add_label(FieldType.Function.DST_ADDRESS, 16)

        num_messages = 50

        pg = ProtocolGenerator([mb.message_type],
                               syncs_by_mt={mb.message_type: "0x9a9d"},
                               participants=[self.alice, self.bob])

        for i in range(num_messages):
            if i % 2 == 0:
                source, destination = self.alice, self.bob
                data_length = 8
            else:
                source, destination = self.bob, self.alice
                data_length = 16
            pg.generate_message(data=pg.decimal_to_bits(4 * i, data_length),
                                source=source,
                                destination=destination)

        #self.save_protocol("address_two_participants", pg)

        self.clear_message_types(pg.protocol.messages)
        ff = FormatFinder(pg.protocol.messages)

        address_engine = AddressEngine(ff.hexvectors, ff.participant_indices)
        address_dict = address_engine.find_addresses()
        self.assertEqual(len(address_dict), 2)
        addresses_1 = list(
            map(util.convert_numbers_to_hex_string, address_dict[0]))
        addresses_2 = list(
            map(util.convert_numbers_to_hex_string, address_dict[1]))
        self.assertIn(self.alice.address_hex, addresses_1)
        self.assertIn(self.alice.address_hex, addresses_2)
        self.assertIn(self.bob.address_hex, addresses_1)
        self.assertIn(self.bob.address_hex, addresses_2)

        ff.known_participant_addresses.clear()
        self.assertEqual(len(ff.known_participant_addresses), 0)

        ff.perform_iteration()

        self.assertEqual(len(ff.known_participant_addresses), 2)
        self.assertIn(bytes([int(h, 16) for h in self.alice.address_hex]),
                      map(bytes, ff.known_participant_addresses.values()))
        self.assertIn(bytes([int(h, 16) for h in self.bob.address_hex]),
                      map(bytes, ff.known_participant_addresses.values()))

        self.assertEqual(len(ff.message_types), 1)
        mt = ff.message_types[0]
        dst_addr = mt.get_first_label_with_type(FieldType.Function.DST_ADDRESS)
        self.assertIsNotNone(dst_addr)
        self.assertEqual(dst_addr.start, 32)
        self.assertEqual(dst_addr.length, 16)
        src_addr = mt.get_first_label_with_type(FieldType.Function.SRC_ADDRESS)
        self.assertIsNotNone(src_addr)
        self.assertEqual(src_addr.start, 48)
        self.assertEqual(src_addr.length, 16)