/** @file
  The implementation for Shell command ifconfig based on IP4Config2 protocol.

  (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellNetwork1CommandsLib.h"

typedef enum {
  IfConfigOpList  = 1,
  IfConfigOpSet   = 2,
  IfConfigOpClear = 3
} IFCONFIG_OPCODE;

typedef enum {
  VarCheckReserved = -1,
  VarCheckOk       = 0,
  VarCheckDuplicate,
  VarCheckConflict,
  VarCheckUnknown,
  VarCheckLackValue,
  VarCheckOutOfMem
} VAR_CHECK_CODE;

typedef enum {
  FlagTypeSingle = 0,
  FlagTypeNeedVar,
  FlagTypeNeedSet,
  FlagTypeSkipUnknown
} VAR_CHECK_FLAG_TYPE;

#define MACADDRMAXSIZE  32

typedef struct _IFCONFIG_INTERFACE_CB {
  EFI_HANDLE                        NicHandle;
  LIST_ENTRY                        Link;
  EFI_IP4_CONFIG2_PROTOCOL          *IfCfg;
  EFI_IP4_CONFIG2_INTERFACE_INFO    *IfInfo;
  EFI_IP4_CONFIG2_POLICY            Policy;
  UINT32                            DnsCnt;
  EFI_IPv4_ADDRESS                  DnsAddr[1];
} IFCONFIG_INTERFACE_CB;

typedef struct _ARG_LIST ARG_LIST;

struct _ARG_LIST {
  ARG_LIST    *Next;
  CHAR16      *Arg;
};

typedef struct _IFCONFIG4_PRIVATE_DATA {
  LIST_ENTRY    IfList;

  UINT32        OpCode;
  CHAR16        *IfName;
  ARG_LIST      *VarArg;
} IFCONFIG_PRIVATE_DATA;

typedef struct _VAR_CHECK_ITEM {
  CHAR16                 *FlagStr;
  UINT32                 FlagID;
  UINT32                 ConflictMask;
  VAR_CHECK_FLAG_TYPE    FlagType;
} VAR_CHECK_ITEM;

SHELL_PARAM_ITEM  mIfConfigCheckList[] = {
  {
    L"-b",
    TypeFlag
  },
  {
    L"-l",
    TypeValue
  },
  {
    L"-r",
    TypeValue
  },
  {
    L"-c",
    TypeValue
  },
  {
    L"-s",
    TypeMaxValue
  },
  {
    NULL,
    TypeMax
  },
};

VAR_CHECK_ITEM  mSetCheckList[] = {
  {
    L"static",
    0x00000001,
    0x00000001,
    FlagTypeSingle
  },
  {
    L"dhcp",
    0x00000002,
    0x00000001,
    FlagTypeSingle
  },
  {
    L"dns",
    0x00000008,
    0x00000004,
    FlagTypeSingle
  },
  {
    NULL,
    0x0,
    0x0,
    FlagTypeSkipUnknown
  },
};

STATIC CONST CHAR16  PermanentString[10] = L"PERMANENT";

/**
  Free the ARG_LIST.

  @param List Pointer to ARG_LIST to free.
**/
VOID
FreeArgList (
  ARG_LIST  *List
  )
{
  ARG_LIST  *Next;

  while (List->Next != NULL) {
    Next = List->Next;
    FreePool (List);
    List = Next;
  }

  FreePool (List);
}

