git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11505 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1763 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1763 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   The implementation for ifcommand shell command.
 | |
| 
 | |
|   Copyright (c) 2006 - 2011, 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"
 | |
| 
 | |
| #define NIC_ITEM_CONFIG_SIZE   (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE)
 | |
| #define EFI_IP4_TO_U32(EfiIpAddr)   (*(IP4_ADDR*)((EfiIpAddr).Addr))
 | |
| 
 | |
| BOOLEAN                                 mIp4ConfigExist    = FALSE;
 | |
| STATIC EFI_HII_CONFIG_ROUTING_PROTOCOL  *mHiiConfigRouting = NULL;
 | |
| 
 | |
| STATIC CONST UINTN SecondsToNanoSeconds = 10000000;
 | |
| STATIC CONST CHAR16 DhcpString[5]       = L"DHCP";
 | |
| STATIC CONST CHAR16 StaticString[7]     = L"STATIC";
 | |
| STATIC CONST CHAR16 PermanentString[10] = L"PERMANENT";
 | |
| 
 | |
| typedef struct {
 | |
|   LIST_ENTRY                  Link;
 | |
|   EFI_HANDLE                  Handle;
 | |
|   NIC_ADDR                    NicAddress;
 | |
|   CHAR16                      Name[IP4_NIC_NAME_LENGTH];
 | |
|   BOOLEAN                     MediaPresentSupported;
 | |
|   BOOLEAN                     MediaPresent;
 | |
|   EFI_IP4_CONFIG_PROTOCOL     *Ip4Config;
 | |
|   NIC_IP4_CONFIG_INFO         *ConfigInfo;
 | |
| } NIC_INFO;
 | |
| 
 | |
| typedef struct {
 | |
|   EFI_IP_ADDRESS              DestIp;
 | |
|   EFI_MAC_ADDRESS             DestMac;
 | |
|   EFI_IP_ADDRESS              LocalIp;
 | |
|   EFI_MAC_ADDRESS             LocalMac;
 | |
|   UINT8                       MacLen;
 | |
|   EFI_EVENT                   OnResolved;
 | |
|   BOOLEAN                     Duplicate;
 | |
| } ARP_REQUEST;
 | |
| 
 | |
| STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 | |
|   {L"-c",     TypeValue},
 | |
|   {L"-l",     TypeValue},
 | |
|   {L"-s",     TypeMaxValue},
 | |
|   {NULL,      TypeMax}
 | |
|   };
 | |
| 
 | |
| STATIC LIST_ENTRY                  NicInfoList;
 | |
| STATIC BOOLEAN                     ArpResolved;
 | |
| STATIC BOOLEAN                     mTimeout;
 | |
| 
 | |
| /**
 | |
|   Count the space delimited items in a string.
 | |
| 
 | |
|   @param[in] String     A pointer to the string to count.
 | |
| 
 | |
|   @return The number of space-delimited items.
 | |
|   @retval 0xFF an error occured.
 | |
| **/
 | |
| UINT8
 | |
| EFIAPI
 | |
| CountSubItems (
 | |
|   IN CONST CHAR16 *String
 | |
|   )
 | |
