/** @file
  iSCSI DHCP6 related configuration routines.

Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "IScsiImpl.h"


/**
  Extract the Root Path option and get the required target information from
  Boot File Uniform Resource Locator (URL) Option.

  @param[in]       RootPath      The RootPath string.
  @param[in]       Length        Length of the RootPath option payload.
  @param[in, out]  ConfigData    The iSCSI session configuration data read from
                                 nonvolatile device.

  @retval EFI_SUCCESS            All required information is extracted from the
                                 RootPath option.
  @retval EFI_NOT_FOUND          The RootPath is not an iSCSI RootPath.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval EFI_INVALID_PARAMETER  The RootPath is malformatted.

**/
EFI_STATUS
IScsiDhcp6ExtractRootPath (
  IN     CHAR8                        *RootPath,
  IN     UINT16                       Length,
  IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
  )
{
  EFI_STATUS                  Status;
  UINT16                      IScsiRootPathIdLen;
  CHAR8                       *TmpStr;
  ISCSI_ROOT_PATH_FIELD       Fields[RP_FIELD_IDX_MAX];
  ISCSI_ROOT_PATH_FIELD       *Field;
  UINT32                      FieldIndex;
  UINT8                       Index;
  ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
  EFI_IP_ADDRESS              Ip;
  UINT8                       IpMode;  

  ConfigNvData = &ConfigData->SessionConfigData;
  ConfigNvData->DnsMode = FALSE;
  //
  // "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
  //
  IScsiRootPathIdLen = (UINT16) AsciiStrLen (ISCSI_ROOT_PATH_ID);

  if ((Length <= IScsiRootPathIdLen) ||
      (CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {
    return EFI_NOT_FOUND;
  }
  //
  // Skip the iSCSI RootPath ID "iscsi:".
  //
  RootPath = RootPath + IScsiRootPathIdLen;
  Length   = (UINT16) (Length - IScsiRootPathIdLen);

  TmpStr   = (CHAR8 *) AllocatePool (Length + 1);
  if (TmpStr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (TmpStr, RootPath, Length);
  TmpStr[Length]  = '\0';

  Index           = 0;
  FieldIndex      = 0;
  ZeroMem (&Fields[0], sizeof (Fields));

  //
  // Extract SERVERNAME field in the Root Path option.
  //
  if (TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_START_DELIMITER) {
    //
    // The servername is expressed as domain name.
    //
    ConfigNvData->DnsMode = TRUE;
  } else {
    Index++;
  }

  Fields[RP_FIELD_IDX_SERVERNAME].Str = &TmpStr[Index];

  if (!ConfigNvData->DnsMode) {
    while ((TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_END_DELIMITER)&& (Index < Length)) {
      Index++;
    }

    //
    // Skip ']' and ':'.
    //
    TmpStr[Index] = '\0';
    Index += 2;
  } else {
    while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
      Index++;
    }
    //
    // Skip ':'.
    //
    TmpStr[Index] = '\0';
    Index += 1;
  }

  Fields[RP_FIELD_IDX_SERVERNAME].Len = (UINT8) AsciiStrLen (Fields[RP_FIELD_IDX_SERVERNAME].Str);

  //
  // Extract others fields in the Root Path option string.
  //
  for (FieldIndex = 1; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {

    if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {
      Fields[FieldIndex].Str = &TmpStr[Index];
    }

    while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
      Index++;
    }

    if (TmpStr[Index] == ISCSI_ROOT_PATH_FIELD_DELIMITER) {
      if (FieldIndex != RP_FIELD_IDX_TARGETNAME) {
        TmpStr[Index] = '\0';
        Index++;
      }

      if (Fields[FieldIndex].Str != NULL) {
        Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);
      }
    }
  }

  if (FieldIndex != RP_FIELD_IDX_MAX) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||
      (Fields[RP_FIELD_IDX_TARGETNAME].Str == NULL) ||
      (Fields[RP_FIELD_IDX_PROTOCOL].Len > 1)
      ) {

    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  //
  // Get the IP address of the target.
  //
  Field   = &Fields[RP_FIELD_IDX_SERVERNAME];  
  if (ConfigNvData->IpMode < IP_MODE_AUTOCONFIG) {
    IpMode = ConfigNvData->IpMode;
  } else {
    IpMode = ConfigData->AutoConfigureMode;
  }

  //
  // Server name is expressed as domain name, just save it.
  //
  if (ConfigNvData->DnsMode) {
    if (Field->Len > sizeof (ConfigNvData->TargetUrl)) {
      return EFI_INVALID_PARAMETER;
    }
    CopyMem (&ConfigNvData->TargetUrl, Field->Str, Field->Len);
    ConfigNvData->TargetUrl[Field->Len + 1] = '\0';
  } else {
    ZeroMem(&ConfigNvData->TargetUrl, sizeof (ConfigNvData->TargetUrl));
    Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
    CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Check the protocol type.
  //
  Field = &Fields[RP_FIELD_IDX_PROTOCOL];
  if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  //
  // Get the port of the iSCSI target.
  //
  Field = &Fields[RP_FIELD_IDX_PORT];
  if (Field->Str != NULL) {
    ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);
  } else {
    ConfigNvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
  }
  //
  // Get the LUN.
  //
  Field = &Fields[RP_FIELD_IDX_LUN];
  if (Field->Str != NULL) {
    Status = IScsiAsciiStrToLun (Field->Str, ConfigNvData->BootLun);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  } else {
    ZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));
  }
  //
  // Get the target iSCSI Name.
  //
  Field = &Fields[RP_FIELD_IDX_TARGETNAME];

  if (AsciiStrLen (Field->Str) > ISCSI_NAME_MAX_SIZE - 1) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }
  //
  // Validate the iSCSI name.
  //
  Status = IScsiNormalizeName (Field->Str, AsciiStrLen (Field->Str));
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  AsciiStrCpyS (ConfigNvData->TargetName, ISCSI_NAME_MAX_SIZE, Field->Str);

