def test_query_messed_up_prefix(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message ia_na_option = bundle.response.get_option_of_type(IANAOption) ia_address = ia_na_option.get_option_of_type(IAAddressOption) query = LQQueryOption(QUERY_BY_ADDRESS, options=[ia_address]) # Messed-up data, a log message should appear with TemporaryDirectory() as tmp_dir_name: store = LeasequerySqliteStore(os.path.join(tmp_dir_name, 'lq.sqlite')) store.worker_init([]) store.remember_lease(bundle) # Mess up the data in our poor database db = sqlite3.connect(store.sqlite_filename) db.row_factory = sqlite3.Row db.execute("UPDATE prefixes SET first_address='2001:0db8:0000:0000:0000:0000:0000:0000'") db.commit() with self.assertLogs('', 'NOTSET')as cm: nr_found, results = store.find_leases(query) results = list(results) self.assertEqual(nr_found, 1) self.assertEqual(len(results), 1) self.assertEqual(len(cm.output), 1) self.assertRegex(cm.output[0], 'Ignoring invalid prefix range')
def test_query_by_unspecified_link_address(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message query = LQQueryOption(QUERY_BY_LINK_ADDRESS, link_address=IPv6Address('::')) self.query(bundle, query)
def setUp(self): self.packet_fixture = bytes.fromhex( '0e' # Message type Leasequery 'e86f0c' # Transaction ID '0001' # Option type 1: OPTION_CLIENT_ID '000a' # Option length: 10 '0003' # DUID type: DUID_LL '0001' # Hardware type: Ethernet '001ee6f77d00' # MAC Address '002c' # Option type 44: OPTION_LQ_QUERY '0017' # Option length: 23 '01' # Query type: QUERY_BY_ADDRESS 'fe800000000000000000000000000001' # Link address: fe80::1 '0006' # Option type: OPTION_ORO '0002' # Option length: 2 '002f' # Requested option: OPTION_LQ_RELAY_DATA ) self.message_fixture = LeasequeryMessage( transaction_id=bytes.fromhex('e86f0c'), options=[ ClientIdOption(duid=LinkLayerDUID( hardware_type=1, link_layer_address=bytes.fromhex('001ee6f77d00'))), LQQueryOption( query_type=QUERY_BY_ADDRESS, link_address=IPv6Address('fe80::1'), options=[ OptionRequestOption( requested_options=[OPTION_LQ_RELAY_DATA]), ]), ]) self.parse_packet()
def test_query_by_unknown(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message query = LQQueryOption(-1) # No valid query provided, no data self.query_empty(bundle, query, invalid=True)
def test_query_by_address_malformed(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message query = LQQueryOption(QUERY_BY_ADDRESS) with self.assertRaisesRegex(ReplyWithLeasequeryError, 'Address queries must contain an address'): self.query(bundle, query)
def test_query_by_remote_id_malformed(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message query = LQQueryOption(QUERY_BY_REMOTE_ID) with self.assertRaisesRegex(ReplyWithLeasequeryError, 'Remote-ID queries must contain a remote ID'): self.query(bundle, query)
def create_link_address_query(options) -> LQQueryOption: """ Create query option for link-address query. :param options: Options from the main argument parser :return: The Leasequery """ return LQQueryOption(QUERY_BY_LINK_ADDRESS, options.link_address)
def create_relay_id_query(options) -> LQQueryOption: """ Create query option for relay-id query. :param options: Options from the main argument parser :return: The Leasequery """ return LQQueryOption(QUERY_BY_RELAY_ID, options.link_address, [RelayIdOption(parse_duid(options.duid))])
def create_client_id_query(options) -> LQQueryOption: """ Create query option for client-id query. :param options: Options from the main argument parser :return: The Leasequery """ return LQQueryOption(QUERY_BY_CLIENT_ID, options.link_address, [ClientIdOption(parse_duid(options.duid))])
def create_client_address_query(options) -> LQQueryOption: """ Create query option for address query. :param options: Options from the main argument parser :return: The Leasequery """ return LQQueryOption(QUERY_BY_ADDRESS, options.link_address, [IAAddressOption(options.address)])
def test_query_by_client_id_on_wrong_link(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message client_id_option = bundle.response.get_option_of_type(ClientIdOption) query = LQQueryOption(QUERY_BY_CLIENT_ID, link_address=IPv6Address('3ffe::'), options=[client_id_option]) self.query_empty(bundle, query)
def test_query_by_relay_id_on_link(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message relay_id_option = bundle.incoming_relay_messages[-1].get_option_of_type(RelayIdOption) query = LQQueryOption(QUERY_BY_RELAY_ID, link_address=bundle.link_address, options=[relay_id_option]) self.query(bundle, query)
def test_query_by_address_with_extra_data(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message ia_na_option = bundle.response.get_option_of_type(IANAOption) ia_address = ia_na_option.get_option_of_type(IAAddressOption) query = LQQueryOption(QUERY_BY_ADDRESS, options=[ia_address, OptionRequestOption([OPTION_DNS_SERVERS])]) self.query(bundle, query, [RecursiveNameServersOption])
def test_query_by_address_with_relay_data(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message ia_na_option = bundle.response.get_option_of_type(IANAOption) ia_address = ia_na_option.get_option_of_type(IAAddressOption) query = LQQueryOption(QUERY_BY_ADDRESS, options=[ia_address, OptionRequestOption([OPTION_LQ_RELAY_DATA])]) self.query(bundle, query, [LQRelayDataOption])
def test_query_by_address_on_wrong_link(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message ia_na_option = bundle.response.get_option_of_type(IANAOption) ia_address = ia_na_option.get_option_of_type(IAAddressOption) query = LQQueryOption(QUERY_BY_ADDRESS, link_address=IPv6Address('3ffe::'), options=[ia_address]) self.query_empty(bundle, query)
def test_query_by_remote_id_on_wrong_link(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message # Test every remote-id for relay_message in bundle.incoming_relay_messages: for option in relay_message.get_options_of_type(RemoteIdOption): with self.subTest(msg="{}:{}".format(option.enterprise_number, normalise_hex(option.remote_id))): query = LQQueryOption(QUERY_BY_REMOTE_ID, link_address=IPv6Address('3ffe::'), options=[option]) self.query_empty(bundle, query)
def create_remote_id_query(options) -> LQQueryOption: """ Create query option for remote-id query. :param options: Options from the main argument parser :return: The Leasequery """ return LQQueryOption(QUERY_BY_REMOTE_ID, options.link_address, [ RemoteIdOption(int(options.enterprise_nr), bytes.fromhex(options.remote_id)) ])
def test_query_by_relay_id_on_wrong_link(self): bundle = TransactionBundle(self.relayed_solicit_message, received_over_multicast=False) bundle.response = reply_message client_id_option = bundle.response.get_option_of_type(ClientIdOption) query = LQQueryOption(QUERY_BY_RELAY_ID, link_address=IPv6Address('3ffe::'), options=[RelayIdOption(duid=client_id_option.duid)]) # Our test data doesn't have a relay-id, so no results expected self.query_empty(bundle, query)
def setUp(self): self.option_bytes = bytes.fromhex( '002c' # Option type 44: OPTION_LQ_QUERY '0017' # Option length: 23 '01' # Query type: QUERY_BY_ADDRESS 'fe800000000000000000000000000001' # Link address: fe80::1 '0006' # Option type: OPTION_ORO '0002' # Option length: 2 '002f' # Requested option: OPTION_LQ_RELAY_DATA ) self.option_object = LQQueryOption( query_type=QUERY_BY_ADDRESS, link_address=IPv6Address('fe80::1'), options=[ OptionRequestOption(requested_options=[OPTION_LQ_RELAY_DATA]), ]) self.parse_option()
def test_parse_wrong_type(self): with self.assertRaisesRegex(ValueError, 'does not contain LQQueryOption data'): option = LQQueryOption() option.load_from(b'00020010ff12000000000000000000000000abcd')