| {
 | |
|   CONST CHAR16  *Walker;
 | |
|   UINT8         Count;
 | |
| 
 | |
|   if (String == NULL || *String == CHAR_NULL) {
 | |
|     return (0xFF);
 | |
|   }
 | |
| 
 | |
|   for (Walker = String, Count = 0 ; Walker != NULL && *Walker != CHAR_NULL ; Walker = (StrStr(Walker, L" ")==NULL?NULL:StrStr(Walker, L" ")+1), Count++);
 | |
|   return (Count);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Find the NIC_INFO by the specified nic name.
 | |
| 
 | |
|   @param[in] Name     The pointer to the string containing the NIC name.
 | |
|   
 | |
|   @return The pointer to the NIC_INFO if there is a NIC_INFO named by Name.
 | |
|   @retval NULL  No NIC_INFO was found for Name.
 | |
| **/
 | |
| NIC_INFO*
 | |
| EFIAPI
 | |
| IfconfigFindNicByName (
 | |
|   IN CONST CHAR16           *Name
 | |
|   )
 | |
| {
 | |
|   LIST_ENTRY                *Entry;
 | |
|   LIST_ENTRY                *NextEntry;
 | |
|   NIC_INFO                  *Info;
 | |
|   CHAR16                    *TempString;
 | |
| 
 | |
|   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &NicInfoList) {
 | |
|     Info = BASE_CR (Entry, NIC_INFO, Link);
 | |
|     TempString = (CHAR16*)Info->Name;
 | |
| 
 | |
|     if (StringNoCaseCompare (&Name, &TempString) == 0) {
 | |
|       return Info;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Tests whether a child handle is a child device of the controller.
 | |
| 
 | |
|   @param[in] ControllerHandle   A handle for a (parent) controller to test.
 | |
|   @param[in] ChildHandle        A child handle to test.
 | |
|   @param[in] ProtocolGuid       Supplies the protocol that the child controller
 | |
|                                 opens on its parent controller.
 | |
| 
 | |
|   @retval EFI_SUCCESS         ChildHandle is a child of the ControllerHandle.
 | |
|   @retval EFI_UNSUPPORTED     ChildHandle is not a child of the ControllerHandle.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| TestChildHandle (
 | |
|   IN CONST EFI_HANDLE       ControllerHandle,
 | |
|   IN CONST EFI_HANDLE       ChildHandle,
 | |
|   IN CONST EFI_GUID         *ProtocolGuid
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                            Status;
 | |
|   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY   *OpenInfoBuffer;
 | |
|   UINTN                                 EntryCount;
 | |
|   UINTN                                 Index;
 | |
| 
 | |
|   ASSERT (ProtocolGuid != NULL);
 | |
| 
 | |
|   //
 | |
|   // Retrieve the list of agents that are consuming the specific protocol
 | |
|   // on ControllerHandle.
 | |
|   //
 | |
|   Status = gBS->OpenProtocolInformation (
 | |
|                  ControllerHandle,
 | |
|                  (EFI_GUID *) ProtocolGuid,
 | |
|                  &OpenInfoBuffer,
 | |
|                  &EntryCount
 | |
|                  );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Inspect if ChildHandle is one of the agents.
 | |
|   //
 | |
|   Status = EFI_UNSUPPORTED;
 | |
|   for (Index = 0; Index < EntryCount; Index++) {
 | |
|     if ((OpenInfoBuffer[Index].ControllerHandle == ChildHandle) &&
 | |
|         (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
 | |
|       Status = EFI_SUCCESS;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   FreePool (OpenInfoBuffer);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get the child handle of the NIC handle.
 | |
| 
 | |
|   @param[in] Controller     Routing information: GUID.
 | |
|   @param[out] ChildHandle   Returned child handle.
 | |
| 
 | |
|   @retval EFI_SUCCESS         Successfully to get child handle.
 | |
| **/
 | |
| EFI_STATUS 
 | |
| GetChildHandle (
 | |
|   IN EFI_HANDLE         Controller,
 | |
|   OUT EFI_HANDLE        *ChildHandle
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                 Status;
 | |
|   EFI_HANDLE                 *Handles;
 | |
|   UINTN                      HandleCount;
 | |
|   UINTN                      Index;
 | |
|   EFI_DEVICE_PATH_PROTOCOL   *ChildDeviceDevicePath;
 | |
|   VENDOR_DEVICE_PATH         *VendorDeviceNode;
 | |
| 
 | |
|   //
 | |
|   // Locate all EFI Hii Config Access protocols
 | |
|   //
 | |
|   Status = gBS->LocateHandleBuffer (
 | |
|                  ByProtocol,
 | |
|                  &gEfiHiiConfigAccessProtocolGuid,
 | |
|                  NULL,
 | |
|                  &HandleCount,
 | |
|                  &Handles
 | |
|                  );
 | |
|   if (EFI_ERROR (Status) || (HandleCount == 0)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = EFI_NOT_FOUND;
 | |
| 
 | |
|   for (Index = 0; Index < HandleCount; Index++) {
 | |
|   
 | |
|     Status = TestChildHandle (Controller, Handles[Index], &gEfiManagedNetworkServiceBindingProtocolGuid);
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       //
 | |
|       // Get device path on the child handle
 | |
|       //
 | |
|       Status = gBS->HandleProtocol (
 | |
|                      Handles[Index],
 | |
|                      &gEfiDevicePathProtocolGuid,
 | |
|                      (VOID **) &ChildDeviceDevicePath
 | |
|                      );
 | |
|       
 | |
|       if (!EFI_ERROR (Status)) {
 | |
|         while (!IsDevicePathEnd (ChildDeviceDevicePath)) {
 | |
|           ChildDeviceDevicePath = NextDevicePathNode (ChildDeviceDevicePath);
 | |
|           //
 | |
|           // Parse one instance
 | |
|           //
 | |
|           if (ChildDeviceDevicePath->Type == HARDWARE_DEVICE_PATH && 
 | |
|               ChildDeviceDevicePath->SubType == HW_VENDOR_DP) {
 | |
|             VendorDeviceNode = (VENDOR_DEVICE_PATH *) ChildDeviceDevicePath;
 | |
|             if (CompareMem (&VendorDeviceNode->Guid, &gEfiNicIp4ConfigVariableGuid, sizeof (EFI_GUID)) == 0) {
 | |
|               //
 | |
|               // Found item matched gEfiNicIp4ConfigVariableGuid
 | |
|               //
 | |
|               *ChildHandle = Handles[Index];
 | |
|               FreePool (Handles);
 | |
|               return EFI_SUCCESS;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }      
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   FreePool (Handles);
 | |
|   return Status;  
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Append OFFSET/WIDTH/VALUE items at the beginning of string.
 | |
| 
 | |
|   @param[in,out]  String      The pointer to the string to append onto.
 | |
|   @param[in]      Offset      Offset value.
 | |
|   @param[in]      Width       Width value.
 | |
|   @param[in]      Block       Point to data buffer.
 | |
| 
 | |
|   @return The count of unicode character that were appended.
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| AppendOffsetWidthValue (
 | |
|   IN OUT CHAR16               *String,
 | |
|   IN UINTN                    Offset,
 | |
|   IN UINTN                    Width,
 | |
|   IN CONST UINT8              *Block
 | |
|   )
 | |
| 
 | |
| {
 | |
|   CHAR16                      *OriString;
 | |
| 
 | |
|   OriString = String;
 | |
| 
 | |
|   StrCpy (String, L"&OFFSET=");
 | |
|   String += StrLen (L"&OFFSET=");
 | |
|   String += UnicodeSPrint (String, 20, L"%x", Offset);
 | |
| 
 | |
|   StrCpy (String,L"&WIDTH=");
 | |
|   String += StrLen (L"&WIDTH=");
 | |
|   String += UnicodeSPrint (String, 20, L"%x", Width);
 | |
| 
 | |
|   if (Block != NULL) {
 | |
|     StrCpy (String,L"&VALUE=");
 | |
|     String += StrLen (L"&VALUE=");
 | |
|     while ((Width--) != 0) {
 | |
|       String += UnicodeSPrint (String, 20, L"%x", Block[Width]);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   return String - OriString;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Converts the unicode character of the string from uppercase to lowercase.
 | |
|   This is a internal function.
 | |
| 
 | |
|   @param ConfigString  String to be converted
 | |
| **/
 | |
| CHAR16* 
 | |
| EFIAPI
 | |
| HiiToLower (
 | |
|   IN CHAR16   *ConfigString
 | |
|   )
 | |
| {
 | |
|   CHAR16      *String;
 | |
|   BOOLEAN     Lower;
 | |
| 
 | |
|   //
 | |
|   // Convert all hex digits in range [A-F] in the configuration header to [a-f]
 | |
|   //
 | |
|   for (String = ConfigString, Lower = FALSE; String != NULL && *String != L'\0'; String++) {
 | |
|     if (*String == L'=') {
 | |
|       Lower = TRUE;
 | |
|     } else if (*String == L'&') {
 | |
|       Lower = FALSE;
 | |
|     } else if (Lower && *String >= L'A' && *String <= L'F') {
 | |
|       *String = (CHAR16) (*String - L'A' + L'a');
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (ConfigString);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Construct <ConfigHdr> using routing information GUID/NAME/PATH.
 | |
| 
 | |
|   @param[in] Guid         Routing information: GUID.
 | |
|   @param[in] Name         Routing information: NAME.
 | |
|   @param[in] DriverHandle Driver handle which contains the routing information: PATH.
 | |
| 
 | |
|   @retval NULL            An error occured.
 | |
|   @return                 The pointer to configHdr string.
 | |
| **/
 | |
| CHAR16 *
 | |
| EFIAPI
 | |
| ConstructConfigHdr (
 | |
|   IN CONST EFI_GUID          *Guid,
 | |
|   IN CONST CHAR16            *Name,
 | |
|   IN EFI_HANDLE              DriverHandle
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                 Status;
 | |
|   CHAR16                     *ConfigHdr;
 | |
|   EFI_DEVICE_PATH_PROTOCOL   *DevicePath;
 | |
|   CHAR16                     *String;
 | |
|   UINTN                      Index;
 | |
|   UINT8                      *Buffer;
 | |
|   UINTN                      DevicePathLength;
 | |
|   UINTN                      NameLength;
 | |
| 
 | |
|   //
 | |
|   // Get the device path from handle installed EFI HII Config Access protocol
 | |
|   //
 | |
|   Status = gBS->HandleProtocol (
 | |
|                  DriverHandle,
 | |
|                  &gEfiDevicePathProtocolGuid,
 | |
|                  (VOID **) &DevicePath
 | |
|                  );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   DevicePathLength = GetDevicePathSize (DevicePath);
 | |
|   NameLength = StrLen (Name);
 | |
|   ConfigHdr = AllocateZeroPool ((5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathLength * 2 + 1) * sizeof (CHAR16));
 | |
|   if (ConfigHdr == NULL) {
 | |
|     return NULL;
 | |
|   } 
 | |
| 
 | |
|   String = ConfigHdr;
 | |
|   StrCpy (String, L"GUID=");
 | |
|   String += StrLen (L"GUID=");
 | |
| 
 | |
|   //
 | |
|   // Append Guid converted to <HexCh>32
 | |
|   //
 | |
|   for (Index = 0, Buffer = (UINT8 *)Guid; Index < sizeof (EFI_GUID); Index++) {
 | |
|     String += UnicodeSPrint (String, 6, L"%02x", *Buffer++);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Append L"&NAME="
 | |
|   //
 | |
|   StrCpy (String, L"&NAME=");
 | |
|   String += StrLen (L"&NAME=");
 | |
|   for (Index = 0; Index < NameLength ; Index++) {
 | |
|     String += UnicodeSPrint (String, 10, L"00%x", Name[Index]);
 | |
|   }
 | |
|   
 | |
|   //
 | |
|   // Append L"&PATH="
 | |
|   //
 | |
|   StrCpy (String, L"&PATH=");
 | |
|   String += StrLen (L"&PATH=");
 | |
|   for (Index = 0, Buffer = (UINT8 *) DevicePath; Index < DevicePathLength; Index++) {
 | |
|     String += UnicodeSPrint (String, 6, L"%02x", *Buffer++);
 | |
|   }
 | |
| 
 | |
|   return (HiiToLower(ConfigHdr));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get network physical device NIC information.
 | |
| 
 | |
|   @param[in] Handle         The network physical device handle.
 | |
|   @param[out] NicAddr       NIC information.
 | |
| 
 | |
|   @retval EFI_SUCCESS         Get NIC information successfully.
 | |
| **/                  
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IfConfigGetNicMacInfo (
 | |
|   IN  EFI_HANDLE                    Handle,
 | |
|   OUT NIC_ADDR                      *NicAddr
 | |
|   )    
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   EFI_HANDLE                    MnpHandle;
 | |
|   EFI_SIMPLE_NETWORK_MODE       SnpMode;
 | |
|   EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;
 | |
| 
 | |
|   MnpHandle = NULL;
 | |
|   Mnp       = NULL;
 | |
| 
 | |
|   Status = NetLibCreateServiceChild (
 | |
|              Handle,
 | |
|              gImageHandle, 
 | |
|              &gEfiManagedNetworkServiceBindingProtocolGuid,
 | |
|              &MnpHandle
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->HandleProtocol (
 | |
|                   MnpHandle,
 | |
|                   &gEfiManagedNetworkProtocolGuid,
 | |
|                   (VOID **) &Mnp
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_ERROR;
 | |
|   }
 | |
| 
 | |
|   Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
 | |
|   if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
 | |
|     goto ON_ERROR;
 | |
|   }
 | |
|  
 | |
|   NicAddr->Type    = (UINT16) SnpMode.IfType;
 | |
|   NicAddr->Len     = (UINT8) SnpMode.HwAddressSize;
 | |
|   CopyMem (&NicAddr->MacAddr, &SnpMode.CurrentAddress, NicAddr->Len);
 | |
| 
 | |
| ON_ERROR:
 | |
| 
 | |
|   NetLibDestroyServiceChild (
 | |
|     Handle,
 | |
|     gImageHandle, 
 | |
|     &gEfiManagedNetworkServiceBindingProtocolGuid,
 | |
|     MnpHandle
 | |
|     );
 | |
| 
 | |
|   return Status;
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get network physical device NIC information.
 | |
| 
 | |
|   @param[in] Handle         The network physical device handle.
 | |
|   @param[out] MediaPresentSupported
 | |
|                             Upon successful return, TRUE is media present 
 | |
|                             is supported.  FALSE otherwise.
 | |
|   @param[out] MediaPresent  Upon successful return, TRUE is media present 
 | |
|                             is enabled.  FALSE otherwise.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The operation was successful.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IfConfigGetNicMediaStatus (
 | |
|   IN  EFI_HANDLE                    Handle,
 | |
|   OUT BOOLEAN                       *MediaPresentSupported,
 | |
|   OUT BOOLEAN                       *MediaPresent
 | |
|   )    
 | |
|                   
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   EFI_HANDLE                    MnpHandle;
 | |
|   EFI_SIMPLE_NETWORK_MODE       SnpMode;
 | |
|   EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;
 | |
| 
 | |
|   MnpHandle = NULL;
 | |
|   Mnp       = NULL;
 | |
| 
 | |
|   Status = NetLibCreateServiceChild (
 | |
|              Handle,
 | |
|              gImageHandle, 
 | |
|              &gEfiManagedNetworkServiceBindingProtocolGuid,
 | |
|              &MnpHandle
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->HandleProtocol (
 | |
|                   MnpHandle,
 | |
|                   &gEfiManagedNetworkProtocolGuid,
 | |
|                   (VOID **) &Mnp
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_ERROR;
 | |
|   }
 | |
| 
 | |
|   Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
 | |
|   if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
 | |
|     goto ON_ERROR;
 | |
|   }
 | |
|  
 | |
|   *MediaPresentSupported = SnpMode.MediaPresentSupported;
 | |
|   *MediaPresent = SnpMode.MediaPresent;
 | |
| 
 | |
| ON_ERROR:
 | |
| 
 | |
|   NetLibDestroyServiceChild (
 | |
|     Handle,
 | |
|     gImageHandle, 
 | |
|     &gEfiManagedNetworkServiceBindingProtocolGuid,
 | |
|     MnpHandle
 | |
|     );
 | |
| 
 | |
|   return Status;
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get all Nic's information through HII service.
 | |
| 
 | |
|   @retval EFI_SUCCESS         All the nic information is collected.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IfconfigGetAllNicInfoByHii (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   EFI_HANDLE                    *Handles;
 | |
|   UINTN                         HandleCount;
 | |
|   CHAR16                        *ConfigResp;
 | |
|   CHAR16                        *ConfigHdr;
 | |
|   UINTN                         Index;
 | |
|   CHAR16                        *AccessProgress;
 | |
|   CHAR16                        *AccessResults;
 | |
|   UINTN                         BufferSize;
 | |
|   NIC_INFO                      *NicInfo;
 | |
|   NIC_IP4_CONFIG_INFO           *NicConfigRequest;
 | |
|   NIC_IP4_CONFIG_INFO           *NicConfig;
 | |
|   CHAR16                        *String;
 | |
|   UINTN                         Length;
 | |
|   UINTN                         Offset;
 | |
|   EFI_HANDLE                    ChildHandle;
 | |
| 
 | |
|   AccessResults    = NULL;
 | |
|   ConfigHdr        = NULL;
 | |
|   ConfigResp       = NULL;
 | |
|   NicConfigRequest = NULL;
 | |
|   NicInfo          = NULL;
 | |
| 
 | |
|   InitializeListHead (&NicInfoList);
 | |
| 
 | |
|   //
 | |
|   // Check if HII Config Routing protocol available.
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (
 | |
|                 &gEfiHiiConfigRoutingProtocolGuid,
 | |
|                 NULL,
 | |
|                 (VOID**)&mHiiConfigRouting
 | |
|                 );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Locate all network device handles
 | |
|   //
 | |
|   Status = gBS->LocateHandleBuffer (
 | |
|                  ByProtocol,
 | |
|                  &gEfiManagedNetworkServiceBindingProtocolGuid,
 | |
|                  NULL,
 | |
|                  &HandleCount,
 | |
|                  &Handles
 | |
|                  );
 | |
|   if (EFI_ERROR (Status) || (HandleCount == 0)) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < HandleCount; Index++) {
 | |
|     Status = GetChildHandle (Handles[Index], &ChildHandle);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       //
 | |
|       // If failed to get Child handle, try NIC controller handle for back-compatibility.
 | |
|       //
 | |
|       ChildHandle = Handles[Index];
 | |
|     }
 | |
|     //
 | |
|     // Construct configuration request string header
 | |
|     //
 | |
|     ConfigHdr = ConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, ChildHandle);
 | |
|     if (ConfigHdr != NULL) {
 | |
|       Length = StrLen (ConfigHdr);
 | |
|     } else {
 | |
|       Length = 0;
 | |
|     }
 | |
|     ConfigResp = AllocateZeroPool ((Length + NIC_ITEM_CONFIG_SIZE * 2 + 100) * sizeof (CHAR16));
 | |
|     if (ConfigResp == NULL) {
 | |
|       Status = EFI_OUT_OF_RESOURCES;
 | |
|       goto ON_ERROR;
 | |
|     }
 | |
|     if (ConfigHdr != NULL) {
 | |
|       StrCpy (ConfigResp, ConfigHdr);
 | |
|     }
 | |
|  
 | |
|     //
 | |
|     // Append OFFSET/WIDTH pair
 | |
|     //
 | |
|     String = ConfigResp + Length;
 | |
|     Offset = 0;
 | |
|     AppendOffsetWidthValue (String, Offset, NIC_ITEM_CONFIG_SIZE, NULL);
 | |
| 
 | |
|     NicInfo = AllocateZeroPool (sizeof (NIC_INFO));
 | |
|     if (NicInfo == NULL) {
 | |
|       Status = EFI_OUT_OF_RESOURCES;
 | |
|       goto ON_ERROR;
 | |
|     }
 | |
|     NicInfo->Handle       = Handles[Index];
 | |
| 
 | |
|     //
 | |
|     // Get network physical devcie MAC information
 | |
|     //
 | |
|     IfConfigGetNicMacInfo (Handles[Index], &NicInfo->NicAddress);
 | |
|     if (NicInfo->NicAddress.Type == NET_IFTYPE_ETHERNET) {
 | |
|       UnicodeSPrint (NicInfo->Name, IP4_NIC_NAME_LENGTH, L"eth%d", Index);
 | |
|     } else {
 | |
|       UnicodeSPrint (NicInfo->Name, IP4_NIC_NAME_LENGTH, L"unk%d", Index);
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Get media status
 | |
|     //
 | |
|     IfConfigGetNicMediaStatus (Handles[Index], &NicInfo->MediaPresentSupported, &NicInfo->MediaPresent);
 | |
| 
 | |
|     NicConfigRequest = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);
 | |
|     if (NicConfigRequest == NULL) {
 | |
|       Status = EFI_OUT_OF_RESOURCES;
 | |
|       goto ON_ERROR;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Get network parameters by HII service
 | |
|     //
 | |
|     Status = mHiiConfigRouting->ExtractConfig (
 | |
|                                   mHiiConfigRouting,
 | |
|                                   ConfigResp,
 | |
|                                   &AccessProgress,
 | |
|                                   &AccessResults
 | |
|                                   );
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       BufferSize = NIC_ITEM_CONFIG_SIZE;
 | |
|       Status = mHiiConfigRouting->ConfigToBlock (
 | |
|                                     mHiiConfigRouting,
 | |
|                                     AccessResults,
 | |
|                                     (UINT8 *) NicConfigRequest,
 | |
|                                     &BufferSize,
 | |
|                                     &AccessProgress
 | |
|                                     );
 | |
|       if (!EFI_ERROR (Status)) {
 | |
|         BufferSize = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * NicConfigRequest->Ip4Info.RouteTableSize;
 | |
|         NicConfig = AllocateZeroPool (BufferSize);
 | |
|         if (NicConfig == NULL) {
 | |
|           Status = EFI_OUT_OF_RESOURCES;
 | |
|           goto ON_ERROR;
 | |
|         }
 | |
|         CopyMem (NicConfig, NicConfigRequest, BufferSize);
 | |
| 
 | |
|         //
 | |
|         // If succeeds to get NIC configuration, fix up routetable pointer.
 | |
|         //
 | |
|         NicConfig->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (&NicConfig->Ip4Info + 1);
 | |
|         NicInfo->ConfigInfo   = NicConfig;
 | |
| 
 | |
|       } else {
 | |
|         NicInfo->ConfigInfo   = NULL;
 | |
|       }
 | |
| 
 | |
|       FreePool (AccessResults);
 | |
| 
 | |
|     } else {
 | |
|       NicInfo->ConfigInfo   = NULL;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Add the Nic's info to the global NicInfoList.
 | |
|     //
 | |
|     InsertTailList (&NicInfoList, &NicInfo->Link);
 | |
| 
 | |
|     FreePool (NicConfigRequest);
 | |
|     FreePool (ConfigResp);
 | |
|     FreePool (ConfigHdr);
 | |
|   }
 | |
| 
 | |
|   FreePool (Handles);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
|  
 | |
| ON_ERROR:
 | |
|   if (AccessResults != NULL) {
 | |
|     FreePool (AccessResults);
 | |
|   }
 | |
|   if (NicConfigRequest != NULL) {
 | |
|     FreePool (NicConfigRequest);
 | |
|   }
 | |
|   if (NicInfo != NULL) {
 | |
|     FreePool (NicInfo);
 | |
|   }
 | |
|   if (ConfigResp != NULL) {
 | |
|     FreePool (ConfigResp);
 | |
|   }
 | |
|   if (ConfigHdr != NULL) {
 | |
|     FreePool (ConfigHdr);
 | |
|   }
 | |
| 
 | |
|   FreePool (Handles);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Set the address for the specified nic by HII service.
 | |
| 
 | |
|   @param[in] NicInfo    A pointer to the NIC_INFO of the Nic to be configured.
 | |
|   @param[in] Config     The command line arguments for the set operation.
 | |
| 
 | |
|   @retval EFI_SUCCESS         The address set operation is done.
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| IfconfigSetNicAddrByHii (
 | |
|   IN CONST NIC_INFO                 *NicInfo,
 | |
|   IN CONST NIC_IP4_CONFIG_INFO      *Config
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   SHELL_STATUS                  ShellStatus;
 | |
|   NIC_IP4_CONFIG_INFO           *NicConfig;
 | |
|   CHAR16                        *ConfigResp;
 | |
|   CHAR16                        *ConfigHdr;
 | |
|   CHAR16                        *AccessProgress;
 | |
|   CHAR16                        *AccessResults;
 | |
|   CHAR16                        *String;
 | |
|   UINTN                         Length;
 | |
|   UINTN                         Offset;
 | |
|   EFI_HANDLE                    ChildHandle;
 | |
| 
 | |
|   AccessResults  = NULL;
 | |
|   ConfigHdr      = NULL;
 | |
|   ConfigResp     = NULL;
 | |
|   NicConfig      = NULL;
 | |
|   ShellStatus    = SHELL_SUCCESS;
 | |
| 
 | |
|   Status = GetChildHandle (NicInfo->Handle, &ChildHandle);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     //
 | |
|     // If failed to get Child handle, try NIC controller handle for back-compatibility
 | |
|     //
 | |
|     ChildHandle = NicInfo->Handle;
 | |
|   }
 | |
|   //
 | |
|   // Construct config request string header
 | |
|   //
 | |
|   ConfigHdr = ConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, ChildHandle);
 | |
|   if (ConfigHdr != NULL) {
 | |
|     Length = StrLen (ConfigHdr);
 | |
|   } else {
 | |
|     ShellStatus = SHELL_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
|   ConfigResp = AllocateZeroPool ((Length + NIC_ITEM_CONFIG_SIZE * 2 + 100) * sizeof (CHAR16));
 | |
|   if (ConfigResp == NULL) {
 | |
|     ShellStatus = SHELL_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
|   if (ConfigHdr != NULL) {
 | |
|     StrCpy (ConfigResp, ConfigHdr);
 | |
|   }
 | |
| 
 | |
|   NicConfig = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);
 | |
|   if (NicConfig == NULL) {
 | |
|     ShellStatus = SHELL_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   if (Config != NULL) {
 | |
|     CopyMem (NicConfig, Config, sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * Config->Ip4Info.RouteTableSize);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Append OFFSET/WIDTH pair
 | |
|   //
 | |
|   String = ConfigResp + Length;
 | |
|   Offset = 0;
 | |
|   AppendOffsetWidthValue (String, Offset, NIC_ITEM_CONFIG_SIZE, NULL);
 | |
| 
 | |
|   //
 | |
|   // Call HII helper function to generate configuration string
 | |
|   //
 | |
|   Status = mHiiConfigRouting->BlockToConfig (
 | |
|                                 mHiiConfigRouting,
 | |
|                                 ConfigResp,
 | |
|                                 (UINT8 *) NicConfig,
 | |
|                                 NIC_ITEM_CONFIG_SIZE,
 | |
|                                 &AccessResults,
 | |
|                                 &AccessProgress
 | |
|                                 );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ShellStatus = SHELL_NOT_FOUND;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Set IP setting by HII servie
 | |
|   //
 | |
|   Status = mHiiConfigRouting->RouteConfig (
 | |
|                                 mHiiConfigRouting,
 | |
|                                 AccessResults,
 | |
|                                 &AccessProgress
 | |
|                                 );
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     ShellStatus = SHELL_ACCESS_DENIED;
 | |
|   }
 | |
| 
 | |
| ON_EXIT:
 | |
|   SHELL_FREE_NON_NULL(AccessResults);
 | |
|   SHELL_FREE_NON_NULL(NicConfig);
 | |
|   SHELL_FREE_NON_NULL(ConfigResp);
 | |
|   SHELL_FREE_NON_NULL(ConfigHdr);
 | |
| 
 | |
|   return ShellStatus;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   The callback function for the Arp address resolved event.
 | |
| 
 | |
|   @param[in] Event    The event this function is registered to.
 | |
|   @param[in] Context  The context registered to the event.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| IfconfigOnArpResolved (
 | |
|   IN EFI_EVENT                  Event,
 | |
|   IN VOID                       *Context
 | |
|   )
 | |
| {
 | |
|   ARP_REQUEST                   *Request;
 | |
|   UINT8                         Index;
 | |
| 
 | |
|   Request = (ARP_REQUEST *) Context;
 | |
|   ASSERT (Request != NULL);
 | |
| 
 | |
|   Request->Duplicate = FALSE;
 | |
|   
 | |
|   if (0 == CompareMem (&Request->LocalMac, &Request->DestMac, Request->MacLen)) {
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL,
 | |
|       STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|       gShellNetwork1HiiHandle, 
 | |
|       L"Already Configured",
 | |
|       (UINTN)Request->DestIp.v4.Addr[0],
 | |
|       (UINTN)Request->DestIp.v4.Addr[1],
 | |
|       (UINTN)Request->DestIp.v4.Addr[2],
 | |
|       (UINTN)Request->DestIp.v4.Addr[3]
 | |
|       );
 | |
|     ArpResolved = TRUE;
 | |
|     return;
 | |
|   }
 | |
|   
 | |
|   for (Index = 0; Index < Request->MacLen; Index++) {
 | |
|     if (Request->DestMac.Addr[Index] != 0) {
 | |
|       Request->Duplicate = TRUE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (Request->Duplicate) {
 | |
|     ShellPrintHiiEx(
 | |
|     -1,
 | |
|     -1,
 | |
|     NULL,
 | |
|     STRING_TOKEN(STR_IFCONFIG_CONF_IP_ADDR), 
 | |
|     gShellNetwork1HiiHandle, 
 | |
|     (UINTN)Request->DestMac.Addr[0], 
 | |
|     (UINTN)Request->DestMac.Addr[1], 
 | |
|     (UINTN)Request->DestMac.Addr[2],
 | |
|     (UINTN)Request->DestMac.Addr[3], 
 | |
|     (UINTN)Request->DestMac.Addr[4], 
 | |
|     (UINTN)Request->DestMac.Addr[5]
 | |
|     );    
 | |
|   }
 | |
| 
 | |
|   ArpResolved = TRUE;
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Check whether the address to be configured conflicts with other hosts.
 | |
| 
 | |
|   @param[in] NicInfo    The pointer to the NIC_INFO of the Nic to be configured.
 | |
|   @param[in] IpAddr     The IPv4 address to be configured to the Nic.
 | |
| 
 | |
|   @return TRUE      Some other host already uses the IpAddr.
 | |
|   @return FALSE     The address is unused.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| IfconfigIsIpDuplicate (
 | |
|   IN  NIC_INFO                  *NicInfo,
 | |
|   IN  IP4_ADDR                  IpAddr
 | |
|   )
 | |
| {
 | |
|   EFI_ARP_PROTOCOL              *Arp;
 | |
|   EFI_ARP_CONFIG_DATA           ArpCfgData;
 | |
|   EFI_HANDLE                    ArpHandle;
 | |
|   ARP_REQUEST                   Request;
 | |
|   EFI_STATUS                    Status;
 | |
| 
 | |
|   Arp           = NULL;
 | |
|   ArpHandle     = NULL;
 | |
|   ZeroMem (&Request, sizeof (ARP_REQUEST));
 | |
| 
 | |
|   Status = NetLibCreateServiceChild (
 | |
|              NicInfo->Handle,
 | |
|              gImageHandle, 
 | |
|              &gEfiArpServiceBindingProtocolGuid,
 | |
|              &ArpHandle
 | |
|              );
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                  ArpHandle,
 | |
|                  &gEfiArpProtocolGuid,
 | |
|                  (VOID**)&Arp,
 | |
|                  gImageHandle,
 | |
|                  ArpHandle,
 | |
|                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                  );
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Set up the Arp requests
 | |
|   //
 | |
|   EFI_IP4_TO_U32 (Request.DestIp.v4)  = IpAddr;
 | |
|   EFI_IP4_TO_U32 (Request.LocalIp.v4) = 0xffffffff;
 | |
|   Request.LocalMac                    = NicInfo->NicAddress.MacAddr;
 | |
|   Request.MacLen                      = NicInfo->NicAddress.Len;
 | |
|   
 | |
|   Status = gBS->CreateEvent (
 | |
|                  EVT_NOTIFY_SIGNAL,
 | |
|                  TPL_CALLBACK,
 | |
|                  IfconfigOnArpResolved,
 | |
|                  (VOID *) &Request,
 | |
|                  &Request.OnResolved
 | |
|                  );
 | |
|   
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
|   
 | |
|   ArpCfgData.SwAddressType    = 0x0800;
 | |
|   ArpCfgData.SwAddressLength  = 4;
 | |
|   ArpCfgData.StationAddress   = &Request.LocalIp;
 | |
|   ArpCfgData.EntryTimeOut     = 0;
 | |
|   ArpCfgData.RetryCount       = 3;
 | |
|   ArpCfgData.RetryTimeOut     = 0;
 | |
|   
 | |
|   Status = Arp->Configure (Arp, &ArpCfgData);
 | |
|   
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = Arp->Request (
 | |
|                   Arp,
 | |
|                   &Request.DestIp,
 | |
|                   Request.OnResolved,
 | |
|                   &Request.DestMac
 | |
|                   );
 | |
|   
 | |
|   if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   while (!ArpResolved) {
 | |
|     
 | |
|   }
 | |
| 
 | |
| ON_EXIT:
 | |
|   if (Request.OnResolved != NULL) {
 | |
|     gBS->CloseEvent (Request.OnResolved);
 | |
|   }
 | |
| 
 | |
|   NetLibDestroyServiceChild (
 | |
|     NicInfo->Handle, 
 | |
|     gImageHandle, 
 | |
|     &gEfiArpServiceBindingProtocolGuid, 
 | |
|     ArpHandle
 | |
|     );
 | |
| 
 | |
|   return Request.Duplicate;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   The callback function for the timer event used to get map.
 | |
| 
 | |
|   @param[in] Event    The event this function is registered to.
 | |
|   @param[in] Context  The context registered to the event.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| TimeoutToGetMap (
 | |
|   IN EFI_EVENT      Event,
 | |
|   IN VOID           *Context
 | |
|   )
 | |
| {
 | |
|   mTimeout = TRUE;
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create an IP child, use it to start the auto configuration, then destory it.
 | |
| 
 | |
|   @param[in] NicInfo    The pointer to the NIC_INFO of the Nic to be configured.
 | |
| 
 | |
|   @retval EFI_SUCCESS         The configuration is done.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IfconfigStartIp4(
 | |
|   IN NIC_INFO                   *NicInfo
 | |
|   )
 | |
| {
 | |
|   EFI_IP4_PROTOCOL              *Ip4;
 | |
|   EFI_HANDLE                    Ip4Handle;
 | |
|   EFI_HANDLE                    TimerToGetMap;
 | |
|   EFI_IP4_CONFIG_DATA           Ip4ConfigData;
 | |
|   EFI_IP4_MODE_DATA             Ip4Mode;
 | |
|   EFI_STATUS                    Status;
 | |
| 
 | |
|   //
 | |
|   // Get the Ip4ServiceBinding Protocol
 | |
|   //
 | |
|   Ip4Handle     = NULL;
 | |
|   Ip4           = NULL;
 | |
|   TimerToGetMap = NULL;
 | |
| 
 | |
|   ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_START_SET_ADDR), gShellNetwork1HiiHandle);
 | |
| 
 | |
|   Status = NetLibCreateServiceChild (
 | |
|              NicInfo->Handle,
 | |
|              gImageHandle,
 | |
|              &gEfiIp4ServiceBindingProtocolGuid,
 | |
|              &Ip4Handle
 | |
|              );
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                  Ip4Handle,
 | |
|                  &gEfiIp4ProtocolGuid,
 | |
|                  (VOID **) &Ip4,
 | |
|                  NicInfo->Handle,
 | |
|                  gImageHandle,
 | |
|                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                  );
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Ip4ConfigData.DefaultProtocol          = EFI_IP_PROTO_ICMP;
 | |
|   Ip4ConfigData.AcceptAnyProtocol        = FALSE;
 | |
|   Ip4ConfigData.AcceptIcmpErrors         = FALSE;
 | |
|   Ip4ConfigData.AcceptBroadcast          = FALSE;
 | |
|   Ip4ConfigData.AcceptPromiscuous        = FALSE;
 | |
|   Ip4ConfigData.UseDefaultAddress        = TRUE;
 | |
|   ZeroMem (&Ip4ConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
 | |
|   ZeroMem (&Ip4ConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
 | |
|   Ip4ConfigData.TypeOfService            = 0;
 | |
|   Ip4ConfigData.TimeToLive               = 1;
 | |
|   Ip4ConfigData.DoNotFragment            = FALSE;
 | |
|   Ip4ConfigData.RawData                  = FALSE;
 | |
|   Ip4ConfigData.ReceiveTimeout           = 0;
 | |
|   Ip4ConfigData.TransmitTimeout          = 0;
 | |
| 
 | |
|   Status = Ip4->Configure (Ip4, &Ip4ConfigData);
 | |
| 
 | |
|   if (Status == EFI_NO_MAPPING) {
 | |
|     mTimeout = FALSE;
 | |
|     Status  = gBS->CreateEvent (
 | |
|                     EVT_NOTIFY_SIGNAL | EVT_TIMER,
 | |
|                     TPL_CALLBACK - 1,
 | |
|                     TimeoutToGetMap,
 | |
|                     NULL,
 | |
|                     &TimerToGetMap
 | |
|                     );
 | |
|     
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
|     
 | |
|     Status = gBS->SetTimer (
 | |
|                    TimerToGetMap,
 | |
|                    TimerRelative,
 | |
|                    MultU64x32 (SecondsToNanoSeconds, 5)
 | |
|                    );
 | |
|     
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_WAIT_SET_DONE), gShellNetwork1HiiHandle);
 | |
|     
 | |
|     while (!mTimeout) {
 | |
|       Ip4->Poll (Ip4);
 | |
|   
 | |
|       if (!EFI_ERROR (Ip4->GetModeData (Ip4, &Ip4Mode, NULL, NULL)) && 
 | |
|           Ip4Mode.IsConfigured) {       
 | |
|         break;
 | |
|       }
 | |
|     }    
 | |
|   }
 | |
| 
 | |
|   Status = Ip4->GetModeData (Ip4, &Ip4Mode, NULL, NULL);
 | |
| 
 | |
|   if ((Status == EFI_SUCCESS) && Ip4Mode.IsConfigured) {
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL,
 | |
|       STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|       gShellNetwork1HiiHandle, 
 | |
|       L"Default",
 | |
|       (UINTN)Ip4Mode.ConfigData.StationAddress.Addr[0],
 | |
|       (UINTN)Ip4Mode.ConfigData.StationAddress.Addr[1],
 | |
|       (UINTN)Ip4Mode.ConfigData.StationAddress.Addr[2],
 | |
|       (UINTN)Ip4Mode.ConfigData.StationAddress.Addr[3]
 | |
|       );
 | |
|   }
 | |
|   
 | |
| ON_EXIT: 
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_GET_DEF_ADDR_FAIL), gShellNetwork1HiiHandle);
 | |
|   }
 | |
| 
 | |
|   if (TimerToGetMap != NULL) {
 | |
|     gBS->SetTimer (TimerToGetMap, TimerCancel, 0);
 | |
|     gBS->CloseEvent (TimerToGetMap);
 | |
|   }
 | |
| 
 | |
|   NetLibDestroyServiceChild (
 | |
|     NicInfo->Handle,
 | |
|     gImageHandle,
 | |
|     &gEfiIp4ServiceBindingProtocolGuid,
 | |
|     Ip4Handle
 | |
|     );
 | |
|   
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Set the address for the nic specified by the params.
 | |
| 
 | |
|   @param[in] Argc       The count of the passed in Params.
 | |
|   @param[in] Params     The command line arguments for the set operation.
 | |
| 
 | |
|   @retval EFI_SUCCESS   The address set operation is done.
 | |
|   @return               Some error occurs.
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| IfconfigSetNicAddr (
 | |
|   IN UINTN                      Argc,
 | |
|   IN CONST CHAR16               *Params
 | |
|   )
 | |
| {
 | |
|   NIC_IP4_CONFIG_INFO           *Config;
 | |
|   NIC_IP4_CONFIG_INFO           *OldConfig;
 | |
|   EFI_IP_ADDRESS                Ip;
 | |
|   EFI_IP_ADDRESS                Mask;
 | |
|   EFI_IP_ADDRESS                Gateway;
 | |
|   NIC_INFO                      *Info;
 | |
|   BOOLEAN                       Permanent;
 | |
|   SHELL_STATUS                  ShellStatus;
 | |
|   CONST CHAR16                  *Walker;
 | |
|   CHAR16                        *Temp;
 | |
|   CONST CHAR16                  *DhcpTemp;
 | |
|   CONST CHAR16                  *StaticTemp;
 | |
|   CONST CHAR16                  *PermTemp;
 | |
|   UINT32                        NetworkBytes1;
 | |
|   UINT32                        NetworkBytes2;
 | |
|   EFI_STATUS                    Status;
 | |
| 
 | |
|   Walker  = Params;
 | |
|   Temp    = NULL;
 | |
|   Temp    = StrnCatGrow(&Temp, NULL, Walker, StrStr(Walker, L" ")-Walker);
 | |
|   Info    = IfconfigFindNicByName (Temp);
 | |
| 
 | |
|   if (Info == NULL) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INTERFACE_NOT_FOUND), gShellNetwork1HiiHandle, Temp);
 | |
|     return SHELL_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   Walker  += StrLen(Temp) + 1;
 | |
|   FreePool(Temp);
 | |
|   Temp = NULL;
 | |
|   Temp    = StrnCatGrow(&Temp, NULL, Walker, StrStr(Walker, L" ")==NULL?0:StrStr(Walker, L" ")-Walker);
 | |
| 
 | |
|   Config = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE));
 | |
|   if (Config == NULL) {
 | |
|     return SHELL_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   Config->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (Config + 1);
 | |
| 
 | |
|   OldConfig = Info->ConfigInfo;
 | |
|   Permanent   = FALSE;
 | |
|   ShellStatus = SHELL_INVALID_PARAMETER;
 | |
| 
 | |
|   DhcpTemp = DhcpString;
 | |
|   StaticTemp = StaticString;
 | |
|   
 | |
|   if (StringNoCaseCompare(&Temp, &DhcpTemp) == 0) {
 | |
|     //
 | |
|     // Validate the parameter for DHCP, two valid forms: eth0 DHCP and eth0 DHCP perment
 | |
|     //
 | |
|     if ((Argc != 2) && (Argc!= 3)) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellNetwork1HiiHandle, Temp);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     if (Argc == 3) {
 | |
|       Walker  += StrLen(Temp) + 1;
 | |
|       FreePool(Temp);
 | |
|       Temp    = NULL;
 | |
|       Temp    = StrnCatGrow(&Temp, NULL, Walker, 0);
 | |
| 
 | |
|       PermTemp = PermanentString;
 | |
|       if (StringNoCaseCompare(&Temp, &PermTemp) != 0) {
 | |
|         ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_GEN_PROBLEM_OP2), gShellNetwork1HiiHandle, Temp, PermanentString, L"Nothing");
 | |
|         ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|         goto ON_EXIT;
 | |
|       }
 | |
| 
 | |
|       Permanent = TRUE;
 | |
|     }
 | |
| 
 | |
|     if ((OldConfig != NULL) && (OldConfig->Source == IP4_CONFIG_SOURCE_DHCP) &&
 | |
|         (OldConfig->Perment == Permanent)) {
 | |
| 
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INTERFACE_CONFIGURED), gShellNetwork1HiiHandle, Info->Name);
 | |
|       ShellStatus = SHELL_ALREADY_STARTED;
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     Config->Source = IP4_CONFIG_SOURCE_DHCP;
 | |
|   } else if (StringNoCaseCompare(&Temp, &StaticTemp) == 0) {
 | |
|     //
 | |
|     // validate the parameter, two forms: eth0 static IP NETMASK GATEWAY and
 | |
|     // eth0 static IP NETMASK GATEWAY perment
 | |
|     //
 | |
|     if ((Argc != 5) && (Argc != 6)) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellNetwork1HiiHandle, Temp);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     Walker  += StrLen(Temp) + 1;
 | |
|     FreePool(Temp);
 | |
|     Temp    = NULL;
 | |
|     Temp    = StrnCatGrow(&Temp, NULL, Walker, StrStr(Walker, L" ")-Walker);
 | |
| 
 | |
|     if (EFI_ERROR (NetLibStrToIp4 (Temp, &Ip.v4))) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IP_STR), gShellNetwork1HiiHandle, Temp);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     Walker  += StrLen(Temp) + 1;
 | |
|     FreePool(Temp);
 | |
|     Temp    = NULL;
 | |
|     Temp    = StrnCatGrow(&Temp, NULL, Walker, StrStr(Walker, L" ")-Walker);
 | |
|     if (EFI_ERROR (NetLibStrToIp4 (Temp, &Mask.v4))) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IP_STR), gShellNetwork1HiiHandle, Temp);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     Walker  += StrLen(Temp) + 1;
 | |
|     FreePool(Temp);
 | |
|     Temp    = NULL;
 | |
|     if (Argc == 6) {
 | |
|       Temp    = StrnCatGrow(&Temp, NULL, Walker, StrStr(Walker, L" ")-Walker);
 | |
|     } else {
 | |
|       Temp    = StrnCatGrow(&Temp, NULL, Walker, 0);
 | |
|     }
 | |
|     if (EFI_ERROR (NetLibStrToIp4 (Temp, &Gateway.v4))) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IP_STR), gShellNetwork1HiiHandle, Temp);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     if (Argc == 6) {
 | |
|       Walker  += StrLen(Temp) + 1;
 | |
|       FreePool(Temp);
 | |
|       Temp    = NULL;
 | |
|       Temp    = StrnCatGrow(&Temp, NULL, Walker, 0);
 | |
| 
 | |
|       PermTemp = PermanentString;
 | |
|       if (StringNoCaseCompare(&Temp, &PermTemp) != 0) {
 | |
|         ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_GEN_PROBLEM_OP2), gShellNetwork1HiiHandle, Temp, PermanentString, L"Nothing");
 | |
|         ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|         goto ON_EXIT;
 | |
|       }
 | |
| 
 | |
|       Permanent = TRUE;
 | |
|     }
 | |
| 
 | |
|     NetworkBytes1 = NTOHL (Ip.Addr[0]);
 | |
|     NetworkBytes2 = NTOHL (Mask.Addr[0]);
 | |
|     if ((Ip.Addr[0] == 0) || (Mask.Addr[0] == 0) ||
 | |
|         !NetIp4IsUnicast (NetworkBytes1, NetworkBytes2)) {
 | |
| 
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_ADDR_PAIR), gShellNetwork1HiiHandle);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     NetworkBytes1 = NTOHL (Gateway.Addr[0]);
 | |
|     if (!IP4_NET_EQUAL (Ip.Addr[0], Gateway.Addr[0], Mask.Addr[0]) ||
 | |
|         !NetIp4IsUnicast (NetworkBytes1, NetworkBytes2)) {
 | |
|         
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_GATEWAY), gShellNetwork1HiiHandle);
 | |
|       ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|       goto ON_EXIT;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Set the configuration up, two route table entries are added:
 | |
|     // one for the direct connected network, and another for the 
 | |
|     // default gateway. Remember, some structure members are cleared
 | |
|     // by AllocateZeroPool
 | |
|     //
 | |
|     Config->Source = IP4_CONFIG_SOURCE_STATIC;
 | |
|     Config->Ip4Info.RouteTableSize = 2;
 | |
| 
 | |
|     CopyMem (&Config->Ip4Info.StationAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));
 | |
|     CopyMem (&Config->Ip4Info.SubnetMask, &Mask.v4, sizeof (EFI_IPv4_ADDRESS));
 | |
| 
 | |
|     Ip.Addr[0] = Ip.Addr[0] & Mask.Addr[0];
 | |
| 
 | |
|     CopyMem (&Config->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));
 | |