ON_EXIT:

  FreePool (TmpStr);

  return Status;
}

/**
  EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol 
  instance to intercept events that occurs in the DHCPv6 Information Request
  exchange process.

  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance that 
                                is used to configure this  callback function.
  @param[in]  Context           Pointer to the context that is initialized in
                                the EFI_DHCP6_PROTOCOL.InfoRequest().
  @param[in]  Packet            Pointer to Reply packet that has been received.
                                The EFI DHCPv6 Protocol instance is responsible
                                for freeing the buffer.

  @retval EFI_SUCCESS           Tell the EFI DHCPv6 Protocol instance to finish
                                Information Request exchange process.
  @retval EFI_NOT_READY         Tell the EFI DHCPv6 Protocol instance to continue
                                Information Request exchange process.
  @retval EFI_ABORTED           Tell the EFI DHCPv6 Protocol instance to abort
                                the Information Request exchange process.
  @retval EFI_UNSUPPORTED       Tell the EFI DHCPv6 Protocol instance to finish
                                the Information Request exchange process because some
                                request information are not received.

**/
EFI_STATUS
EFIAPI
IScsiDhcp6ParseReply (
  IN EFI_DHCP6_PROTOCOL          *This,
  IN VOID                        *Context,
  IN EFI_DHCP6_PACKET            *Packet
  )
{
  EFI_STATUS                  Status;
  UINT32                      Index;
  UINT32                      OptionCount;
  EFI_DHCP6_PACKET_OPTION     *BootFileOpt;
  EFI_DHCP6_PACKET_OPTION     **OptionList;
  ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;
  UINT16                      ParaLen;
 
  OptionCount = 0;
  BootFileOpt = NULL;
  
  Status      = This->Parse (This, Packet, &OptionCount, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return EFI_NOT_READY;
  }

  OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *));
  if (OptionList == NULL) {
    return EFI_NOT_READY;
  }

  Status = This->Parse (This, Packet, &OptionCount, OptionList);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_READY;
    goto Exit;
  }

  ConfigData = (ISCSI_ATTEMPT_CONFIG_NVDATA *) Context;

  for (Index = 0; Index < OptionCount; Index++) {
    OptionList[Index]->OpCode = NTOHS (OptionList[Index]->OpCode);
    OptionList[Index]->OpLen  = NTOHS (OptionList[Index]->OpLen);

    //
    // Get DNS server addresses from this reply packet.
    //
    if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {

      if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {
        Status = EFI_UNSUPPORTED;
        goto Exit;
      }
      //
      // Primary DNS server address.
      //
      CopyMem (&ConfigData->PrimaryDns, &OptionList[Index]->Data[0], sizeof (EFI_IPv6_ADDRESS));

      if (OptionList[Index]->OpLen > 16) {
        //
        // Secondary DNS server address
        //
        CopyMem (&ConfigData->SecondaryDns, &OptionList[Index]->Data[16], sizeof (EFI_IPv6_ADDRESS));
      }

    } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_URL) {
      //
      // The server sends this option to inform the client about an URL to a boot file.
      //
      BootFileOpt = OptionList[Index];
    } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_PARAM) {
      //
      // The server sends this option to inform the client about DHCP6 server address.
      //
      if (OptionList[Index]->OpLen < 18) {
        Status = EFI_UNSUPPORTED;
        goto Exit;
      }
      //
      // Check param-len 1, should be 16 bytes.
      //
      CopyMem (&ParaLen, &OptionList[Index]->Data[0], sizeof (UINT16));
      if (NTOHS (ParaLen) != 16) {
        Status = EFI_UNSUPPORTED;
        goto Exit;
      }

      CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[2], sizeof (EFI_IPv6_ADDRESS));
    }
  }

  if (BootFileOpt == NULL) {
    Status = EFI_UNSUPPORTED;
    goto Exit;
  }
  
  //
  // Get iSCSI root path from Boot File Uniform Resource Locator (URL) Option
  //
  Status = IScsiDhcp6ExtractRootPath (
             (CHAR8 *) BootFileOpt->Data,
             BootFileOpt->OpLen,
             ConfigData
             );

