Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | // SPDX-License-Identifier: GPL-2.0-or-later /* * efi_selftest_ipconfig * * This unit test covers the IPv4 Config2 Protocol. * */ #include <efi_selftest.h> #include <charset.h> #include <net.h> static struct efi_boot_services *boottime; static struct efi_ip4_config2_protocol *ip4_config2; static const efi_guid_t efi_ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID; /* * Setup unit test. * * Open IPv4 Config2 protocol * * @handle: handle of the loaded image * @systable: system table * Return: EFI_ST_SUCCESS for success */ static int setup(const efi_handle_t handle, const struct efi_system_table *systable) { efi_status_t ret; efi_handle_t *net_handle; efi_uintn_t num_handles; efi_handle_t *handles; boottime = systable->boottime; num_handles = 0; boottime->locate_handle_buffer(BY_PROTOCOL, &efi_ip4_config2_guid, NULL, &num_handles, &handles); if (!num_handles) { efi_st_error("Failed to locate ipv4 config2 protocol\n"); return EFI_ST_FAILURE; } for (net_handle = handles; num_handles--; net_handle++) { ret = boottime->open_protocol(*net_handle, &efi_ip4_config2_guid, (void **)&ip4_config2, 0, 0, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (ret != EFI_SUCCESS || !ip4_config2) continue; break; // Get first handle that supports ipv4 } if (!ip4_config2) { efi_st_error("Failed to open ipv4 config2 protocol\n"); return EFI_ST_FAILURE; } return EFI_ST_SUCCESS; } /* * Execute unit test. * * * Return: EFI_ST_SUCCESS for success */ static int execute(void) { efi_status_t ret; enum efi_ip4_config2_policy policy; efi_uintn_t data_size; struct efi_ip4_config2_manual_address manual_address; struct efi_ip4_config2_manual_address orig_address; u8 netmask[] = {255, 255, 255, 0}; u8 ip[] = {10, 0, 0, 1}; /* Setup may have failed */ if (!ip4_config2) { efi_st_error("Setup failure, cannot proceed with test\n"); return EFI_ST_FAILURE; } /* Set policy to static */ policy = EFI_IP4_CONFIG2_POLICY_STATIC; ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_POLICY, sizeof(policy), (void *)&policy); if (ret != EFI_SUCCESS) { efi_st_error("Failed to set policy\n"); return EFI_ST_FAILURE; } /* Save original ip address and netmask */ data_size = sizeof(manual_address); ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, &data_size, &orig_address); if (ret != EFI_SUCCESS) { efi_st_error("Failed to save original ip address and netmask\n"); return EFI_ST_FAILURE; } /* Set static ip and netmask */ memcpy(&manual_address.address, ip, sizeof(struct efi_ipv4_address)); memcpy(&manual_address.subnet_mask, netmask, sizeof(struct efi_ipv4_address)); ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, sizeof(manual_address), &manual_address); if (ret != EFI_SUCCESS) { efi_st_error("Failed to get ip address and netmask\n"); return EFI_ST_FAILURE; } /* Try to set interface info, this should fail */ ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, 0, NULL); if (ret == EFI_SUCCESS) { efi_st_error("Interface info is read-only\n"); return EFI_ST_FAILURE; } /* Get ip address and netmask and check that they match with the previously set ones */ data_size = sizeof(manual_address); ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, &data_size, &manual_address); if (ret != EFI_SUCCESS) { efi_st_error("Failed to get ip address and netmask\n"); return EFI_ST_FAILURE; } if (memcmp(ip, &manual_address.address, sizeof(struct efi_ipv4_address)) || memcmp(netmask, &manual_address.subnet_mask, sizeof(struct efi_ipv4_address))) { efi_st_error("Ip address mismatch\n"); return EFI_ST_FAILURE; } /* Restore original ip address and netmask */ ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, sizeof(orig_address), &orig_address); if (ret != EFI_SUCCESS) { efi_st_error("Failed to restore original ip address and netmask\n"); return EFI_ST_FAILURE; } efi_st_printf("Efi ipconfig test execute succeeded\n"); return EFI_ST_SUCCESS; } /* * Tear down unit test. * * Return: EFI_ST_SUCCESS for success */ static int teardown(void) { int exit_status = EFI_ST_SUCCESS; return exit_status; } EFI_UNIT_TEST(ipconfig) = { .name = "IPv4 config2 protocol", .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, .setup = setup, .execute = execute, .teardown = teardown, #ifdef CONFIG_SANDBOX /* * Running this test on the sandbox requires setting environment * variable ethact to a network interface connected to a DHCP server and * ethrotate to 'no'. */ .on_request = true, #endif }; |