4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync iSCSI DHCP6 related configuration routines.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Extract the Root Path option and get the required target information from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Boot File Uniform Resource Locator (URL) Option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] RootPath The RootPath string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Length Length of the RootPath option payload.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] ConfigData The iSCSI session configuration data read from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync nonvolatile device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS All required information is extracted from the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RootPath option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The RootPath is not an iSCSI RootPath.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The RootPath is malformatted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiRootPathIdLen = (UINT16) AsciiStrLen (ISCSI_ROOT_PATH_ID);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip the iSCSI RootPath ID "iscsi:".
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Extract SERVERNAME field in the Root Path option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_START_DELIMITER) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fields[RP_FIELD_IDX_SERVERNAME].Str = &TmpStr[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_END_DELIMITER) && (Index < Length)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip ']' and ':'.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fields[RP_FIELD_IDX_SERVERNAME].Len = (UINT8) AsciiStrLen (Fields[RP_FIELD_IDX_SERVERNAME].Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Extract others fields in the Root Path option string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (FieldIndex = 1; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TmpStr[Index] == ISCSI_ROOT_PATH_FIELD_DELIMITER) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the IP address of the target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the protocol type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the port of the iSCSI target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiAsciiStrToLun (Field->Str, ConfigNvData->BootLun);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the target iSCSI Name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (AsciiStrLen (Field->Str) > ISCSI_NAME_MAX_SIZE - 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the iSCSI name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiNormalizeName (Field->Str, AsciiStrLen (Field->Str));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiStrCpy (ConfigNvData->TargetName, Field->Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync instance to intercept events that occurs in the DHCPv6 Information Request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync exchange process.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is used to configure this callback function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context Pointer to the context that is initialized in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the EFI_DHCP6_PROTOCOL.InfoRequest().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet Pointer to Reply packet that has been received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The EFI DHCPv6 Protocol instance is responsible
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for freeing the buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Tell the EFI DHCPv6 Protocol instance to finish
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Information Request exchange process.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY Tell the EFI DHCPv6 Protocol instance to continue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Information Request exchange process.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED Tell the EFI DHCPv6 Protocol instance to abort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the Information Request exchange process.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED Tell the EFI DHCPv6 Protocol instance to finish
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the Information Request exchange process because some
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync request information are not received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = This->Parse (This, Packet, &OptionCount, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = This->Parse (This, Packet, &OptionCount, OptionList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ConfigData = (ISCSI_ATTEMPT_CONFIG_NVDATA *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionList[Index]->OpCode = NTOHS (OptionList[Index]->OpCode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionList[Index]->OpLen = NTOHS (OptionList[Index]->OpLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get DNS server addresses from this reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Primary DNS server address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&ConfigData->PrimaryDns, &OptionList[Index]->Data[0], sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Secondary DNS server address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&ConfigData->SecondaryDns, &OptionList[Index]->Data[16], sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_URL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The server sends this option to inform the client about an URL to a boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get iSCSI root path from Boot File Uniform Resource Locator (URL) Option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parse the DHCP ACK to get the address configuration and DNS information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Image The handle of the driver image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Controller The handle of the controller;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] ConfigData The attempt configuration data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MAPPING DHCP failed to acquire address and other
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The DHCP ACK's DNS option is malformatted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Some unexpected error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There is no sufficient resource to finish the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MEDIA There was a media error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check media status before doing DHCP.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // iSCSI will only request target info from DHCPv6 server.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!ConfigData->SessionConfigData.TargetInfoFromDhcp) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a DHCP6 child instance and get the protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ask the server to reply with DNS and Boot File URL options by info request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All members in EFI_DHCP6_PACKET_OPTION are in network order.