|     CopyMem (&Config->Ip4Info.RouteTable[0].SubnetMask, &Mask.v4, sizeof (EFI_IPv4_ADDRESS));
 | |
|     CopyMem (&Config->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));
 | |
|   } else {
 | |
|     // neither static or DHCP.  error.
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_GEN_TOO_FEW), gShellNetwork1HiiHandle);
 | |
|     ASSERT(ShellStatus == SHELL_INVALID_PARAMETER);
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   CopyMem (&Config->NicAddr, &Info->NicAddress, sizeof (NIC_ADDR));
 | |
|   Config->Perment = Permanent;
 | |
| 
 | |
|   //
 | |
|   // Use HII service to set NIC address
 | |
|   //
 | |
|   ShellStatus = IfconfigSetNicAddrByHii (Info, Config);
 | |
|   if (ShellStatus != SHELL_SUCCESS) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_SET_FAIL), gShellNetwork1HiiHandle, ShellStatus^MAX_BIT);
 | |
|     goto ON_EXIT;
 | |
|   } 
 | |
| 
 | |
|   Status = IfconfigStartIp4 (Info);
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     ShellStatus = SHELL_ACCESS_DENIED;
 | |
|   }
 | |
| 
 | |
|   if (ShellStatus != SHELL_SUCCESS) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_IP_CHILD_FAIL), gShellNetwork1HiiHandle, ShellStatus^MAX_BIT);
 | |