/**
  Split a string with specified separator and save the substring to a list.

  @param[in]    String       The pointer of the input string.
  @param[in]    Separator    The specified separator.

  @return The pointer of headnode of ARG_LIST.

**/
ARG_LIST *
SplitStrToList (
  IN CONST CHAR16  *String,
  IN CHAR16        Separator
  )
{
  CHAR16    *Str;
  CHAR16    *ArgStr;
  ARG_LIST  *ArgList;
  ARG_LIST  *ArgNode;

  if (*String == L'\0') {
    return NULL;
  }

  //
  // Copy the CONST string to a local copy.
  //
  Str = AllocateCopyPool (StrSize (String), String);
  if (Str == NULL) {
    return NULL;
  }

  ArgStr = Str;

  //
  // init a node for the list head.
  //
  ArgNode = (ARG_LIST *)AllocateZeroPool (sizeof (ARG_LIST));
  if (ArgNode == NULL) {
    return NULL;
  }

  ArgList = ArgNode;

  //
  // Split the local copy and save in the list node.
  //
  while (*Str != L'\0') {
    if (*Str == Separator) {
      *Str          = L'\0';
      ArgNode->Arg  = ArgStr;
      ArgStr        = Str + 1;
      ArgNode->Next = (ARG_LIST *)AllocateZeroPool (sizeof (ARG_LIST));
      if (ArgNode->Next == NULL) {
        //
        // Free the local copy of string stored in the first node
        //
        FreePool (ArgList->Arg);
        FreeArgList (ArgList);
        return NULL;
      }

      ArgNode = ArgNode->Next;
    }

    Str++;
  }

  ArgNode->Arg  = ArgStr;
  ArgNode->Next = NULL;

  return ArgList;
}

/**
  Check the correctness of input Args with '-s' option.

  @param[in]    CheckList    The pointer of VAR_CHECK_ITEM array.
  @param[in]    Name         The pointer of input arg.
  @param[in]    Init         The switch to execute the check.

  @return   VarCheckOk          Valid parameter or Initialize check successfully.
  @return   VarCheckDuplicate   Duplicated parameter happened.
  @return   VarCheckConflict    Conflicted parameter happened
  @return   VarCheckUnknown     Unknown parameter.

**/
VAR_CHECK_CODE
IfConfigRetriveCheckListByName (
  IN VAR_CHECK_ITEM  *CheckList,
  IN CHAR16          *Name,
  IN BOOLEAN         Init
  )
{
  STATIC UINT32   CheckDuplicate;
  STATIC UINT32   CheckConflict;
  VAR_CHECK_CODE  RtCode;
  UINT32          Index;
  VAR_CHECK_ITEM  Arg;

  if (Init) {
    CheckDuplicate = 0;
    CheckConflict  = 0;
    return VarCheckOk;
  }

  RtCode = VarCheckOk;
  Index  = 0;
  Arg    = CheckList[Index];

  //
  // Check the Duplicated/Conflicted/Unknown input Args.
  //
  while (Arg.FlagStr != NULL) {
    if (StrCmp (Arg.FlagStr, Name) == 0) {
      if (CheckDuplicate & Arg.FlagID) {
        RtCode = VarCheckDuplicate;
        break;
      }

      if (CheckConflict & Arg.ConflictMask) {
        RtCode = VarCheckConflict;
        break;
      }

      CheckDuplicate |= Arg.FlagID;
      CheckConflict  |= Arg.ConflictMask;
      break;
    }

    Arg = CheckList[++Index];
  }

  if (Arg.FlagStr == NULL) {
    RtCode = VarCheckUnknown;
  }

  return RtCode;
}

/**
  The notify function of create event when performing a manual config.

  @param[in]    Event        The event this notify function registered to.
  @param[in]    Context      Pointer to the context data registered to the event.

**/
VOID
EFIAPI
IfConfigManualAddressNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  *((BOOLEAN *)Context) = TRUE;
}

/**
  Print MAC address.

  @param[in]    Node    The pointer of MAC address buffer.
  @param[in]    Size    The size of MAC address buffer.

**/
VOID
IfConfigPrintMacAddr (
  IN UINT8   *Node,
  IN UINT32  Size
  )
{
  UINTN  Index;

  ASSERT (Size <= MACADDRMAXSIZE);

  for (Index = 0; Index < Size; Index++) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_BODY), gShellNetwork1HiiHandle, Node[Index]);
    if (Index + 1 < Size) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_COLON), gShellNetwork1HiiHandle);
    }
  }

  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);
}

