/** @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++) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_BODY), gShellNetwork1HiiHandle, Node[Index]);
    if (Index + 1 < Size) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_COLON), gShellNetwork1HiiHandle);
    }
  }

  ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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);

    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);

    //
    // Print interface name.
    //
    ShellPrintHiiDefaultEx (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) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected");
      } else {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present");
      }
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media state unknown");
    }

    //
    // Print interface config policy.
    //
    if (IfCb->Policy == Ip4Config2PolicyDhcp) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_DHCP), gShellNetwork1HiiHandle);
    } else {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_MAN), gShellNetwork1HiiHandle);
    }

    //
    // Print mac address of the interface.
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_HEAD), gShellNetwork1HiiHandle);

    IfConfigPrintMacAddr (
      IfCb->IfInfo->HwAddress.Addr,
      IfCb->IfInfo->HwAddressSize
      );

    //
    // Print IPv4 address list of the interface.
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_HEAD), gShellNetwork1HiiHandle);

    ShellPrintHiiDefaultEx (
      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.
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_SUBNET_MASK_HEAD), gShellNetwork1HiiHandle);

    ShellPrintHiiDefaultEx (
      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.
    //
    ShellPrintHiiDefaultEx (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));
      }
    }

    ShellPrintHiiDefaultEx (
      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.
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, IfCb->IfInfo->RouteTableSize);

    for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_ROUTES_ENTRY_INDEX), gShellNetwork1HiiHandle, Index);

      ShellPrintHiiDefaultEx (
        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]
        );

      ShellPrintHiiDefaultEx (
        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]
        );

      ShellPrintHiiDefaultEx (
        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.
    //
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_HEAD), gShellNetwork1HiiHandle);

    for (Index = 0; Index < IfCb->DnsCnt; Index++) {
      ShellPrintHiiDefaultEx (
        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]
        );

      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);
    }
  }

  ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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)) {
      ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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:
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_DUPLICATE_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);
          break;

        case VarCheckConflict:
          ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_CONFLICT_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);
          break;

        case VarCheckUnknown:
          //
          // To handle unsupported option.
          //
          TempString = PermanentString;
          if (StringNoCaseCompare (&VarArg->Arg, &TempString) == 0) {
            ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, PermanentString);
            goto ON_EXIT;
          }

          //
          // To handle unknown option.
          //
          ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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) {
        ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      //
      // Get subnetmask.
      //
      VarArg = VarArg->Next;
      if (VarArg == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.SubnetMask);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      //
      // Get gateway.
      //
      VarArg = VarArg->Next;
      if (VarArg == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto ON_EXIT;
      }

      Status = NetLibStrToIp4 (VarArg->Arg, &Gateway);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (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))
      {
        ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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) {
        ShellPrintHiiDefaultEx (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)) {
          ShellPrintHiiDefaultEx (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)) {
        ShellPrintHiiDefaultEx (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)) {
      ShellPrintHiiDefaultEx (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")) {
    ShellPrintHiiDefaultEx (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"))
  {
    ShellPrintHiiDefaultEx (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"))))
  {
    ShellPrintHiiDefaultEx (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) {
        ShellPrintHiiDefaultEx (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) {
        ShellPrintHiiDefaultEx (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) {
      ShellPrintHiiDefaultEx (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) {
      ShellPrintHiiDefaultEx (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)) {
      ShellPrintHiiDefaultEx (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;
}