|   }
 | |
|   
 | |
| ON_EXIT:
 | |
|   SHELL_FREE_NON_NULL(Config);
 | |
|   
 | |
|   return ShellStatus;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Show the address information for the nic specified.
 | |
| 
 | |
|   @param[in] Name   A pointer to the string containg the nic's name, if NULL, 
 | |
|                     all nics' information is shown.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| IfconfigShowNicInfo (
 | |
|   IN CONST CHAR16           *Name
 | |
|   )
 | |
| {
 | |
|   LIST_ENTRY                *Entry;
 | |
|   LIST_ENTRY                *NextEntry;
 | |
|   NIC_INFO                  *NicInfo;
 | |
|   UINT32                    Index;
 | |
|   EFI_IP4_IPCONFIG_DATA     *Ip4Config;
 | |
|   EFI_IPv4_ADDRESS          Gateway;
 | |
|   CONST CHAR16              *TempString;
 | |
| 
 | |
|   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &NicInfoList) {
 | |
|     NicInfo = BASE_CR (Entry, NIC_INFO, Link);
 | |
| 
 | |
|     TempString = (CHAR16*)NicInfo->Name;
 | |
|     if ((Name != NULL) && (StringNoCaseCompare (&Name, &TempString) != 0)) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_NIC_NAME), gShellNetwork1HiiHandle, NicInfo->Name);
 | |