/**
  The get current status of all handles.

  @param[in]   IfName         The pointer of IfName(interface name).
  @param[in]   IfList         The pointer of IfList(interface list).

  @retval EFI_SUCCESS    The get status processed successfully.
  @retval others         The get status process failed.

**/
EFI_STATUS
IfConfigGetInterfaceInfo (
  IN CHAR16      *IfName,
  IN LIST_ENTRY  *IfList
  )
{
  EFI_STATUS                      Status;
  UINTN                           HandleIndex;
  UINTN                           HandleNum;
  EFI_HANDLE                      *HandleBuffer;
  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Cfg2;
  EFI_IP4_CONFIG2_INTERFACE_INFO  *IfInfo;
  IFCONFIG_INTERFACE_CB           *IfCb;
  UINTN                           DataSize;

  HandleBuffer = NULL;
  HandleNum    = 0;

  IfInfo = NULL;
  IfCb   = NULL;

  //
  // Locate all the handles with ip4 service binding protocol.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiIp4ServiceBindingProtocolGuid,
                  NULL,
                  &HandleNum,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status) || (HandleNum == 0)) {
    return Status;
  }

  //
  // Enumerate all handles that installed with ip4 service binding protocol.
  //
  for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
    IfCb     = NULL;
    IfInfo   = NULL;
    DataSize = 0;

    //
    // Ip4config protocol and ip4 service binding protocol are installed
    // on the same handle.
    //
    ASSERT (HandleBuffer != NULL);
    Status = gBS->HandleProtocol (
                    HandleBuffer[HandleIndex],
                    &gEfiIp4Config2ProtocolGuid,
                    (VOID **)&Ip4Cfg2
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Get the interface information size.
    //
    Status = Ip4Cfg2->GetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypeInterfaceInfo,
                        &DataSize,
                        NULL
                        );

    if (Status != EFI_BUFFER_TOO_SMALL) {
      goto ON_ERROR;
    }

    IfInfo = AllocateZeroPool (DataSize);

    if (IfInfo == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_ERROR;
    }

    //
    // Get the interface info.
    //
    Status = Ip4Cfg2->GetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypeInterfaceInfo,
                        &DataSize,
                        IfInfo
                        );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Check the interface name if required.
    //
    if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {
      FreePool (IfInfo);
      continue;
    }

    DataSize = 0;

    //
    // Get the size of dns server list.
    //
    Status = Ip4Cfg2->GetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypeDnsServer,
                        &DataSize,
                        NULL
                        );

    if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
      goto ON_ERROR;
    }

    IfCb = AllocateZeroPool (sizeof (IFCONFIG_INTERFACE_CB) + DataSize);

    if (IfCb == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_ERROR;
    }

    IfCb->NicHandle = HandleBuffer[HandleIndex];
    IfCb->IfInfo    = IfInfo;
    IfCb->IfCfg     = Ip4Cfg2;
    IfCb->DnsCnt    = (UINT32)(DataSize / sizeof (EFI_IPv4_ADDRESS));

    //
    // Get the dns server list if has.
    //
    if (DataSize > 0) {
      Status = Ip4Cfg2->GetData (
                          Ip4Cfg2,
                          Ip4Config2DataTypeDnsServer,
                          &DataSize,
                          IfCb->DnsAddr
                          );

      if (EFI_ERROR (Status)) {
        goto ON_ERROR;
      }
    }

    //
    // Get the config policy.
    //
    DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
    Status   = Ip4Cfg2->GetData (
                          Ip4Cfg2,
                          Ip4Config2DataTypePolicy,
                          &DataSize,
                          &IfCb->Policy
                          );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    InsertTailList (IfList, &IfCb->Link);

    if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {
      //
      // Only need the appointed interface, keep the allocated buffer.
      //
      IfCb   = NULL;
      IfInfo = NULL;
      break;
    }
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (IfInfo != NULL) {
    FreePool (IfInfo);
  }

  if (IfCb != NULL) {
    FreePool (IfCb);
  }

  return Status;
}

