]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Application/VConfig/VConfig.c
Add NetworkPkg (P.UDK2010.UP3.Network.P1)
[mirror_edk2.git] / NetworkPkg / Application / VConfig / VConfig.c
diff --git a/NetworkPkg/Application/VConfig/VConfig.c b/NetworkPkg/Application/VConfig/VConfig.c
new file mode 100644 (file)
index 0000000..c948131
--- /dev/null
@@ -0,0 +1,668 @@
+/** @file\r
+  Shell application for VLAN configuration.\r
+\r
+  Copyright (C) 2009 - 2010, 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
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/VlanConfig.h>\r
+\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/ShellLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/NetLib.h>\r
+\r
+#define INVALID_NIC_INDEX   0xffff\r
+#define INVALID_VLAN_ID     0xffff\r
+\r
+//\r
+// This is the generated String package data for all .UNI files.\r
+// This data array is ready to be used as input of HiiAddPackages() to\r
+// create a packagelist (which contains Form packages, String packages, etc).\r
+//\r
+extern UINT8      VConfigStrings[];\r
+\r
+EFI_HANDLE        mImageHandle  = NULL;\r
+EFI_HII_HANDLE    mHiiHandle    = NULL;\r
+\r
+SHELL_PARAM_ITEM  mParamList[] = {\r
+  {\r
+    L"-l",\r
+    TypeValue\r
+  },\r
+  {\r
+    L"-a",\r
+    TypeMaxValue\r
+  },\r
+  {\r
+    L"-d",\r
+    TypeValue\r
+  },\r
+  {\r
+    NULL,\r
+    TypeMax\r
+  }\r
+};\r
+\r
+/**\r
+  Locate the network interface handle buffer.\r
+\r
+  @param[out]  NumberOfHandles Pointer to the number of handles.\r
+  @param[out]  HandleBuffer    Pointer to the buffer to store the returned handles.\r
+\r
+**/\r
+VOID\r
+LocateNicHandleBuffer (\r
+  OUT UINTN                       *NumberOfHandles,\r
+  OUT EFI_HANDLE                  **HandleBuffer\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  *NumberOfHandles  = 0;\r
+  *HandleBuffer     = NULL;\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiVlanConfigProtocolGuid,\r
+                  NULL,\r
+                  NumberOfHandles,\r
+                  HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_LOCATE_FAIL), mHiiHandle, Status);\r
+  }\r
+}\r
+\r
+/**\r
+  Extract the decimal index from the network interface name.\r
+\r
+  @param[in]  Name           Name of the network interface.\r
+\r
+  @retval INVALID_NIC_INDEX  Failed to extract the network interface index.\r
+  @return others             The network interface index.\r
+\r
+**/\r
+UINTN\r
+NicNameToIndex (\r
+  IN CHAR16                   *Name\r
+  )\r
+{\r
+  CHAR16  *Str;\r
+\r
+  Str = Name + 3;\r
+  if ((StrnCmp (Name, L"eth", 3) != 0) || (*Str == 0)) {\r
+    return INVALID_NIC_INDEX;\r
+  }\r
+\r
+  while (*Str != 0) {\r
+    if ((*Str < L'0') || (*Str > L'9')) {\r
+      return INVALID_NIC_INDEX;\r
+    }\r
+\r
+    Str++;\r
+  }\r
+\r
+  return (UINT16) StrDecimalToUintn (Name + 3);\r
+}\r
+\r
+/**\r
+  Find network interface device handle by its name.\r
+\r
+  @param[in]  Name           Name of the network interface.\r
+\r
+  @retval NULL               Cannot find the network interface.\r
+  @return others             Handle of the network interface.\r
+\r
+**/\r
+EFI_HANDLE\r
+NicNameToHandle (\r
+  IN CHAR16                   *Name\r
+  )\r
+{\r
+  UINTN       NumberOfHandles;\r
+  EFI_HANDLE  *HandleBuffer;\r
+  UINTN       Index;\r
+  EFI_HANDLE  Handle;\r
+\r
+  //\r
+  // Find all NIC handles.\r
+  //\r
+  LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);\r
+  if (NumberOfHandles == 0) {\r
+    return NULL;\r
+  }\r
+\r
+  Index = NicNameToIndex (Name);\r
+  if (Index >= NumberOfHandles) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_IF), mHiiHandle, Name);\r
+    Handle = NULL;\r
+  } else {\r
+    Handle = HandleBuffer[Index];\r
+  }\r
+\r
+  FreePool (HandleBuffer);\r
+  return Handle;\r
+}\r
+\r
+/**\r
+  Open VlanConfig protocol from a handle.\r
+\r
+  @param[in]  Handle         The handle to open the VlanConfig protocol.\r
+\r
+  @return The VlanConfig protocol interface.\r
+\r
+**/\r
+EFI_VLAN_CONFIG_PROTOCOL *\r
+OpenVlanConfigProtocol (\r
+  IN EFI_HANDLE                 Handle\r
+  )\r
+{\r
+  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;\r
+\r
+  VlanConfig = NULL;\r
+  gBS->OpenProtocol (\r
+         Handle,\r
+         &gEfiVlanConfigProtocolGuid,\r
+         (VOID **) &VlanConfig,\r
+         mImageHandle,\r
+         Handle,\r
+         EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+         );\r
+\r
+  return VlanConfig;\r
+}\r
+\r
+/**\r
+  Close VlanConfig protocol of a handle.\r
+\r
+  @param[in]  Handle         The handle to close the VlanConfig protocol.\r
+\r
+**/\r
+VOID\r
+CloseVlanConfigProtocol (\r
+  IN EFI_HANDLE                 Handle\r
+  )\r
+{\r
+  gBS->CloseProtocol (\r
+         Handle,\r
+         &gEfiVlanConfigProtocolGuid,\r
+         mImageHandle,\r
+         Handle\r
+         );\r
+}\r
+\r
+/**\r
+  Display VLAN configuration of a network interface.\r
+\r
+  @param[in]  Handle         Handle of the network interface.\r
+  @param[in]  NicIndex       Index of the network interface.\r
+\r
+**/\r
+VOID\r
+ShowNicVlanInfo (\r
+  IN EFI_HANDLE              Handle,\r
+  IN UINTN                   NicIndex\r
+  )\r
+{\r
+  CHAR16                    *MacStr;\r
+  EFI_STATUS                Status;\r
+  UINTN                     Index;\r
+  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;\r
+  UINT16                    NumberOfVlan;\r
+  EFI_VLAN_FIND_DATA        *VlanData;\r
+\r
+  VlanConfig = OpenVlanConfigProtocol (Handle);\r
+  if (VlanConfig == NULL) {\r
+    return ;\r
+  }\r
+\r
+  MacStr  = NULL;\r
+  Status  = NetLibGetMacString (Handle, mImageHandle, &MacStr);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_MAC_FAIL), mHiiHandle, Status);\r
+    goto Exit;\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_ETH_MAC), mHiiHandle, NicIndex, MacStr);\r
+\r
+  Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);\r
+  if (EFI_ERROR (Status)) {\r
+    if (Status == EFI_NOT_FOUND) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VLAN), mHiiHandle);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_FIND_FAIL), mHiiHandle, Status);\r
+    }\r
+\r
+    goto Exit;\r
+  }\r
+\r
+  for (Index = 0; Index < NumberOfVlan; Index++) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_VCONFIG_VLAN_DISPLAY),\r
+      mHiiHandle,\r
+      VlanData[Index].VlanId,\r
+      VlanData[Index].Priority\r
+      );\r
+  }\r
+\r
+  FreePool (VlanData);\r
+\r
+Exit:\r
+  CloseVlanConfigProtocol (Handle);\r
+\r
+  if (MacStr != NULL) {\r
+    FreePool (MacStr);\r
+  }\r
+}\r
+\r
+/**\r
+  Display the VLAN configuration of all, or a specified network interface.\r
+\r
+  @param[in]  Name           Name of the network interface. If NULL, the VLAN\r
+                             configuration of all network will be displayed.\r
+\r
+**/\r
+VOID\r
+DisplayVlan (\r
+  IN CHAR16              *Name OPTIONAL\r
+  )\r
+{\r
+  UINTN       NumberOfHandles;\r
+  EFI_HANDLE  *HandleBuffer;\r
+  UINTN       Index;\r
+  EFI_HANDLE  NicHandle;\r
+\r
+  if (Name != NULL) {\r
+    //\r
+    // Display specified NIC\r
+    //\r
+    NicHandle = NicNameToHandle (Name);\r
+    if (NicHandle == NULL) {\r
+      return ;\r
+    }\r
+\r
+    ShowNicVlanInfo (NicHandle, 0);\r
+    return ;\r
+  }\r
+\r
+  //\r
+  // Find all NIC handles\r
+  //\r
+  LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);\r
+  if (NumberOfHandles == 0) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    ShowNicVlanInfo (HandleBuffer[Index], Index);\r
+  }\r
+\r
+  FreePool (HandleBuffer);\r
+}\r
+\r
+/**\r
+  Convert a NULL-terminated unicode decimal VLAN ID string to VLAN ID.\r
+\r
+  @param[in]  String       Pointer to VLAN ID string from user input.\r
+\r
+  @retval Value translated from String, or INVALID_VLAN_ID is string is invalid.\r
+\r
+**/\r
+UINT16\r
+StrToVlanId (\r
+  IN CHAR16             *String\r
+  )\r
+{\r
+  CHAR16  *Str;\r
+\r
+  if (String == NULL) {\r
+    return INVALID_VLAN_ID;\r
+  }\r
+\r
+  Str = String;\r
+  while ((*Str >= '0') && (*Str <= '9')) {\r
+    Str++;\r
+  }\r
+\r
+  if (*Str != 0) {\r
+    return INVALID_VLAN_ID;\r
+  }\r
+\r
+  return (UINT16) StrDecimalToUintn (String);\r
+}\r
+\r
+/**\r
+  Add a VLAN device.\r
+\r
+  @param[in]  ParamStr       Parameter string from user input.\r
+\r
+**/\r
+VOID\r
+AddVlan (\r
+  IN CHAR16             *ParamStr\r
+  )\r
+{\r
+  CHAR16                    *Name;\r
+  CHAR16                    *VlanIdStr;\r
+  CHAR16                    *PriorityStr;\r
+  CHAR16                    *StrPtr;\r
+  BOOLEAN                   IsSpace;\r
+  UINTN                     VlanId;\r
+  UINTN                     Priority;\r
+  EFI_HANDLE                Handle;\r
+  EFI_HANDLE                VlanHandle;\r
+  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;\r
+  EFI_STATUS                Status;\r
+\r
+  VlanConfig  = NULL;\r
+  Priority    = 0;\r
+\r
+  if (ParamStr == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);\r
+    return ;\r
+  }\r
+\r
+  StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);\r
+  if (StrPtr == NULL) {\r
+    return ;\r
+  }\r
+\r
+  Name        = StrPtr;\r
+  VlanIdStr   = NULL;\r
+  PriorityStr = NULL;\r
+  IsSpace     = FALSE;\r
+  while (*StrPtr != 0) {\r
+    if (*StrPtr == L' ') {\r
+      *StrPtr = 0;\r
+      IsSpace = TRUE;\r
+    } else {\r
+      if (IsSpace) {\r
+        //\r
+        // Start of a parameter.\r
+        //\r
+        if (VlanIdStr == NULL) {\r
+          //\r
+          // 2nd parameter is VLAN ID.\r
+          //\r
+          VlanIdStr = StrPtr;\r
+        } else if (PriorityStr == NULL) {\r
+          //\r
+          // 3rd parameter is Priority.\r
+          //\r
+          PriorityStr = StrPtr;\r
+        } else {\r
+          //\r
+          // Ignore else parameters.\r
+          //\r
+          break;\r
+        }\r
+      }\r
+\r
+      IsSpace = FALSE;\r
+    }\r
+\r
+    StrPtr++;\r
+  }\r
+\r
+  Handle = NicNameToHandle (Name);\r
+  if (Handle == NULL) {\r
+    goto Exit;\r
+  }\r
+\r
+  VlanConfig = OpenVlanConfigProtocol (Handle);\r
+  if (VlanConfig == NULL) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Check VLAN ID.\r
+  //\r
+  if ((VlanIdStr == NULL) || (*VlanIdStr == 0)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);\r
+    goto Exit;\r
+  }\r
+\r
+  VlanId = StrToVlanId (VlanIdStr);\r
+  if (VlanId > 4094) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Check Priority.\r
+  //\r
+  if ((PriorityStr != NULL) && (*PriorityStr != 0)) {\r
+    Priority = StrDecimalToUintn (PriorityStr);\r
+    if (Priority > 7) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_PRIORITY), mHiiHandle, PriorityStr);\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Set VLAN\r
+  //\r
+  Status = VlanConfig->Set (VlanConfig, (UINT16) VlanId, (UINT8) Priority);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_FAIL), mHiiHandle, Status);\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Connect the VLAN device.\r
+  //\r
+  VlanHandle = NetLibGetVlanHandle (Handle, (UINT16) VlanId);\r
+  if (VlanHandle != NULL) {\r
+    gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_SUCCESS), mHiiHandle);\r
+\r
+Exit:\r
+  if (VlanConfig != NULL) {\r
+    CloseVlanConfigProtocol (Handle);\r
+  }\r
+\r
+  FreePool (Name);\r
+}\r
+\r
+/**\r
+  Remove a VLAN device.\r
+\r
+  @param[in]  ParamStr       Parameter string from user input.\r
+\r
+**/\r
+VOID\r
+DeleteVlan (\r
+  CHAR16 *ParamStr\r
+  )\r
+{\r
+  CHAR16                    *Name;\r
+  CHAR16                    *VlanIdStr;\r
+  CHAR16                    *StrPtr;\r
+  UINTN                     VlanId;\r
+  EFI_HANDLE                Handle;\r
+  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;\r
+  EFI_STATUS                Status;\r
+  UINT16                    NumberOfVlan;\r
+  EFI_VLAN_FIND_DATA        *VlanData;\r
+\r
+  VlanConfig = NULL;\r
+\r
+  if (ParamStr == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);\r
+    return ;\r
+  }\r
+\r
+  StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);\r
+  if (StrPtr == NULL) {\r
+    return ;\r
+  }\r
+\r
+  Name      = StrPtr;\r
+  VlanIdStr = NULL;\r
+  while (*StrPtr != 0) {\r
+    if (*StrPtr == L'.') {\r
+      *StrPtr   = 0;\r
+      VlanIdStr = StrPtr + 1;\r
+      break;\r
+    }\r
+\r
+    StrPtr++;\r
+  }\r
+\r
+  Handle = NicNameToHandle (Name);\r
+  if (Handle == NULL) {\r
+    goto Exit;\r
+  }\r
+\r
+  VlanConfig = OpenVlanConfigProtocol (Handle);\r
+  if (VlanConfig == NULL) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Check VLAN ID\r
+  //\r
+  if (VlanIdStr == NULL || *VlanIdStr == 0) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);\r
+    goto Exit;\r
+  }\r
+\r
+  VlanId = StrToVlanId (VlanIdStr);\r
+  if (VlanId > 4094) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Delete VLAN.\r
+  //\r
+  Status = VlanConfig->Remove (VlanConfig, (UINT16) VlanId);\r
+  if (EFI_ERROR (Status)) {\r
+    if (Status == EFI_NOT_FOUND) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NOT_FOUND), mHiiHandle);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_FAIL), mHiiHandle, Status);\r
+    }\r
+\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Check whether this is the last VLAN to remove.\r
+  //\r
+  Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // This is the last VLAN to remove, try to connect the controller handle.\r
+    //\r
+    gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
+  } else {\r
+    FreePool (VlanData);\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_SUCCESS), mHiiHandle);\r
+\r
+Exit:\r
+  if (VlanConfig != NULL) {\r
+    CloseVlanConfigProtocol (Handle);\r
+  }\r
+\r
+  FreePool (Name);\r
+}\r
+\r
+/**\r
+  The actual entry point for the application.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS       The entry point executed successfully.\r
+  @retval other             Some error occur when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VlanConfigMain (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  LIST_ENTRY    *List;\r
+  CONST CHAR16  *Str;\r
+\r
+  mImageHandle = ImageHandle;\r
+\r
+  //\r
+  // Register our string package to HII database.\r
+  //\r
+  mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, VConfigStrings, NULL);\r
+  if (mHiiHandle == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  List = NULL;\r
+  ShellCommandLineParseEx (mParamList, &List, NULL, FALSE, FALSE);\r
+  if (List == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);\r
+    goto Exit;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (List, L"-?")) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_HELP), mHiiHandle);\r
+    goto Exit;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (List, L"-l")) {\r
+    Str = ShellCommandLineGetValue (List, L"-l");\r
+    DisplayVlan ((CHAR16 *) Str);\r
+    goto Exit;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (List, L"-a")) {\r
+    Str = ShellCommandLineGetValue (List, L"-a");\r
+    AddVlan ((CHAR16 *) Str);\r
+    goto Exit;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (List, L"-d")) {\r
+    Str = ShellCommandLineGetValue (List, L"-d");\r
+    DeleteVlan ((CHAR16 *) Str);\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // No valid argument till now.\r
+  //\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);\r
+\r
+Exit:\r
+  if (List != NULL) {\r
+    ShellCommandLineFreeVarList (List);\r
+  }\r
+\r
+  //\r
+  // Remove our string package from HII database.\r
+  //\r
+  HiiRemovePackages (mHiiHandle);\r
+\r
+  return EFI_SUCCESS;\r
+}\r