| 
 | |
|     ShellPrintHiiEx(
 | |
|     -1,
 | |
|     -1,
 | |
|     NULL,
 | |
|     STRING_TOKEN(STR_IFCONFIG_SHOW_MAC_ADDR), 
 | |
|     gShellNetwork1HiiHandle, 
 | |
|     (UINTN)NicInfo->NicAddress.MacAddr.Addr[0], 
 | |
|     (UINTN)NicInfo->NicAddress.MacAddr.Addr[1], 
 | |
|     (UINTN)NicInfo->NicAddress.MacAddr.Addr[2],
 | |
|     (UINTN)NicInfo->NicAddress.MacAddr.Addr[3], 
 | |
|     (UINTN)NicInfo->NicAddress.MacAddr.Addr[4], 
 | |
|     (UINTN)NicInfo->NicAddress.MacAddr.Addr[5]
 | |
|     );    
 | |
| 
 | |
|     Print (L"  Media State: %s\n", NicInfo->MediaPresent ? L"Media present" : L"Media disconnected");
 | |
| 
 | |
|     if (NicInfo->ConfigInfo == NULL) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_NIC_NOT_CONFIGURED), gShellNetwork1HiiHandle);
 | |
|       continue;
 | |
|     } 
 | |
| 
 | |
|     if (NicInfo->ConfigInfo->Source == IP4_CONFIG_SOURCE_DHCP) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_CONFIG_SOURCE), gShellNetwork1HiiHandle, L"DHCP");
 | |