/**
  The list process of the ifconfig command.

  @param[in]   IfList    The pointer of IfList(interface list).

  @retval SHELL_SUCCESS  The ifconfig command list processed successfully.
  @retval others         The ifconfig command list process failed.

**/
SHELL_STATUS
IfConfigShowInterfaceInfo (
  IN LIST_ENTRY  *IfList
  )
{
  LIST_ENTRY             *Entry;
  LIST_ENTRY             *Next;
  IFCONFIG_INTERFACE_CB  *IfCb;
  EFI_STATUS             MediaStatus;
  EFI_IPv4_ADDRESS       Gateway;
  UINT32                 Index;

  MediaStatus = EFI_SUCCESS;

  if (IsListEmpty (IfList)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);
  }

  //
  // Go through the interface list.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {
    IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);

    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);

    //
    // Print interface name.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IF_NAME), gShellNetwork1HiiHandle, IfCb->IfInfo->Name);

    //
    // Get Media State.
    //
    if (EFI_SUCCESS == NetLibDetectMediaWaitTimeout (IfCb->NicHandle, 0, &MediaStatus)) {
      if (MediaStatus != EFI_SUCCESS) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected");
      } else {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present");
      }
    } else {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media state unknown");
    }

    //
    // Print interface config policy.
    //
    if (IfCb->Policy == Ip4Config2PolicyDhcp) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_DHCP), gShellNetwork1HiiHandle);
    } else {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_MAN), gShellNetwork1HiiHandle);
    }

    //
    // Print mac address of the interface.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_HEAD), gShellNetwork1HiiHandle);

    IfConfigPrintMacAddr (
      IfCb->IfInfo->HwAddress.Addr,
      IfCb->IfInfo->HwAddressSize
      );

    //
    // Print IPv4 address list of the interface.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_HEAD), gShellNetwork1HiiHandle);

    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY),
      gShellNetwork1HiiHandle,
      (UINTN)IfCb->IfInfo->StationAddress.Addr[0],
      (UINTN)IfCb->IfInfo->StationAddress.Addr[1],
      (UINTN)IfCb->IfInfo->StationAddress.Addr[2],
      (UINTN)IfCb->IfInfo->StationAddress.Addr[3]
      );

    //
    // Print subnet mask list of the interface.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_SUBNET_MASK_HEAD), gShellNetwork1HiiHandle);

    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY),
      gShellNetwork1HiiHandle,
      (UINTN)IfCb->IfInfo->SubnetMask.Addr[0],
      (UINTN)IfCb->IfInfo->SubnetMask.Addr[1],
      (UINTN)IfCb->IfInfo->SubnetMask.Addr[2],
      (UINTN)IfCb->IfInfo->SubnetMask.Addr[3]
      );

    //
    // Print default gateway of the interface.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_GATEWAY_HEAD), gShellNetwork1HiiHandle);

    ZeroMem (&Gateway, sizeof (EFI_IPv4_ADDRESS));

    for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {
      if ((CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetAddress, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) &&
          (CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetMask, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0))
      {
        CopyMem (&Gateway, &IfCb->IfInfo->RouteTable[Index].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
      }
    }

    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY),
      gShellNetwork1HiiHandle,
      (UINTN)Gateway.Addr[0],
      (UINTN)Gateway.Addr[1],
      (UINTN)Gateway.Addr[2],
      (UINTN)Gateway.Addr[3]
      );

    //
    // Print route table entry.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, IfCb->IfInfo->RouteTableSize);

    for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_ROUTES_ENTRY_INDEX), gShellNetwork1HiiHandle, Index);

      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR),
        gShellNetwork1HiiHandle,
        L"Subnet ",
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[0],
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[1],
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[2],
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[3]
        );

      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR),
        gShellNetwork1HiiHandle,
        L"Netmask",
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[0],
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[1],
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[2],
        (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[3]
        );

      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR),
        gShellNetwork1HiiHandle,
        L"Gateway",
        (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[0],
        (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[1],
        (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[2],
        (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[3]
        );
    }

    //
    // Print dns server addresses list of the interface if has.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_HEAD), gShellNetwork1HiiHandle);

    for (Index = 0; Index < IfCb->DnsCnt; Index++) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_BODY),
        gShellNetwork1HiiHandle,
        (UINTN)IfCb->DnsAddr[Index].Addr[0],
        (UINTN)IfCb->DnsAddr[Index].Addr[1],
        (UINTN)IfCb->DnsAddr[Index].Addr[2],
        (UINTN)IfCb->DnsAddr[Index].Addr[3]
        );

      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);
    }
  }

  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);

  return SHELL_SUCCESS;
}

