]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c
ShellPkg/Dp: Add null pointer check
[mirror_edk2.git] / ShellPkg / Library / UefiShellNetwork1CommandsLib / Ifconfig.c
index 0c4a3b09c323832cc58856b847da773c486f9f8c..ab6ab8b57ea251b939a04592453f9e4d016861b4 100644 (file)
@@ -2,7 +2,7 @@
   The implementation for Shell command ifconfig based on IP4Config2 protocol.\r
 \r
   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -129,6 +129,26 @@ VAR_CHECK_ITEM  mSetCheckList[] = {
 \r
 STATIC CONST CHAR16 PermanentString[10] = L"PERMANENT";\r
 \r
+/**\r
+  Free the ARG_LIST.\r
+\r
+  @param List Pointer to ARG_LIST to free.\r
+**/\r
+VOID\r
+FreeArgList (\r
+  ARG_LIST       *List\r
+)\r
+{\r
+  ARG_LIST       *Next;\r
+  while (List->Next != NULL) {\r
+    Next = List->Next;\r
+    FreePool (List);\r
+    List = Next;\r
+  }\r
+\r
+  FreePool (List);\r
+}\r
+\r
 /**\r
   Split a string with specified separator and save the substring to a list.\r
 \r
@@ -157,14 +177,18 @@ SplitStrToList (
   // Copy the CONST string to a local copy.\r
   //\r
   Str = AllocateCopyPool (StrSize (String), String);\r
-  ASSERT (Str != NULL);\r
+  if (Str == NULL) {\r
+    return NULL;\r
+  }\r
   ArgStr  = Str;\r
 \r
   //\r
   // init a node for the list head.\r
   //\r
   ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));\r
-  ASSERT (ArgNode != NULL);\r
+  if (ArgNode == NULL) {\r
+    return NULL;\r
+  }\r
   ArgList = ArgNode;\r
 \r
   //\r
@@ -176,7 +200,14 @@ SplitStrToList (
       ArgNode->Arg  = ArgStr;\r
       ArgStr        = Str + 1;\r
       ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));\r
-      ASSERT (ArgNode->Next != NULL);\r
+      if (ArgNode->Next == NULL) {\r
+        //\r
+        // Free the local copy of string stored in the first node\r
+        //\r
+        FreePool (ArgList->Arg);\r
+        FreeArgList (ArgList);\r
+        return NULL;\r
+      }\r
       ArgNode = ArgNode->Next;\r
     }\r
 \r
@@ -519,11 +550,11 @@ IfConfigShowInterfaceInfo (
   LIST_ENTRY                   *Entry;\r
   LIST_ENTRY                   *Next;\r
   IFCONFIG_INTERFACE_CB        *IfCb;\r
-  BOOLEAN                       MediaPresent;\r
+  EFI_STATUS                    MediaStatus;\r
   EFI_IPv4_ADDRESS              Gateway;\r
   UINT32                        Index;\r
   \r
-  MediaPresent = TRUE;\r
+  MediaStatus = EFI_SUCCESS;\r
 \r
   if (IsListEmpty (IfList)) {\r
     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
@@ -545,11 +576,14 @@ IfConfigShowInterfaceInfo (
     //\r
     // Get Media State.\r
     //\r
-    NetLibDetectMedia (IfCb->NicHandle, &MediaPresent);\r
-    if (!MediaPresent) {\r
-      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected");\r
+    if (EFI_SUCCESS == NetLibDetectMediaWaitTimeout (IfCb->NicHandle, 0, &MediaStatus)) {\r
+      if (MediaStatus != EFI_SUCCESS) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected");\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present");\r
+      }\r
     } else {\r
-      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present");\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media state unknown");\r
     }\r
 \r
     //\r
@@ -710,6 +744,7 @@ IfConfigShowInterfaceInfo (
   The clean process of the ifconfig command to clear interface info.\r
 \r
   @param[in]   IfList    The pointer of IfList(interface list).\r
+  @param[in]   IfName    The pointer of interface name.\r
 \r
   @retval SHELL_SUCCESS  The ifconfig command clean processed successfully.\r
   @retval others         The ifconfig command clean process failed.\r
@@ -717,7 +752,8 @@ IfConfigShowInterfaceInfo (
 **/\r
 SHELL_STATUS\r
 IfConfigClearInterfaceInfo (\r
-  IN LIST_ENTRY    *IfList\r
+  IN LIST_ENTRY    *IfList,\r
+  IN CHAR16        *IfName\r
   )\r
 {\r
   EFI_STATUS                Status;  \r
@@ -726,8 +762,7 @@ IfConfigClearInterfaceInfo (
   LIST_ENTRY                *Next;\r
   IFCONFIG_INTERFACE_CB     *IfCb;\r
   EFI_IP4_CONFIG2_POLICY    Policy;\r
-\r
-  Policy = Ip4Config2PolicyDhcp;\r
+  \r
   Status = EFI_SUCCESS;\r
   ShellStatus = SHELL_SUCCESS;\r
 \r
@@ -737,9 +772,29 @@ IfConfigClearInterfaceInfo (
 \r
   //\r
   // Go through the interface list.\r
+  // If the interface name is specified, DHCP DORA process will be \r
+  // triggered by the policy transition (static -> dhcp).\r
   //\r
   NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {\r
     IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
+\r
+    if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) {\r
+      Policy = Ip4Config2PolicyStatic;\r
+      \r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip4Config2DataTypePolicy,\r
+                              sizeof (EFI_IP4_CONFIG2_POLICY),\r
+                              &Policy\r
+                              );\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        break;\r
+      }  \r
+    }\r
+\r
+    Policy = Ip4Config2PolicyDhcp;\r
     \r
     Status = IfCb->IfCfg->SetData (\r
                             IfCb->IfCfg,\r
@@ -785,6 +840,8 @@ IfConfigSetInterfaceInfo (
   EFI_IP4_CONFIG2_MANUAL_ADDRESS   ManualAddress;\r
   UINTN                            DataSize;\r
   EFI_IPv4_ADDRESS                 Gateway;\r
+  IP4_ADDR                         SubnetMask;\r
+  IP4_ADDR                         TempGateway;\r
   EFI_IPv4_ADDRESS                 *Dns;\r
   ARG_LIST                         *Tmp;\r
   UINTN                            Index;\r
@@ -966,6 +1023,21 @@ IfConfigSetInterfaceInfo (
         goto ON_EXIT;\r
       }\r
 \r
+      //\r
+      // Need to check the gateway validity before set Manual Address.\r
+      // In case we can set manual address but fail to configure Gateway.\r
+      //\r
+      CopyMem (&SubnetMask, &ManualAddress.SubnetMask, sizeof (IP4_ADDR));\r
+      CopyMem (&TempGateway, &Gateway, sizeof (IP4_ADDR));\r
+      SubnetMask  = NTOHL (SubnetMask);\r
+      TempGateway = NTOHL (TempGateway);\r
+      if ((SubnetMask != 0) &&\r
+          !NetIp4IsUnicast (TempGateway, SubnetMask)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_GATEWAY), gShellNetwork1HiiHandle, VarArg->Arg);\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto ON_EXIT;\r
+      }\r
+\r
       //\r
       // Set manual config policy.\r
       //\r
@@ -1062,7 +1134,11 @@ IfConfigSetInterfaceInfo (
       }\r
 \r
       Dns   = AllocatePool (Index * sizeof (EFI_IPv4_ADDRESS));\r
-      ASSERT(Dns != NULL);\r
+      if (Dns == NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");\r
+        ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
       Tmp   = VarArg;\r
       Index = 0;\r
       while (Tmp != NULL) {\r
@@ -1143,7 +1219,7 @@ IfConfig (
     break;\r
 \r
   case IfConfigOpClear:\r
-    ShellStatus = IfConfigClearInterfaceInfo (&Private->IfList);\r
+    ShellStatus = IfConfigClearInterfaceInfo (&Private->IfList, Private->IfName);\r
     break;\r
 \r
   case IfConfigOpSet:\r
@@ -1172,8 +1248,6 @@ IfConfigCleanup (
   LIST_ENTRY                *Entry;\r
   LIST_ENTRY                *NextEntry;\r
   IFCONFIG_INTERFACE_CB     *IfCb;\r
-  ARG_LIST                  *ArgNode;\r
-  ARG_LIST                  *ArgHead;\r
 \r
   ASSERT (Private != NULL);\r
 \r
@@ -1181,15 +1255,7 @@ IfConfigCleanup (
   // Clean the list which save the set config Args.\r
   //\r
   if (Private->VarArg != NULL) {\r
-    ArgHead = Private->VarArg;\r
-\r
-    while (ArgHead->Next != NULL) {\r
-      ArgNode = ArgHead->Next;\r
-      FreePool (ArgHead);\r
-      ArgHead = ArgNode;\r
-    }\r
-\r
-    FreePool (ArgHead);\r
+    FreeArgList (Private->VarArg);\r
   }\r
 \r
   if (Private->IfName != NULL) {\r
@@ -1304,11 +1370,15 @@ ShellCommandRunIfconfig (
     ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");\r
     if (ValueStr != NULL) {\r
       Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
-      ASSERT (Str != NULL);\r
+      if (Str == NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");\r
+        ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
       Private->IfName = Str;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // To get interface name for the clear option.\r
   //\r
@@ -1317,7 +1387,11 @@ ShellCommandRunIfconfig (
     ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");\r
     if (ValueStr != NULL) {\r
       Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
-      ASSERT (Str != NULL);\r
+      if (Str == NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");\r
+        ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
       Private->IfName = Str;\r
     }\r
   }\r
@@ -1336,8 +1410,12 @@ ShellCommandRunIfconfig (
     //\r
     // To split the configuration into multi-section.\r
     //\r
-    ArgList         = SplitStrToList (ValueStr, L' ');\r
-    ASSERT (ArgList != NULL);\r
+    ArgList = SplitStrToList (ValueStr, L' ');\r
+    if (ArgList == NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig");\r
+      ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+      goto ON_EXIT;\r
+    }\r
 \r
     Private->OpCode = IfConfigOpSet;\r
     Private->IfName = ArgList->Arg;\r