|     } else if (NicInfo->ConfigInfo->Source == IP4_CONFIG_SOURCE_STATIC) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_CONFIG_SOURCE), gShellNetwork1HiiHandle, L"STATIC");
 | |
|     } else {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_CONFIG_SOURCE), gShellNetwork1HiiHandle, L"Unknown");
 | |
|     }
 | |
| 
 | |
|     ShellPrintHiiEx(-1, -1, NULL,
 | |
|       STRING_TOKEN (STR_IFCONFIG_PERMENT_STATUS),
 | |
|       gShellNetwork1HiiHandle,
 | |
|       (NicInfo->ConfigInfo->Perment? L"TRUE":L"FALSE")
 | |
|       );
 | |
| 
 | |
|     Ip4Config = &NicInfo->ConfigInfo->Ip4Info;
 | |
| 
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL,
 | |
|       STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|       gShellNetwork1HiiHandle, 
 | |
|       L"IP address",
 | |
|       (UINTN)Ip4Config->StationAddress.Addr[0],
 | |
|       (UINTN)Ip4Config->StationAddress.Addr[1],
 | |
|       (UINTN)Ip4Config->StationAddress.Addr[2],
 | |
|       (UINTN)Ip4Config->StationAddress.Addr[3]
 | |
|       );
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL,
 | |