/**
  The clean process of the ifconfig command to clear interface info.

  @param[in]   IfList    The pointer of IfList(interface list).
  @param[in]   IfName    The pointer of interface name.

  @retval SHELL_SUCCESS  The ifconfig command clean processed successfully.
  @retval others         The ifconfig command clean process failed.

**/
SHELL_STATUS
IfConfigClearInterfaceInfo (
  IN LIST_ENTRY  *IfList,
  IN CHAR16      *IfName
  )
{
  EFI_STATUS              Status;
  SHELL_STATUS            ShellStatus;
  LIST_ENTRY              *Entry;
  LIST_ENTRY              *Next;
  IFCONFIG_INTERFACE_CB   *IfCb;
  EFI_IP4_CONFIG2_POLICY  Policy;

  Status      = EFI_SUCCESS;
  ShellStatus = SHELL_SUCCESS;

  if (IsListEmpty (IfList)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);
  }

  //
  // Go through the interface list.
  // If the interface name is specified, DHCP DORA process will be
  // triggered by the policy transition (static -> dhcp).
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {
    IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);

    if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) {
      Policy = Ip4Config2PolicyStatic;

      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip4Config2DataTypePolicy,
                              sizeof (EFI_IP4_CONFIG2_POLICY),
                              &Policy
                              );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_ACCESS_DENIED;
        break;
      }
    }

    Policy = Ip4Config2PolicyDhcp;

    Status = IfCb->IfCfg->SetData (
                            IfCb->IfCfg,
                            Ip4Config2DataTypePolicy,
                            sizeof (EFI_IP4_CONFIG2_POLICY),
                            &Policy
                            );
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
      ShellStatus = SHELL_ACCESS_DENIED;
      break;
    }
  }

  return ShellStatus;
}

