/** @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 - 2016, 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 "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;
  BOOLEAN                       MediaPresent;
  EFI_IPv4_ADDRESS              Gateway;
  UINT32                        Index;
  
  MediaPresent = TRUE;

  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.
    //
    NetLibDetectMedia (IfCb->NicHandle, &MediaPresent);
    if (!MediaPresent) {
      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");
    }

    //
    // 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;
  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;
      }

      //
      // 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;
}
