def test_user_check_IA_NA_with_registry_unknown_user_logging(): # With a user registry and multiple subnets # an unknown user should get last subnet misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('libdhcp_user_chk.so') srv_control.configure_loggers('kea-dhcp4.callouts', 'DEBUG', 99) srv_control.configure_loggers('kea-dhcp4.hooks', 'INFO', 'None') srv_control.build_and_send_config_files() srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option(1) srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:01') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', 'OFFER') srv_msg.response_check_include_option(1) srv_msg.response_check_content('yiaddr', '10.0.0.5') srv_msg.response_check_option_content(1, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_1.txt') srv_msg.log_contains(r'INFO \[kea-dhcp4.hooks') srv_msg.log_contains(r'DEBUG \[kea-dhcp4.callouts')
def test_user_check_hook_IA_NA_with_registry_known_user(): # With a user registry and multiple subnets # an known user should get first subnet misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv6/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::5') srv_control.config_srv_another_subnet_no_interface('1000::/64', '1000::5-1000::5') srv_control.add_hooks('libdhcp_user_chk.so') srv_control.build_and_send_config_files() srv_control.start_srv('DHCP', 'started') misc.test_procedure() # Send a query from a registered user srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:11:02:03:04:05:06') srv_msg.client_does_include('Client', 'client-id') srv_msg.client_does_include('Client', 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', 'ADVERTISE') srv_msg.response_check_include_option(3) srv_msg.response_check_option_content(3, 'sub-option', 5) srv_msg.response_check_suboption_content(5, 3, 'addr', '3000::5') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv6/kea_only/user_chk/outcome_2.txt')
def test_user_check_hook_IA_NA_with_registry_known_user(): # With a user registry and multiple subnets # an known user should get first subnet misc.test_setup() srv_msg.send_file_to_server('tests/dhcpv6/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::5') srv_control.config_srv_another_subnet_no_interface('1000::/64', '1000::5-1000::5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() # Send a query from a registered user srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:11:02:03:04:05:06') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') srv_msg.response_check_suboption_content('Response', '5', '3', None, 'addr', '3000::5') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv6/kea_only/user_chk/outcome_2.txt')
def test_user_check_IA_NA_with_registry_known_user(): # With a user registry and multiple subnets # an known user should get first subnet misc.test_setup() srv_msg.send_file_to_server('tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option('1') srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:04') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'OFFER') srv_msg.response_check_include_option('Response', None, '1') srv_msg.response_check_content('Response', None, 'yiaddr', '192.168.50.5') srv_msg.response_check_option_content('Response', '1', None, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_2.txt')
def test_user_check_IA_NA_with_registry_known_user(): # With a user registry and multiple subnets # an known user should get first subnet misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('libdhcp_user_chk.so') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option('1') srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:04') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'OFFER') srv_msg.response_check_include_option('Response', None, '1') srv_msg.response_check_content('Response', None, 'yiaddr', '192.168.50.5') srv_msg.response_check_option_content('Response', '1', None, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_2.txt')
def test_user_check_IA_NA_with_registry_unknown_user_logging_2(): # With a user registry and multiple subnets # an unknown user should get last subnet misc.test_setup() srv_msg.send_file_to_server('tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') # Server logging system is configured with logger type kea-dhcp4.callouts, severity DEBUG, severity level 99 and log file kea.log. # Server logging system is configured with logger type kea-dhcp4.hooks, severity INFO, severity level None and log file kea.log. srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option('1') srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:01') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'OFFER') srv_msg.response_check_include_option('Response', None, '1') srv_msg.response_check_content('Response', None, 'yiaddr', '10.0.0.5') srv_msg.response_check_option_content('Response', '1', None, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_1.txt') # File stored in $(SOFTWARE_INSTALL_DIR)/var/kea/kea.log MUST contain line or phrase: INFO \[kea-dhcp4.hooks # File stored in $(SOFTWARE_INSTALL_DIR)/var/kea/kea.log MUST contain line or phrase: DEBUG \[kea-dhcp4.callouts misc.test_setup() srv_msg.send_file_to_server('tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') # Server logging system is configured with logger type kea-dhcp4.callouts, severity DEBUG, severity level 99 and log file kea.log. # Server logging system is configured with logger type kea-dhcp4.hooks, severity INFO, severity level None and log file kea.log. srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option('1') srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:01') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'OFFER') srv_msg.response_check_include_option('Response', None, '1') srv_msg.response_check_content('Response', None, 'yiaddr', '10.0.0.5') srv_msg.response_check_option_content('Response', '1', None, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_1.txt')
def test_user_check_hook_IA_NA_with_registry_unknown_user_logging(): # With a user registry and multiple subnets # an unknown user should get last subnet misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv6/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::5') srv_control.config_srv_another_subnet_no_interface('1000::/64', '1000::5-1000::5') srv_control.add_hooks('libdhcp_user_chk.so') srv_control.configure_loggers('kea-dhcp6.callouts', 'DEBUG', '99') srv_control.configure_loggers('kea-dhcp6.hooks', 'INFO', 'None') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() # Send a query from an unregistered user srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:ff:ff:ff:ff:ff:01') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA_Address') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') srv_msg.response_check_suboption_content('Response', '5', '3', None, 'addr', '1000::5') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv6/kea_only/user_chk/outcome_1.txt') srv_msg.log_contains(r'INFO \[kea-dhcp6.hooks') srv_msg.log_contains(r'DEBUG \[kea-dhcp6.callouts')
def test_user_check_hook_IA_NA_with_registry_unknown_user_logging_2(): # With a user registry and multiple subnets # an unknown user should get last subnet misc.test_setup() srv_msg.send_file_to_server('tests/dhcpv6/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::5') srv_control.config_srv_another_subnet_no_interface('1000::/64', '1000::5-1000::5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') srv_control.configure_loggers('kea-dhcp6.callouts', 'DEBUG', '99', 'kea.log') srv_control.configure_loggers('kea-dhcp6.hooks', 'DEBUG', '99', 'kea.log') srv_control.build_and_send_config_files('SSH', 'config-file') # DHCP server failed to start. During configuration process. srv_control.start_srv('DHCP', 'started') misc.test_procedure() # Send a query from an unregistered user srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:ff:ff:ff:ff:ff:01') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA_Address') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') srv_msg.response_check_suboption_content('Response', '5', '3', None, 'addr', '1000::5') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv6/kea_only/user_chk/outcome_1.txt') srv_msg.forge_sleep('10', 'seconds') srv_control.start_srv('DHCP', 'stopped') misc.test_setup() srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::5') srv_control.config_srv_another_subnet_no_interface('1000::/64', '1000::5-1000::5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') srv_control.configure_loggers('kea-dhcp6.callouts', 'DEBUG', '99', 'kea.log') srv_control.configure_loggers('kea-dhcp6.hooks', 'INFO', 'None', 'kea.log') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() # Send a query from an unregistered user srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:ff:ff:ff:ff:ff:02') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA_Address') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') srv_msg.response_check_suboption_content('Response', '5', '3', None, 'addr', '1000::5') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt')
def test_user_check_IA_NA_with_registry_unknown_user_logging_2(): # With a user registry and multiple subnets # an unknown user should get last subnet misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('libdhcp_user_chk.so') # Server logging system is configured with logger type kea-dhcp4.callouts, severity DEBUG, severity level 99 and log file kea.log. # Server logging system is configured with logger type kea-dhcp4.hooks, severity INFO, severity level None and log file kea.log. srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option('1') srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:01') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'OFFER') srv_msg.response_check_include_option('Response', None, '1') srv_msg.response_check_content('Response', None, 'yiaddr', '10.0.0.5') srv_msg.response_check_option_content('Response', '1', None, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_1.txt') # File stored in kea.log MUST contain line or phrase: INFO \[kea-dhcp4.hooks # File stored in kea.log MUST contain line or phrase: DEBUG \[kea-dhcp4.callouts misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv4/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.5-192.168.50.5') srv_control.config_srv_another_subnet_no_interface('10.0.0.0/24', '10.0.0.5-10.0.0.5') srv_control.add_hooks('libdhcp_user_chk.so') # Server logging system is configured with logger type kea-dhcp4.callouts, severity DEBUG, severity level 99 and log file kea.log. # Server logging system is configured with logger type kea-dhcp4.hooks, severity INFO, severity level None and log file kea.log. srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') misc.test_procedure() srv_msg.client_requests_option('1') srv_msg.client_sets_value('Client', 'chaddr', '0c:0e:0a:01:ff:01') srv_msg.client_send_msg('DISCOVER') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'OFFER') srv_msg.response_check_include_option('Response', None, '1') srv_msg.response_check_content('Response', None, 'yiaddr', '10.0.0.5') srv_msg.response_check_option_content('Response', '1', None, 'value', '255.255.255.0') # Check the outcome file for correct content srv_msg.copy_remote('/tmp/user_chk_outcome.txt') srv_msg.compare_file('tests/dhcpv4/kea_only/user_chk/outcome_1.txt')
def test_v6_upgrade_mysql_db(): # new db parameters tmp_db_name = "kea_tmp_db" tmp_user_name = "kea_tmp_user" # # make sure that new db does not exists # srv_msg.execute_shell_cmd("mysql -u root -N -B -e \"DROP DATABASE IF EXISTS %s;\"" % tmp_db_name) # create new db without schema srv_control.build_database(db_name=tmp_db_name, db_user=tmp_user_name, init_db=False) # send db dump file srv_msg.remove_file_from_server('/tmp/my_db_v6.sql') srv_msg.send_file_to_server('tests/dhcpv6/db_upgrade/my_db_v6.sql', '/tmp/my_db_v6.sql') # switch interface and username to the one setup is using srv_msg.execute_shell_cmd( "sed -i 's/!serverinterface!/$(SERVER_IFACE)/g' /tmp/my_db_v6.sql") srv_msg.execute_shell_cmd("sed -i 's/!db_user!/%s/g' /tmp/my_db_v6.sql" % tmp_user_name) # recreate db content in new db srv_msg.execute_shell_cmd( "mysql -u%s -p$(DB_PASSWD) %s < /tmp/my_db_v6.sql" % (tmp_user_name, tmp_db_name)) # start kea, which should fail due to mismatch in db version misc.test_setup() srv_control.add_hooks('libdhcp_host_cmds.so') srv_control.add_hooks('libdhcp_lease_cmds.so') srv_control.add_hooks('libdhcp_cb_cmds.so') srv_control.add_hooks('libdhcp_mysql_cb.so') srv_control.open_control_channel() srv_control.agent_control_channel('$(MGMT_ADDRESS)') hosts = { "hosts-databases": [{ "user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "mysql" }] } leases = { "lease-database": { "user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "mysql" } } cb_config = { "config-databases": [{ "user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "mysql" }] } world.dhcp_cfg.update(hosts) world.dhcp_cfg.update(leases) world.dhcp_cfg["config-control"] = cb_config world.dhcp_cfg["server-tag"] = "abc" srv_control.build_and_send_config_files() srv_control.start_srv_during_process('DHCP', 'started') # upgrade with kea admin kea_admin = world.f_cfg.sbin_join('kea-admin') srv_msg.execute_shell_cmd( "sudo %s db-upgrade mysql -u %s -p $(DB_PASSWD) -n %s" % (kea_admin, tmp_user_name, tmp_db_name)) # start kea srv_control.start_srv('DHCP', 'started') # check reservation hr_get = { "subnet-id": 2, "identifier-type": "duid", "identifier": "01:02:03:04:05:06:07:08:09:0A" } resp = _send_cmd("reservation-get", hr_get)["arguments"] assert resp["duid"] == "01:02:03:04:05:06:07:08:09:0a" assert resp["hostname"] == "foo.example.com" assert resp["ip-addresses"] == ["2001:db8:1::1"] assert resp["option-data"] == [{ "always-send": False, "code": 17, "csv-format": True, "data": "4491", "name": "vendor-opts", "space": "dhcp6" }] assert resp["prefixes"] == ["2001:db8:2:abcd::/64"] # check lease lease_get = {"duid": "00:03:00:01:f6:f5:f4:f3:f2:01"} resp = _send_cmd("lease6-get-by-duid", lease_get)["arguments"] assert len(resp["leases"]) == 2 for lease in resp["leases"]: if lease["type"] == "IA_NA": assert lease["duid"] == "00:03:00:01:f6:f5:f4:f3:f2:01" assert lease["hw-address"] == "f6:f5:f4:f3:f2:01" assert lease["iaid"] == 61439 assert lease["ip-address"] == "2001:db8:1::10" assert lease["preferred-lft"] == 3000 assert lease["state"] == 0 assert lease["subnet-id"] == 2 assert lease["valid-lft"] == 1000 if lease["type"] == "IA_PD": assert lease["duid"] == "00:03:00:01:f6:f5:f4:f3:f2:01" assert lease["hw-address"] == "f6:f5:f4:f3:f2:01" assert lease["iaid"] == 24511 assert lease["ip-address"] == "2001:db8:2::" assert lease["preferred-lft"] == 3000 assert lease["prefix-len"] == 91 assert lease["state"] == 0 assert lease["subnet-id"] == 2 assert lease["valid-lft"] == 1000 # check config cmd = dict(command="config-get", arguments={}) cfg = srv_msg.send_ctrl_cmd(cmd, exp_result=0)["arguments"] assert len(cfg["Dhcp6"]["subnet6"]) == 1 assert len(cfg["Dhcp6"]["option-def"]) == 1 assert len(cfg["Dhcp6"]["option-data"]) == 1 assert len(cfg["Dhcp6"]["shared-networks"]) == 1 # let's check subnet and network parameters one by one, it's possible that new # parameters will be added in future and it will trash this test, we are sure that # no new parameters will be added in 1.6.3 schema. resp = _send_cmd("remote-subnet6-get-by-id", {"subnets": [{ "id": 2 }]})["arguments"] assert resp["count"] == 1 subnet = resp["subnets"][0] assert subnet["id"] == 2 assert subnet["metadata"] == {"server-tags": ["abc"]} assert subnet["option-data"] == [{ "always-send": True, "code": 7, "csv-format": True, "data": "123", "name": "preference", "space": "dhcp6" }] assert subnet["pools"][0] == { "option-data": [{ "always-send": True, "code": 7, "csv-format": True, "data": "12", "name": "preference", "space": "dhcp6" }], "pool": "2001:db8:1::10/128" } assert subnet["pd-pools"] == [{ "delegated-len": 91, "option-data": [], "prefix": "2001:db8:2::", "prefix-len": 90 }] assert subnet["rebind-timer"] == 500 assert subnet["renew-timer"] == 200 assert subnet["shared-network-name"] is None assert subnet["subnet"] == "2001:db8:1::/64" assert subnet["valid-lifetime"] == 1000 resp = _send_cmd("remote-network6-get", {"shared-networks": [{ "name": "net1" }]})["arguments"] assert resp["count"] == 1 network = resp["shared-networks"][0] assert network["client-class"] == "abc" assert network["metadata"] == {"server-tags": ["abc"]} assert network["name"] == "net1" assert network["option-data"] == [{ "always-send": True, "code": 7, "csv-format": True, "data": "123", "name": "preference", "space": "dhcp6" }] assert network["rebind-timer"] == 200 assert network["renew-timer"] == 100 assert network["require-client-classes"] == ["XYZ"] assert network["user-context"] == {"some weird network": 55} assert network["valid-lifetime"] == 300 resp = _send_cmd("remote-global-parameter6-get", { "server-tags": ["abc"], "parameters": ["decline-probation-period"] })["arguments"] assert resp["count"] == 1 assert resp["parameters"] == { "decline-probation-period": 123456, "metadata": { "server-tags": ["abc"] } } resp = _send_cmd("remote-option6-global-get", { "server-tags": ["abc"], "options": [{ "code": 21 }] })["arguments"] assert resp["count"] == 1 assert resp["options"][0] == { "always-send": False, "code": 21, "csv-format": True, "data": "isc.example.com", "metadata": { "server-tags": ["abc"] }, "name": "sip-server-dns", "space": "dhcp6" } resp = _send_cmd("remote-option-def6-get", { "server-tags": ["abc"], "option-defs": [{ "code": 222 }] })["arguments"] assert resp["count"] == 1 assert resp["option-defs"][0] == { "array": False, "code": 222, "encapsulate": "", "metadata": { "server-tags": ["abc"] }, "name": "foo", "record-types": "", "space": "dhcp6", "type": "uint32" }
def test_user_check_hook_vendor_options_all(): # Install the requisite user registry file onto the server and then # Configure the server with two subnets. The first subnet will be used # for registeted users, the second for unregistered users. misc.test_setup() srv_msg.send_file_to_server( 'tests/dhcpv6/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::20') srv_control.config_srv_another_subnet_no_interface('1000:1::/64', '1000:1::5-1000:1::5') srv_control.add_hooks('libdhcp_user_chk.so') srv_control.config_srv_opt_space('vendor-4491', 'tftp-servers', '7000::1') srv_control.config_srv_opt_space('vendor-4491', 'config-file', 'bootfile.from.server') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') # # Send a query from an unknown user # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:ff:ff:ff:ff:ff:01') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # Options should come from default user in registry srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 9000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.default') # # Send a query from a registered user with no properties # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:11:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # Options should come from server config srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 7000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.server') # # Send a query from a registered user who supplies only bootfile # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:22:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # bootfile should be from user, tftp server from server config srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 7000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.user') # # Send a query from a registered user who supplies only tftp server # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:33:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # bootfile should be from server config, tftp server from user srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 8000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.server') misc.test_procedure() # Send a query from a registered user who supplies both tftp server and bootfile srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:44:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # tftp server and bootfile should be from user srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 8002::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.user-2')
def test_v4_upgrade_pgsql_db(): # new db parameters tmp_db_name = "kea_tmp_db" tmp_user_name = "kea_tmp_user" # create new db without schema srv_control.build_database(db_name=tmp_db_name, db_user=tmp_user_name, init_db=False) # send db dump file srv_msg.remove_file_from_server('/tmp/pg_db_v4.sql') srv_msg.send_file_to_server('tests/dhcpv4/db_upgrade/pg_db_v4.sql', '/tmp/pg_db_v4.sql') # switch username to the one setup is using srv_msg.execute_shell_cmd("sed -i 's/!db_user!/%s/g' /tmp/pg_db_v4.sql" % tmp_user_name) # recreate db content in new db cmd = "sudo -S -u postgres psql -d %s -f/tmp/pg_db_v4.sql" % tmp_db_name fabric_run_command(cmd, ignore_errors=False, destination_host=world.f_cfg.mgmt_address) # start kea, which should fail due to mismatch in db version misc.test_setup() srv_control.config_srv_subnet('192.168.50.0/24', '192.168.50.10-192.168.50.10') srv_control.add_hooks('libdhcp_host_cmds.so') srv_control.add_hooks('libdhcp_lease_cmds.so') srv_control.open_control_channel() srv_control.agent_control_channel('$(MGMT_ADDRESS)') hosts = {"hosts-databases": [{"user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "postgresql"}]} leases = {"lease-database": {"user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "postgresql"}} world.dhcp_cfg.update(hosts) world.dhcp_cfg.update(leases) srv_control.build_and_send_config_files() srv_control.start_srv_during_process('DHCP', 'started') # upgrade database kea_admin = world.f_cfg.sbin_join('kea-admin') srv_msg.execute_shell_cmd("sudo %s db-upgrade pgsql -u %s -p $(DB_PASSWD) -n %s" % (kea_admin, tmp_user_name, tmp_db_name)) # start kea srv_control.start_srv('DHCP', 'started') cmd = dict(command="config-get", arguments={}) srv_msg.send_ctrl_cmd(cmd, exp_result=0) # check reservation hr_get = {"subnet-id": 1, "identifier-type": "hw-address", "identifier": "01:0a:0b:0c:0d:0e:0f"} response = _send_cmd("reservation-get", hr_get)["arguments"] assert response["boot-file-name"] == "/dev/null" assert response["client-classes"] == ["special_snowflake", "office"] assert response["hw-address"] == "01:0a:0b:0c:0d:0e:0f" assert response["ip-address"] == "192.168.50.205" assert response["option-data"] == [{"always-send": False, "code": 6, "csv-format": True, "data": "10.1.1.202,10.1.1.203", "name": "domain-name-servers", "space": "dhcp4"}] assert response["server-hostname"] == "hal9000" # check lease lease_get = {"hw-address": "ff:01:02:03:ff:04"} resp = _send_cmd("lease4-get-by-hw-address", lease_get)["arguments"] assert resp["leases"][0]["hw-address"] == "ff:01:02:03:ff:04" assert resp["leases"][0]["ip-address"] == "192.168.50.10" assert resp["leases"][0]["state"] == 0 assert resp["leases"][0]["subnet-id"] == 1 assert resp["leases"][0]["valid-lft"] == 4000
def test_v6_upgrade_pgsql_db(): # new db parameters world.f_cfg.multi_threading_enabled = False tmp_db_name = "kea_tmp_db" tmp_user_name = "kea_tmp_user" # create new db without schema srv_control.build_database(db_name=tmp_db_name, db_user=tmp_user_name, init_db=False) # send db dump file srv_msg.remove_file_from_server('/tmp/pg_db_v6.sql') srv_msg.send_file_to_server('tests/dhcpv6/db_upgrade/pg_db_v6.sql', '/tmp/pg_db_v6.sql') # switch username to the one setup is using srv_msg.execute_shell_cmd("sed -i 's/!db_user!/%s/g' /tmp/pg_db_v6.sql" % tmp_user_name) # recreate db content in new db cmd = "sudo -S -u postgres psql -d %s -f/tmp/pg_db_v6.sql" % tmp_db_name fabric_run_command(cmd, ignore_errors=False, destination_host=world.f_cfg.mgmt_address) # start kea, which should fail due to mismatch in db version misc.test_setup() srv_control.config_srv_subnet('2001:db8:1::/64', '2001:db8:1::10-2001:db8:1::10') srv_control.config_srv_prefix('2001:db8:2::', 0, 90, 96) srv_control.add_hooks('libdhcp_host_cmds.so') srv_control.add_hooks('libdhcp_lease_cmds.so') srv_control.open_control_channel() srv_control.agent_control_channel('$(MGMT_ADDRESS)') hosts = { "hosts-databases": [{ "user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "postgresql" }] } leases = { "lease-database": { "user": tmp_user_name, "password": "******", "name": tmp_db_name, "type": "postgresql" } } world.dhcp_cfg.update(hosts) world.dhcp_cfg.update(leases) srv_control.build_and_send_config_files() srv_control.start_srv_during_process('DHCP', 'started') kea_admin = world.f_cfg.sbin_join('kea-admin') srv_msg.execute_shell_cmd( "sudo %s db-upgrade pgsql -u %s -p $(DB_PASSWD) -n %s" % (kea_admin, tmp_user_name, tmp_db_name)) # start kea srv_control.start_srv('DHCP', 'started') # check reservation hr_get = { "subnet-id": 1, "identifier-type": "duid", "identifier": "01:02:03:04:05:06:07:08:09:0A" } resp = _send_cmd("reservation-get", hr_get)["arguments"] assert resp["duid"] == "01:02:03:04:05:06:07:08:09:0a" assert resp["hostname"] == "foo.example.com" assert resp["ip-addresses"] == ["2001:db8:1::100"] assert resp["option-data"] == [{ "always-send": False, "code": 17, "csv-format": True, "data": "4491", "name": "vendor-opts", "space": "dhcp6" }] assert resp["prefixes"] == ["2001:db8:2:abcd::/64"] # check lease lease_get = {"duid": "00:03:00:01:f6:f5:f4:f3:f2:01"} resp = _send_cmd("lease6-get-by-duid", lease_get)["arguments"] assert len(resp["leases"]) == 2 for lease in resp["leases"]: if lease["type"] == "IA_NA": assert lease["duid"] == "00:03:00:01:f6:f5:f4:f3:f2:01" assert lease["hw-address"] == "f6:f5:f4:f3:f2:01" assert lease["iaid"] == 55701 assert lease["ip-address"] == "2001:db8:1::10" assert lease["preferred-lft"] == 3000 assert lease["state"] == 0 assert lease["subnet-id"] == 1 assert lease["valid-lft"] == 4000 if lease["type"] == "IA_PD": assert lease["duid"] == "00:03:00:01:f6:f5:f4:f3:f2:01" assert lease["hw-address"] == "f6:f5:f4:f3:f2:01" assert lease["iaid"] == 76159 assert lease["ip-address"] == "2001:db8:2::" assert lease["preferred-lft"] == 3000 assert lease["prefix-len"] == 96 assert lease["state"] == 0 assert lease["subnet-id"] == 1 assert lease["valid-lft"] == 4000
def test_user_check_hook_vendor_options_all(): # Install the requisite user registry file onto the server and then # Configure the server with two subnets. The first subnet will be used # for registeted users, the second for unregistered users. misc.test_setup() srv_msg.send_file_to_server('tests/dhcpv6/kea_only/user_chk/registry_1.txt', '/tmp/user_chk_registry.txt') srv_msg.remove_file_from_server('/tmp/user_chk_outcome.txt') srv_control.config_srv_subnet('3000::/64', '3000::5-3000::20') srv_control.config_srv_another_subnet_no_interface('1000:1::/64', '1000:1::5-1000:1::5') srv_control.add_hooks('$(SOFTWARE_INSTALL_DIR)/lib/kea/hooks/libdhcp_user_chk.so') srv_control.config_srv_opt_space('vendor-4491', 'tftp-servers', '7000::1') srv_control.config_srv_opt_space('vendor-4491', 'config-file', 'bootfile.from.server') srv_control.build_and_send_config_files('SSH', 'config-file') srv_control.start_srv('DHCP', 'started') # # Send a query from an unknown user # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:ff:ff:ff:ff:ff:01') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # Options should come from default user in registry srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 9000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.default') # # Send a query from a registered user with no properties # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:11:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # Options should come from server config srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 7000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.server') # # Send a query from a registered user who supplies only bootfile # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:22:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # bootfile should be from user, tftp server from server config srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 7000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.user') # # Send a query from a registered user who supplies only tftp server # misc.test_procedure() srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:33:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # bootfile should be from server config, tftp server from user srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 8000::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.server') misc.test_procedure() # Send a query from a registered user who supplies both tftp server and bootfile srv_msg.client_sets_value('Client', 'DUID', '00:03:00:01:44:02:03:04:05:06') srv_msg.client_sets_value('Client', 'enterprisenum', '4491') srv_msg.client_does_include('Client', None, 'vendor-class') srv_msg.add_vendor_suboption('Client', '1', '32') srv_msg.add_vendor_suboption('Client', '1', '33') srv_msg.client_does_include('Client', None, 'vendor-specific-info') srv_msg.client_does_include('Client', None, 'client-id') srv_msg.client_does_include('Client', None, 'IA-NA') srv_msg.client_send_msg('SOLICIT') misc.pass_criteria() srv_msg.send_wait_for_message('MUST', None, 'ADVERTISE') srv_msg.response_check_include_option('Response', None, '3') srv_msg.response_check_option_content('Response', '3', None, 'sub-option', '5') # We don't really care about the address value # tftp server and bootfile should be from user srv_msg.response_check_include_option('Response', None, '17') srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '32') # Response sub-option 32 from option 17 MUST contain tftp-servers 8002::1. srv_msg.response_check_option_content('Response', '17', None, 'sub-option', '33') srv_msg.response_check_suboption_content('Response', '33', '17', None, 'config-file', 'bootfile.from.user-2')