/**
  The set process of the ifconfig command.

  @param[in]   IfList    The pointer of IfList(interface list).
  @param[in]   VarArg    The pointer of ARG_LIST(Args with "-s" option).

  @retval SHELL_SUCCESS  The ifconfig command set processed successfully.
  @retval others         The ifconfig command set process failed.

**/
SHELL_STATUS
IfConfigSetInterfaceInfo (
  IN LIST_ENTRY  *IfList,
  IN ARG_LIST    *VarArg
  )
{
  EFI_STATUS             Status;
  SHELL_STATUS           ShellStatus;
  IFCONFIG_INTERFACE_CB  *IfCb;
  VAR_CHECK_CODE         CheckCode;
  EFI_EVENT              TimeOutEvt;
  EFI_EVENT              MappedEvt;
  BOOLEAN                IsAddressOk;

  EFI_IP4_CONFIG2_POLICY          Policy;
  EFI_IP4_CONFIG2_MANUAL_ADDRESS  ManualAddress;
  UINTN                           DataSize;
  EFI_IPv4_ADDRESS                Gateway;
  IP4_ADDR                        SubnetMask;
  IP4_ADDR                        TempGateway;
  EFI_IPv4_ADDRESS                *Dns;
  ARG_LIST                        *Tmp;
  UINTN                           Index;

  CONST CHAR16  *TempString;

  Dns = NULL;

  if (IsListEmpty (IfList)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);
    return SHELL_INVALID_PARAMETER;
  }

  //
  // Make sure to set only one interface each time.
  //
  IfCb        = NET_LIST_USER_STRUCT (IfList->ForwardLink, IFCONFIG_INTERFACE_CB, Link);
  Status      = EFI_SUCCESS;
  ShellStatus = SHELL_SUCCESS;

  //
  // Initialize check list mechanism.
  //
  CheckCode = IfConfigRetriveCheckListByName (
                NULL,
                NULL,
                TRUE
                );

  //
  // Create events & timers for asynchronous settings.
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &TimeOutEvt
                  );
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
    ShellStatus = SHELL_ACCESS_DENIED;
    goto ON_EXIT;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  IfConfigManualAddressNotify,
                  &IsAddressOk,
                  &MappedEvt
                  );
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
    ShellStatus = SHELL_ACCESS_DENIED;
    goto ON_EXIT;
  }

  //
  // Parse the setting variables.
  //
  while (VarArg != NULL) {
    //
    // Check invalid parameters (duplication & unknown & conflict).
    //
    CheckCode = IfConfigRetriveCheckListByName (
                  mSetCheckList,
                  VarArg->Arg,
                  FALSE
                  );

    if (VarCheckOk != CheckCode) {
      switch (CheckCode) {
        case VarCheckDuplicate:
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_DUPLICATE_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);
          break;

        case VarCheckConflict:
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_CONFLICT_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);
          break;

        case VarCheckUnknown:
          //
          // To handle unsupported option.
          //
          TempString = PermanentString;
          if (StringNoCaseCompare (&VarArg->Arg, &TempString) == 0) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, PermanentString);
            goto ON_EXIT;
          }

          //
          // To handle unknown option.
          //
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNKNOWN_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);
          break;

        default:
          break;
      }

      VarArg = VarArg->Next;
      continue;
    }

    //
    // Process valid variables.
    //
    if (StrCmp (VarArg->Arg, L"dhcp") == 0) {
      //
      // Set dhcp config policy
      //
      Policy = Ip4Config2PolicyDhcp;
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip4Config2DataTypePolicy,
                              sizeof (EFI_IP4_CONFIG2_POLICY),
                              &Policy
                              );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_ACCESS_DENIED;
        goto ON_EXIT;
      }

      VarArg = VarArg->Next;
    } else if (StrCmp (VarArg->Arg, L"static") == 0) {
      VarArg = VarArg->Next;
      if (VarArg == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      ZeroMem (&ManualAddress, sizeof (ManualAddress));

      //
      // Get manual IP address.
      //
      Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.Address);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      //
      // Get subnetmask.
      //
      VarArg = VarArg->Next;
      if (VarArg == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.SubnetMask);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      //
      // Get gateway.
      //
      VarArg = VarArg->Next;
      if (VarArg == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = NetLibStrToIp4 (VarArg->Arg, &Gateway);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      //
      // Need to check the gateway validity before set Manual Address.
      // In case we can set manual address but fail to configure Gateway.
      //
      CopyMem (&SubnetMask, &ManualAddress.SubnetMask, sizeof (IP4_ADDR));
      CopyMem (&TempGateway, &Gateway, sizeof (IP4_ADDR));
      SubnetMask  = NTOHL (SubnetMask);
      TempGateway = NTOHL (TempGateway);
      if ((SubnetMask != 0) &&
          (SubnetMask != 0xFFFFFFFFu) &&
          !NetIp4IsUnicast (TempGateway, SubnetMask))
      {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_GATEWAY), gShellNetwork1HiiHandle, VarArg->Arg);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      //
      // Set manual config policy.
      //
      Policy = Ip4Config2PolicyStatic;
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip4Config2DataTypePolicy,
                              sizeof (EFI_IP4_CONFIG2_POLICY),
                              &Policy
                              );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_ACCESS_DENIED;
        goto ON_EXIT;
      }

      //
      // Set Manual Address.
      //
      IsAddressOk = FALSE;

      Status = IfCb->IfCfg->RegisterDataNotify (
                              IfCb->IfCfg,
                              Ip4Config2DataTypeManualAddress,
                              MappedEvt
                              );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);
        ShellStatus = SHELL_ACCESS_DENIED;
        goto ON_EXIT;
      }

      DataSize = sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);

      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip4Config2DataTypeManualAddress,
                              DataSize,
                              &ManualAddress
                              );

      if (Status == EFI_NOT_READY) {
        gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000);

        while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
          if (IsAddressOk) {
            Status = EFI_SUCCESS;
            break;
          }
        }
      }

      IfCb->IfCfg->UnregisterDataNotify (
                     IfCb->IfCfg,
                     Ip4Config2DataTypeManualAddress,
                     MappedEvt
                     );

      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);
        ShellStatus = SHELL_ACCESS_DENIED;
        goto ON_EXIT;
      }

      //
      // Set gateway.
      //
      DataSize = sizeof (EFI_IPv4_ADDRESS);

      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip4Config2DataTypeGateway,
                              DataSize,
                              &Gateway
                              );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);
        ShellStatus = SHELL_ACCESS_DENIED;
        goto ON_EXIT;
      }

      VarArg = VarArg->Next;
    } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
      //
      // Get DNS addresses.
      //
      VarArg = VarArg->Next;
      Tmp    = VarArg;
      Index  = 0;
      while (Tmp != NULL) {
        Index++;
        Tmp = Tmp->Next;
      }

      Dns = AllocatePool (Index * sizeof (EFI_IPv4_ADDRESS));
      if (Dns == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Tmp   = VarArg;
      Index = 0;
      while (Tmp != NULL) {
        Status = NetLibStrToIp4 (Tmp->Arg, Dns + Index);
        if (EFI_ERROR (Status)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, Tmp->Arg);
          ShellStatus = SHELL_INVALID_PARAMETER;
          goto ON_EXIT;
        }

        Index++;
        Tmp = Tmp->Next;
      }

      VarArg = Tmp;

      //
      // Set DNS addresses.
      //
      DataSize = Index * sizeof (EFI_IPv4_ADDRESS);

      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip4Config2DataTypeDnsServer,
                              DataSize,
                              Dns
                              );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_ACCESS_DENIED;
        goto ON_EXIT;
      }
    }
  }

