1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 from autotest_lib.client.common_lib import error 6 from autotest_lib.client.cros import dhcp_handling_rule 7 from autotest_lib.client.cros import dhcp_packet 8 from autotest_lib.client.cros import dhcp_test_base 9 from autotest_lib.client.cros.networking import shill_proxy 10 11 # Length of time the lease from the DHCP server is valid. 12 LEASE_TIME_SECONDS = 60 13 # We'll fill in the subnet and give this address to the client. 14 INTENDED_IP_SUFFIX = '0.0.0.101' 15 # We should be able to complete a DHCP negotiation in this amount of time. 16 DHCP_NEGOTIATION_TIMEOUT_SECONDS = 10 17 18 class network_DhcpVendorEncapsulatedOptions(dhcp_test_base.DhcpTestBase): 19 """Test implemenation of Vendor Enacapsulated Options in DHCP response.""" 20 21 def check_vendor_encapsulated_options(self, option_string): 22 """Check that the ipconfig in the client shows the the vendor options. 23 24 @param option_string string expected value for vendor options. 25 26 """ 27 proxy = shill_proxy.ShillProxy() 28 device = proxy.find_object( 29 'Device', 30 {'Name': self.ethernet_pair.peer_interface_name}) 31 if device is None: 32 raise error.TestFail('Device was not found.') 33 device_properties = device.GetProperties(utf8_strings=True) 34 ipconfig_path = device_properties['IPConfigs'][0] 35 ipconfig = proxy.get_dbus_object('org.chromium.flimflam.IPConfig', 36 ipconfig_path) 37 ipconfig_properties = ipconfig.GetProperties(utf8_strings=True) 38 ipconfig_vendor_encapsulated_options = ''.join(map(chr, 39 ipconfig_properties['VendorEncapsulatedOptions'])) 40 if ipconfig_vendor_encapsulated_options != option_string: 41 raise error.TestFail('Shill vendor encapsulated options %s does ' 42 'not match expected %s.' % 43 (ipconfig_vendor_encapsulated_options, 44 option_string)) 45 46 device_path = shill_proxy.ShillProxy.dbus2primitive(device.object_path) 47 service = proxy.find_object('Service', {'Device': device_path}) 48 tethering = service.GetProperties()['Tethering'] 49 expected_value = 'Confirmed' 50 if tethering != expected_value: 51 raise error.TestFail('Service tethering state %s does ' 52 'not match expected %s.' % 53 (tethering, expected_value)) 54 55 56 def test_body(self): 57 """Main body of the test.""" 58 subnet_mask = self.ethernet_pair.interface_subnet_mask 59 intended_ip = dhcp_test_base.DhcpTestBase.rewrite_ip_suffix( 60 subnet_mask, 61 self.server_ip, 62 INTENDED_IP_SUFFIX) 63 # Two real name servers, and a bogus one to be unpredictable. 64 dns_servers = ['8.8.8.8', '8.8.4.4', '192.168.87.88'] 65 vendor_options = 'ANDROID_METERED' 66 # This is the pool of information the server will give out to the client 67 # upon request. 68 dhcp_options = { 69 dhcp_packet.OPTION_SERVER_ID : self.server_ip, 70 dhcp_packet.OPTION_SUBNET_MASK : subnet_mask, 71 dhcp_packet.OPTION_IP_LEASE_TIME : LEASE_TIME_SECONDS, 72 dhcp_packet.OPTION_REQUESTED_IP : intended_ip, 73 dhcp_packet.OPTION_DNS_SERVERS : dns_servers, 74 dhcp_packet.OPTION_VENDOR_ENCAPSULATED_OPTIONS : vendor_options 75 } 76 rules = [ 77 dhcp_handling_rule.DhcpHandlingRule_RespondToDiscovery( 78 intended_ip, self.server_ip, dhcp_options, {}), 79 dhcp_handling_rule.DhcpHandlingRule_RespondToRequest( 80 intended_ip, self.server_ip, dhcp_options, {}) 81 ] 82 rules[-1].is_final_handler = True 83 84 # In some DHCP server implementations, the vendor encapsulated option 85 # is provided in the DHCP response without the client requesting it. 86 for rule in rules: 87 rule.force_reply_options = [ 88 dhcp_packet.OPTION_VENDOR_ENCAPSULATED_OPTIONS ] 89 90 self.server.start_test(rules, DHCP_NEGOTIATION_TIMEOUT_SECONDS) 91 self.server.wait_for_test_to_finish() 92 if not self.server.last_test_passed: 93 raise error.TestFail('Test server didn\'t get all the messages it ' 94 'was told to expect during negotiation.') 95 96 self.wait_for_dhcp_propagation() 97 self.check_vendor_encapsulated_options(vendor_options) 98