/** @file\r
Network library.\r
\r
-Copyright (c) 2005 - 2010, Intel Corporation.<BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\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
#include <Uefi.h>\r
\r
+#include <IndustryStandard/SmBios.h>\r
+\r
#include <Protocol/DriverBinding.h>\r
#include <Protocol/ServiceBinding.h>\r
#include <Protocol/SimpleNetwork.h>\r
#include <Protocol/HiiConfigRouting.h>\r
#include <Protocol/ComponentName.h>\r
#include <Protocol/ComponentName2.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
\r
#include <Guid/NicIp4ConfigNvData.h>\r
+#include <Guid/SmBios.h>\r
\r
#include <Library/NetLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/DevicePathLib.h>\r
#include <Library/HiiLib.h>\r
#include <Library/PrintLib.h>\r
+#include <Library/UefiLib.h>\r
\r
#define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE\r
\r
\r
**/\r
CHAR8 *\r
+EFIAPI\r
NetDebugASPrint (\r
IN CHAR8 *Format,\r
...\r
than the mNetDebugLevelMax. Or, it has been sent out.\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetDebugOutput (\r
IN UINT32 Level,\r
IN UINT8 *Module,\r
\r
**/\r
BOOLEAN\r
+EFIAPI\r
NetIp6IsValidUnicast (\r
IN EFI_IPv6_ADDRESS *Ip6\r
)\r
\r
**/\r
BOOLEAN\r
+EFIAPI\r
NetIp6IsUnspecifiedAddr (\r
IN EFI_IPv6_ADDRESS *Ip6\r
)\r
\r
**/\r
BOOLEAN\r
+EFIAPI\r
NetIp6IsLinkLocalAddr (\r
IN EFI_IPv6_ADDRESS *Ip6\r
)\r
\r
**/\r
BOOLEAN\r
+EFIAPI\r
NetIp6IsNetEqual (\r
EFI_IPv6_ADDRESS *Ip1,\r
EFI_IPv6_ADDRESS *Ip2,\r
\r
**/\r
EFI_IPv6_ADDRESS *\r
+EFIAPI\r
Ip6Swap128 (\r
EFI_IPv6_ADDRESS *Ip6\r
)\r
}\r
\r
\r
+/**\r
+ Internal function to get the child handle of the NIC handle.\r
+\r
+ @param[in] Controller NIC controller handle.\r
+ @param[out] ChildHandle Returned child handle.\r
+\r
+ @retval EFI_SUCCESS Successfully to get child handle.\r
+ @retval Others Failed to get child handle.\r
+\r
+**/\r
+EFI_STATUS\r
+NetGetChildHandle (\r
+ IN EFI_HANDLE Controller,\r
+ OUT EFI_HANDLE *ChildHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *Handles;\r
+ UINTN HandleCount;\r
+ UINTN Index;\r
+ EFI_DEVICE_PATH_PROTOCOL *ChildDeviceDevicePath;\r
+ VENDOR_DEVICE_PATH *VendorDeviceNode;\r
+\r
+ //\r
+ // Locate all EFI Hii Config Access protocols\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &Handles\r
+ );\r
+ if (EFI_ERROR (Status) || (HandleCount == 0)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = EFI_NOT_FOUND;\r
+\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+\r
+ Status = EfiTestChildHandle (Controller, Handles[Index], &gEfiManagedNetworkServiceBindingProtocolGuid);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Get device path on the child handle\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ Handles[Index],\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ChildDeviceDevicePath\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ while (!IsDevicePathEnd (ChildDeviceDevicePath)) {\r
+ ChildDeviceDevicePath = NextDevicePathNode (ChildDeviceDevicePath);\r
+ //\r
+ // Parse one instance\r
+ //\r
+ if (ChildDeviceDevicePath->Type == HARDWARE_DEVICE_PATH &&\r
+ ChildDeviceDevicePath->SubType == HW_VENDOR_DP) {\r
+ VendorDeviceNode = (VENDOR_DEVICE_PATH *) ChildDeviceDevicePath;\r
+ if (CompareMem (&VendorDeviceNode->Guid, &gEfiNicIp4ConfigVariableGuid, sizeof (EFI_GUID)) == 0) {\r
+ //\r
+ // Found item matched gEfiNicIp4ConfigVariableGuid\r
+ //\r
+ *ChildHandle = Handles[Index];\r
+ FreePool (Handles);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ FreePool (Handles);\r
+ return Status;\r
+}\r
+\r
+\r
/**\r
This is the default unload handle for all the network drivers.\r
\r
EFI_STRING AccessProgress;\r
EFI_STRING AccessResults;\r
EFI_STRING String;\r
+ EFI_HANDLE ChildHandle;\r
\r
ConfigInfo = NULL;\r
ConfigHdr = NULL;\r
return TRUE;\r
}\r
\r
+ Status = NetGetChildHandle (Controller, &ChildHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return TRUE;\r
+ }\r
+\r
//\r
// Construct config request string header\r
//\r
- ConfigHdr = HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, Controller);\r
+ ConfigHdr = HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, ChildHandle);\r
if (ConfigHdr == NULL) {\r
return TRUE;\r
}\r
goto ON_EXIT;\r
}\r
\r
- ConfigInfo = AllocateZeroPool (sizeof (NIC_ITEM_CONFIG_SIZE));\r
+ ConfigInfo = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
if (ConfigInfo == NULL) {\r
goto ON_EXIT;\r
}\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetLibAsciiStrToIp4 (\r
IN CONST CHAR8 *String,\r
OUT EFI_IPv4_ADDRESS *Ip4Address\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetLibAsciiStrToIp6 (\r
IN CONST CHAR8 *String,\r
OUT EFI_IPv6_ADDRESS *Ip6Address\r
UINTN NodeVal;\r
BOOLEAN Short;\r
BOOLEAN Update;\r
+ BOOLEAN LeadZero;\r
+ UINT8 LeadZeroCnt;\r
+ UINT8 Cnt;\r
\r
if ((String == NULL) || (Ip6Address == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Ip6Str = (CHAR8 *) String;\r
- AllowedCnt = 6;\r
+ Ip6Str = (CHAR8 *) String;\r
+ AllowedCnt = 6;\r
+ LeadZeroCnt = 0;\r
\r
//\r
// An IPv6 address leading with : looks strange.\r
TailNodeCnt = 0;\r
Short = FALSE;\r
Update = FALSE;\r
+ LeadZero = FALSE;\r
\r
for (Index = 0; Index < 15; Index = (UINT8) (Index + 2)) {\r
TempStr = Ip6Str;\r
\r
if (*Ip6Str == ':') {\r
if (*(Ip6Str + 1) == ':') {\r
- if ((*(Ip6Str + 2) == '0') || (NodeCnt > 6)) {\r
+ if ((NodeCnt > 6) || \r
+ ((*(Ip6Str + 2) != '\0') && (AsciiStrHexToUintn (Ip6Str + 2) == 0))) {\r
//\r
// ::0 looks strange. report error to user.\r
//\r
return EFI_INVALID_PARAMETER;\r
}\r
+ if ((NodeCnt == 6) && (*(Ip6Str + 2) != '\0') && \r
+ (AsciiStrHexToUintn (Ip6Str + 2) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
//\r
// Skip the abbreviation part of IPv6 address.\r
\r
Ip6Str = Ip6Str + 2;\r
} else {\r
+ if (*(Ip6Str + 1) == '\0') {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
Ip6Str++;\r
NodeCnt++;\r
if ((Short && (NodeCnt > 6)) || (!Short && (NodeCnt > 7))) {\r
if ((NodeVal > 0xFFFF) || (Index > 14)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+ if (NodeVal != 0) {\r
+ if ((*TempStr == '0') && \r
+ ((*(TempStr + 2) == ':') || (*(TempStr + 3) == ':') || \r
+ (*(TempStr + 2) == '\0') || (*(TempStr + 3) == '\0'))) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if ((*TempStr == '0') && (*(TempStr + 4) != '\0') && \r
+ (*(TempStr + 4) != ':')) { \r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } else {\r
+ if (((*TempStr == '0') && (*(TempStr + 1) == '0') && \r
+ ((*(TempStr + 2) == ':') || (*(TempStr + 2) == '\0'))) ||\r
+ ((*TempStr == '0') && (*(TempStr + 1) == '0') && (*(TempStr + 2) == '0') && \r
+ ((*(TempStr + 3) == ':') || (*(TempStr + 3) == '\0')))) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
+ Cnt = 0;\r
+ while ((TempStr[Cnt] != ':') && (TempStr[Cnt] != '\0')) {\r
+ Cnt++; \r
+ }\r
+ if (LeadZeroCnt == 0) {\r
+ if ((Cnt == 4) && (*TempStr == '0')) {\r
+ LeadZero = TRUE;\r
+ LeadZeroCnt++;\r
+ }\r
+ if ((Cnt != 0) && (Cnt < 4)) {\r
+ LeadZero = FALSE;\r
+ LeadZeroCnt++;\r
+ }\r
+ } else {\r
+ if ((Cnt == 4) && (*TempStr == '0') && !LeadZero) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if ((Cnt != 0) && (Cnt < 4) && LeadZero) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } \r
\r
Ip6Address->Addr[Index] = (UINT8) (NodeVal >> 8);\r
Ip6Address->Addr[Index + 1] = (UINT8) (NodeVal & 0xFF);\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetLibStrToIp4 (\r
IN CONST CHAR16 *String,\r
OUT EFI_IPv4_ADDRESS *Ip4Address\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetLibStrToIp6 (\r
IN CONST CHAR16 *String,\r
OUT EFI_IPv6_ADDRESS *Ip6Address\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetLibStrToIp6andPrefix (\r
IN CONST CHAR16 *String,\r
OUT EFI_IPv6_ADDRESS *Ip6Address,\r
// If input string doesn't indicate the prefix length, return 0xff.\r
//\r
Length = 0xFF;\r
- \r
+\r
//\r
// Convert the string to prefix length\r
//\r
return Status;\r
}\r
\r
+\r
+\r
+/**\r
+ This function obtains the system guid from the smbios table.\r
+\r
+ @param[out] SystemGuid The pointer of the returned system guid.\r
+\r
+ @retval EFI_SUCCESS Successfully obtained the system guid.\r
+ @retval EFI_NOT_FOUND Did not find the SMBIOS table.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NetLibGetSystemGuid (\r
+ OUT EFI_GUID *SystemGuid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;\r
+ SMBIOS_STRUCTURE_POINTER Smbios;\r
+ SMBIOS_STRUCTURE_POINTER SmbiosEnd;\r
+ CHAR8 *String;\r
+\r
+ SmbiosTable = NULL;\r
+ Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable);\r
+\r
+ if (EFI_ERROR (Status) || SmbiosTable == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress;\r
+ SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength);\r
+\r
+ do {\r
+ if (Smbios.Hdr->Type == 1) {\r
+ if (Smbios.Hdr->Length < 0x19) {\r
+ //\r
+ // Older version did not support UUID.\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ \r
+ //\r
+ // SMBIOS tables are byte packed so we need to do a byte copy to\r
+ // prevend alignment faults on Itanium-based platform.\r
+ //\r
+ CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof (EFI_GUID));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Go to the next SMBIOS structure. Each SMBIOS structure may include 2 parts:\r
+ // 1. Formatted section; 2. Unformatted string section. So, 2 steps are needed\r
+ // to skip one SMBIOS structure.\r
+ //\r
+ \r
+ //\r
+ // Step 1: Skip over formatted section.\r
+ //\r
+ String = (CHAR8 *) (Smbios.Raw + Smbios.Hdr->Length);\r
+ \r
+ //\r
+ // Step 2: Skip over unformated string section.\r
+ //\r
+ do {\r
+ //\r
+ // Each string is terminated with a NULL(00h) BYTE and the sets of strings\r
+ // is terminated with an additional NULL(00h) BYTE.\r
+ //\r
+ for ( ; *String != 0; String++) {\r
+ }\r
+\r
+ if (*(UINT8*)++String == 0) {\r
+ //\r
+ // Pointer to the next SMBIOS structure.\r
+ //\r
+ Smbios.Raw = (UINT8 *)++String;\r
+ break;\r
+ } \r
+ } while (TRUE);\r
+ } while (Smbios.Raw < SmbiosEnd.Raw);\r
+ return EFI_NOT_FOUND;\r
+}\r