ON_EXIT:
  if (Dns != NULL) {
    FreePool (Dns);
  }

  return ShellStatus;
}

/**
  The ifconfig command main process.

  @param[in]   Private    The pointer of IFCONFIG_PRIVATE_DATA.

  @retval SHELL_SUCCESS  ifconfig command processed successfully.
  @retval others         The ifconfig command process failed.

**/
SHELL_STATUS
IfConfig (
  IN IFCONFIG_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS    Status;
  SHELL_STATUS  ShellStatus;

  ShellStatus = SHELL_SUCCESS;

  //
  // Get configure information of all interfaces.
  //
  Status = IfConfigGetInterfaceInfo (
             Private->IfName,
             &Private->IfList
             );
  if (EFI_ERROR (Status)) {
    ShellStatus = SHELL_NOT_FOUND;
    goto ON_EXIT;
  }

  switch (Private->OpCode) {
    case IfConfigOpList:
      ShellStatus = IfConfigShowInterfaceInfo (&Private->IfList);
      break;

    case IfConfigOpClear:
      ShellStatus = IfConfigClearInterfaceInfo (&Private->IfList, Private->IfName);
      break;

    case IfConfigOpSet:
      ShellStatus = IfConfigSetInterfaceInfo (&Private->IfList, Private->VarArg);
      break;

    default:
      ShellStatus = SHELL_UNSUPPORTED;
  }

ON_EXIT:
  return ShellStatus;
}