|       STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|       gShellNetwork1HiiHandle, 
 | |
|       L"Mask",
 | |
|       (UINTN)Ip4Config->SubnetMask.Addr[0],
 | |
|       (UINTN)Ip4Config->SubnetMask.Addr[1],
 | |
|       (UINTN)Ip4Config->SubnetMask.Addr[2],
 | |
|       (UINTN)Ip4Config->SubnetMask.Addr[3]
 | |
|       );
 | |
| 
 | |
|     ZeroMem (&Gateway, sizeof (EFI_IPv4_ADDRESS));
 | |
|     
 | |
|     for (Index = 0; Index < Ip4Config->RouteTableSize; Index++) {
 | |
|       if ((CompareMem (&Ip4Config->RouteTable[Index].SubnetAddress, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) &&
 | |
|           (CompareMem (&Ip4Config->RouteTable[Index].SubnetMask   , &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) ){
 | |
|         CopyMem (&Gateway, &Ip4Config->RouteTable[Index].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
 | |
|       }
 | |
|     }
 | |
|    
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL,
 | |
|       STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|       gShellNetwork1HiiHandle, 
 | |
|       L"Gateway",
 | |
|       (UINTN)Gateway.Addr[0],
 | |
|       (UINTN)Gateway.Addr[1],
 | |
|       (UINTN)Gateway.Addr[2],
 | |
|       (UINTN)Gateway.Addr[3]
 | |
|       );
 | |
| 
 | |
|     ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, Ip4Config->RouteTableSize);
 | |
| 
 | |
|     for (Index = 0; Index < Ip4Config->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)Ip4Config->RouteTable[Index].SubnetAddress.Addr[0],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetAddress.Addr[1],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetAddress.Addr[2],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetAddress.Addr[3]
 | |
|         );
 | |