Exit:

  FreePool (OptionList);
  return Status;
}


/**
  Parse the DHCP ACK to get the address configuration and DNS information.

  @param[in]       Image         The handle of the driver image.
  @param[in]       Controller    The handle of the controller;
  @param[in, out]  ConfigData    The attempt configuration data.

  @retval EFI_SUCCESS            The DNS information is got from the DHCP ACK.
  @retval EFI_NO_MAPPING         DHCP failed to acquire address and other
                                 information.
  @retval EFI_INVALID_PARAMETER  The DHCP ACK's DNS option is malformatted.
  @retval EFI_DEVICE_ERROR       Some unexpected error occurred.
  @retval EFI_OUT_OF_RESOURCES   There is no sufficient resource to finish the
                                 operation.
  @retval EFI_NO_MEDIA           There was a media error.

**/
EFI_STATUS
IScsiDoDhcp6 (
  IN     EFI_HANDLE                  Image,
  IN     EFI_HANDLE                  Controller,
  IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData
  )
{
  EFI_HANDLE                Dhcp6Handle;
  EFI_DHCP6_PROTOCOL        *Dhcp6;
  EFI_STATUS                Status;
  EFI_STATUS                TimerStatus;
  EFI_DHCP6_PACKET_OPTION   *Oro;
  EFI_DHCP6_RETRANSMISSION  InfoReqReXmit;
  EFI_EVENT                 Timer;
  BOOLEAN                   MediaPresent;

  //
  // Check media status before doing DHCP.
  //
  MediaPresent = TRUE;
  NetLibDetectMedia (Controller, &MediaPresent);
  if (!MediaPresent) {
    return EFI_NO_MEDIA;
  }

  //
  // iSCSI will only request target info from DHCPv6 server.
  //
  if (!ConfigData->SessionConfigData.TargetInfoFromDhcp) {
    return EFI_SUCCESS;
  }

  Dhcp6Handle = NULL;
  Dhcp6       = NULL;
  Oro         = NULL;
  Timer       = NULL;

  //
  // Create a DHCP6 child instance and get the protocol.
  //
  Status = NetLibCreateServiceChild (
             Controller,
             Image,
             &gEfiDhcp6ServiceBindingProtocolGuid,
             &Dhcp6Handle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  Dhcp6Handle,
                  &gEfiDhcp6ProtocolGuid,
                  (VOID **) &Dhcp6,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 5);
  if (Oro == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Ask the server to reply with DNS and Boot File URL options by info request.
  // All members in EFI_DHCP6_PACKET_OPTION are in network order.
  //
  Oro->OpCode  = HTONS (DHCP6_OPT_ORO);
  Oro->OpLen   = HTONS (2 * 3);
  Oro->Data[1] = DHCP6_OPT_DNS_SERVERS;
  Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL;
  Oro->Data[5] = DHCP6_OPT_BOOT_FILE_PARAM;

  InfoReqReXmit.Irt = 4;
  InfoReqReXmit.Mrc = 1;
  InfoReqReXmit.Mrt = 10;
  InfoReqReXmit.Mrd = 30;

  Status = Dhcp6->InfoRequest (
                    Dhcp6,
                    TRUE,
                    Oro,
                    0,
                    NULL,
                    &InfoReqReXmit,
                    NULL,
                    IScsiDhcp6ParseReply,
                    ConfigData
                    );
  if (Status == EFI_NO_MAPPING) {
    Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    Status = gBS->SetTimer (
                    Timer,
                    TimerRelative,
                    ISCSI_GET_MAPPING_TIMEOUT
                    );

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    do {

      TimerStatus = gBS->CheckEvent (Timer);

      if (!EFI_ERROR (TimerStatus)) {
        Status = Dhcp6->InfoRequest (
                          Dhcp6,
                          TRUE,
                          Oro,
                          0,
                          NULL,
                          &InfoReqReXmit,
                          NULL,
                          IScsiDhcp6ParseReply,
                          ConfigData
                          );
      }

    } while (TimerStatus == EFI_NOT_READY);

  }

ON_EXIT:

  if (Oro != NULL) {
    FreePool (Oro);
  }  

  if (Timer != NULL) {
    gBS->CloseEvent (Timer);
  }

  if (Dhcp6 != NULL) {
    gBS->CloseProtocol (
           Dhcp6Handle,
           &gEfiDhcp6ProtocolGuid,
           Image,
           Controller
           );
  }

  NetLibDestroyServiceChild (
    Controller,
    Image,
    &gEfiDhcp6ServiceBindingProtocolGuid,
    Dhcp6Handle
    );

  return Status;
}