/**
  The ifconfig command cleanup process, free the allocated memory.

  @param[in]   Private    The pointer of  IFCONFIG_PRIVATE_DATA.

**/
VOID
IfConfigCleanup (
  IN IFCONFIG_PRIVATE_DATA  *Private
  )
{
  LIST_ENTRY             *Entry;
  LIST_ENTRY             *NextEntry;
  IFCONFIG_INTERFACE_CB  *IfCb;

  ASSERT (Private != NULL);

  //
  // Clean the list which save the set config Args.
  //
  if (Private->VarArg != NULL) {
    FreeArgList (Private->VarArg);
  }

  if (Private->IfName != NULL) {
    FreePool (Private->IfName);
  }

  //
  // Clean the IFCONFIG_INTERFACE_CB list.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->IfList) {
    IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);

    RemoveEntryList (&IfCb->Link);

    if (IfCb->IfInfo != NULL) {
      FreePool (IfCb->IfInfo);
    }

    FreePool (IfCb);
  }

  FreePool (Private);
}

/**
  Function for 'ifconfig' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).

  @retval EFI_SUCCESS    ifconfig command processed successfully.
  @retval others         The ifconfig command process failed.

**/
SHELL_STATUS
EFIAPI
ShellCommandRunIfconfig (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS             Status;
  IFCONFIG_PRIVATE_DATA  *Private;
  LIST_ENTRY             *ParamPackage;
  SHELL_STATUS           ShellStatus;
  CONST CHAR16           *ValueStr;
  ARG_LIST               *ArgList;
  CHAR16                 *ProblemParam;
  CHAR16                 *Str;

  Status      = EFI_INVALID_PARAMETER;
  Private     = NULL;
  ShellStatus = SHELL_SUCCESS;

  Status = ShellCommandLineParseEx (mIfConfigCheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellNetwork1HiiHandle, L"ifconfig", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }

    goto ON_EXIT;
  }

  //
  // To handle unsupported option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, L"-c");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  //
  // To handle no option.
  //
  if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&
      !ShellCommandLineGetFlag (ParamPackage, L"-l"))
  {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_OPTION), gShellNetwork1HiiHandle);
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  //
  // To handle conflict options.
  //
  if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||
      ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
      ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))))
  {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellNetwork1HiiHandle, L"ifconfig");
    ShellStatus = SHELL_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  Private = AllocateZeroPool (sizeof (IFCONFIG_PRIVATE_DATA));
  if (Private == NULL) {
    ShellStatus = SHELL_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  InitializeListHead (&Private->IfList);

  //
  // To get interface name for the list option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {
    Private->OpCode = IfConfigOpList;
    ValueStr        = ShellCommandLineGetValue (ParamPackage, L"-l");
    if (ValueStr != NULL) {
      Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);
      if (Str == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Private->IfName = Str;
    }
  }

  //
  // To get interface name for the clear option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {
    Private->OpCode = IfConfigOpClear;
    ValueStr        = ShellCommandLineGetValue (ParamPackage, L"-r");
    if (ValueStr != NULL) {
      Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);
      if (Str == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");
        ShellStatus = SHELL_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Private->IfName = Str;
    }
  }

  //
  // To get interface name and corresponding Args for the set option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {
    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");
    if (ValueStr == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_INTERFACE), gShellNetwork1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    //
    // To split the configuration into multi-section.
    //
    ArgList = SplitStrToList (ValueStr, L' ');
    if (ArgList == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");
      ShellStatus = SHELL_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    Private->OpCode = IfConfigOpSet;
    Private->IfName = ArgList->Arg;

    Private->VarArg = ArgList->Next;

    if ((Private->IfName == NULL) || (Private->VarArg == NULL)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto ON_EXIT;
    }
  }

  //
  // Main process of ifconfig.
  //
  ShellStatus = IfConfig (Private);

ON_EXIT:

  ShellCommandLineFreeVarList (ParamPackage);

  if (Private != NULL) {
    IfConfigCleanup (Private);
  }

  return ShellStatus;
}