| 
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|         gShellNetwork1HiiHandle, 
 | |
|         L"Netmask",
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetMask.Addr[0],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetMask.Addr[1],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetMask.Addr[2],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].SubnetMask.Addr[3]
 | |
|         );
 | |
| 
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), 
 | |
|         gShellNetwork1HiiHandle, 
 | |
|         L"Gateway",
 | |
|         (UINTN)Ip4Config->RouteTable[Index].GatewayAddress.Addr[0],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].GatewayAddress.Addr[1],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].GatewayAddress.Addr[2],
 | |
|         (UINTN)Ip4Config->RouteTable[Index].GatewayAddress.Addr[3]
 | |
|         );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Clear address configuration for the nic specified.
 | |
| 
 | |
|   @param[in] Name     A pointer to the string containg the nic's name, 
 | |
|                       if NULL, all nics address configurations are cleared.
 | |
| 
 | |
|   @retval EFI_SUCCESS The address configuration is cleared.
 | |
|   @return             Some error occurs.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IfconfigClearNicAddr (
 | |
|   IN CONST CHAR16                     *Name
 | |
|   )
 | |
| {
 | |
|   LIST_ENTRY                    *Entry;
 | |
|   LIST_ENTRY                    *NextEntry;
 | |
|   NIC_INFO                      *Info;
 | |
|   EFI_STATUS                    Status;
 | |
|   
 | |
|   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &NicInfoList) {
 | |
|     Info = BASE_CR (Entry, NIC_INFO, Link);
 | |
| 
 | |
|     if ((Name != NULL) && (StrCmp (Name, Info->Name) != 0)) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
| //    if (Info->NicIp4Config == NULL) { 
 | |
|       Status = IfconfigSetNicAddrByHii (Info, NULL);
 | |
| //    } else {
 | |
| //      Status = Info->NicIp4Config->SetInfo (Info->NicIp4Config, NULL, TRUE);
 | |
| //    }
 | |
| 
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
|   
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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).
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| ShellCommandRunIfconfig (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS          Status;
 | |
|   LIST_ENTRY          *Package;
 | |
|   CHAR16              *ProblemParam;
 | |
|   SHELL_STATUS        ShellStatus;
 | |
|   BOOLEAN             ListOperation;
 | |
|   BOOLEAN             ClearOperation;
 | |
|   BOOLEAN             SetOperation;
 | |
|   CONST CHAR16        *Item;
 | |
|   LIST_ENTRY          *Entry;
 | |
|   NIC_INFO            *Info;
 | |
| 
 | |
|   InitializeListHead (&NicInfoList);
 | |
|   Status = EFI_INVALID_PARAMETER;
 | |
|   ShellStatus = SHELL_SUCCESS;
 | |
| 
 | |
|   //
 | |
|   // initialize the shell lib (we must be in non-auto-init...)
 | |
|   //
 | |
|   Status = ShellInitialize();
 | |
|   ASSERT_EFI_ERROR(Status);
 | |
| 
 | |
|   //
 | |
|   // parse the command line
 | |
|   //
 | |
|   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellNetwork1HiiHandle, ProblemParam);
 | |
|       FreePool(ProblemParam);
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else {
 | |
|       ASSERT(FALSE);
 | |
|     }
 | |
| 
 | |
|     goto Done;
 | |
|   }
 | |
| 
 | |
|   ClearOperation = ShellCommandLineGetFlag(Package, L"-c");
 | |
|   ListOperation  = ShellCommandLineGetFlag(Package, L"-l");
 | |
|   SetOperation   = ShellCommandLineGetFlag(Package, L"-s");
 | |
| 
 | |
|   if ((ClearOperation && ListOperation)
 | |
|     ||(SetOperation   && ListOperation)
 | |
|     ||(ClearOperation && SetOperation)
 | |
|     ) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellNetwork1HiiHandle);
 | |
|     ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     goto Done;
 | |
|   } else if (!ClearOperation && !ListOperation && !SetOperation) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellNetwork1HiiHandle);
 | |
|     ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     goto Done;
 | |
|   }
 | |
|     
 | |
|     
 | |
|   Status = IfconfigGetAllNicInfoByHii ();
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     if (mIp4ConfigExist) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_GET_NIC_FAIL), gShellNetwork1HiiHandle, Status);
 | |
|     } else {
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellNetwork1HiiHandle, L"gEfiIp4ConfigProtocolGuid", &gEfiIp4ConfigProtocolGuid);
 | |
|     }
 | |
| 
 | |
|     return SHELL_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   if (ListOperation) {
 | |
|     Item = ShellCommandLineGetValue (Package, L"-l");
 | |
| 
 | |
|     if (Item != NULL && CountSubItems(Item) > 1) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellNetwork1HiiHandle, L"-l");
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     } 
 | |
|     
 | |
|     //
 | |
|     // Show the configuration.
 | |
|     //
 | |
|     IfconfigShowNicInfo (Item);
 | |
|   } else if (SetOperation) {
 | |
|     Item = ShellCommandLineGetValue (Package, L"-s");
 | |
| 
 | |
|     //
 | |
|     // The correct command line arguments for setting address are:
 | |
|     // IfConfig -s eth0 DHCP [perment]
 | |
|     // IfConfig -s eth0 static ip netmask gateway [perment]
 | |
|     //
 | |
|     if (Item == NULL || (CountSubItems(Item) < 2) || (CountSubItems(Item) > 6) || (CountSubItems(Item) == 4)) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellNetwork1HiiHandle, L"-s");
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     }
 | |
| 
 | |
|     ShellStatus = IfconfigSetNicAddr (CountSubItems(Item), Item);
 | |
|   } else if (ClearOperation) {
 | |
|     Item = ShellCommandLineGetValue (Package, L"-c");
 | |
| 
 | |
|     if (Item != NULL && CountSubItems(Item) > 1) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellNetwork1HiiHandle, L"-c");
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       goto Done;
 | |
|     }
 | |
| 
 | |
|     IfconfigClearNicAddr (Item);
 | |
|   } else {
 | |
|     ASSERT(FALSE);
 | |
|   }
 | |
| 
 | |
| Done:
 | |
|   while (!IsListEmpty (&NicInfoList)) {
 | |
|     Entry = NicInfoList.ForwardLink;
 | |
|     Info  = BASE_CR (Entry, NIC_INFO, Link);
 | |
| 
 | |
|     RemoveEntryList (Entry);
 | |
| 
 | |
|     if (Info->ConfigInfo != NULL) {
 | |
|       FreePool (Info->ConfigInfo);
 | |
|     }
 | |
| 
 | |
|     FreePool (Info);
 | |
|   }
 | |
| 
 | |
|   if (Package != NULL) {
 | |
|     ShellCommandLineFreeVarList(Package);
 | |
|   }
 | |
| 
 | |
|   return (ShellStatus);
 | |
| }
 |