/** @file\r
Network library.\r
\r
-Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
ASSERT if NetMask is zero.\r
\r
- If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address.\r
+ If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address,\r
+ except when the originator is one of the endpoints of a point-to-point link with a 31-bit\r
+ mask (RFC3021).\r
\r
@param[in] Ip The IP to check against.\r
@param[in] NetMask The mask of the IP.\r
if (Ip == 0 || IP4_IS_LOCAL_BROADCAST (Ip)) {\r
return FALSE;\r
}\r
- \r
- if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)) {\r
- return FALSE;\r
+\r
+ if (NetGetMaskLength (NetMask) != 31) {\r
+ if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)) {\r
+ return FALSE;\r
+ }\r
+ } else {\r
+ return TRUE;\r
}\r
\r
return TRUE;\r
UINT64 MonotonicCount;\r
\r
gRT->GetTime (&Time, NULL);\r
- Seed = (~Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second);\r
+ Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second);\r
Seed ^= Time.Nanosecond;\r
Seed ^= Time.Year << 7;\r
\r
UINT16 VlanId;\r
CHAR16 *String;\r
UINTN Index;\r
+ UINTN BufferSize;\r
\r
ASSERT (MacString != NULL);\r
\r
// If VLAN is configured, it will need extra 5 characters like "\0005".\r
// Plus one unicode character for the null-terminator.\r
//\r
- String = AllocateZeroPool ((2 * HwAddressSize + 5 + 1) * sizeof (CHAR16));\r
+ BufferSize = (2 * HwAddressSize + 5 + 1) * sizeof (CHAR16);\r
+ String = AllocateZeroPool (BufferSize);\r
if (String == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
HwAddress = &MacAddress.Addr[0];\r
for (Index = 0; Index < HwAddressSize; Index++) {\r
- String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, *(HwAddress++), 2);\r
+ UnicodeValueToStringS (\r
+ String,\r
+ BufferSize - ((UINTN)String - (UINTN)*MacString),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *(HwAddress++),\r
+ 2\r
+ );\r
+ String += StrnLenS (String, (BufferSize - ((UINTN)String - (UINTN)*MacString)) / sizeof (CHAR16));\r
}\r
\r
//\r
VlanId = NetLibGetVlanId (ServiceHandle);\r
if (VlanId != 0) {\r
*String++ = L'\\';\r
- String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, VlanId, 4);\r
+ UnicodeValueToStringS (\r
+ String,\r
+ BufferSize - ((UINTN)String - (UINTN)*MacString),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ VlanId,\r
+ 4\r
+ );\r
+ String += StrnLenS (String, (BufferSize - ((UINTN)String - (UINTN)*MacString)) / sizeof (CHAR16));\r
}\r
\r
//\r
OUT EFI_IPv4_ADDRESS *Ip4Address\r
)\r
{\r
- UINT8 Index;\r
- CHAR8 *Ip4Str;\r
- CHAR8 *TempStr;\r
- UINTN NodeVal;\r
+ RETURN_STATUS Status;\r
+ CHAR8 *EndPointer;\r
\r
- if ((String == NULL) || (Ip4Address == NULL)) {\r
+ Status = AsciiStrToIpv4Address (String, &EndPointer, Ip4Address, NULL);\r
+ if (RETURN_ERROR (Status) || (*EndPointer != '\0')) {\r
return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ return EFI_SUCCESS;\r
}\r
-\r
- Ip4Str = (CHAR8 *) String;\r
-\r
- for (Index = 0; Index < 4; Index++) {\r
- TempStr = Ip4Str;\r
-\r
- while ((*Ip4Str != '\0') && (*Ip4Str != '.')) {\r
- if (Index != 3 && !NET_IS_DIGIT (*Ip4Str)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- \r
- //\r
- // Allow the IPv4 with prefix case, e.g. 192.168.10.10/24 \r
- //\r
- if (Index == 3 && !NET_IS_DIGIT (*Ip4Str) && *Ip4Str != '/') {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- \r
- Ip4Str++;\r
- }\r
-\r
- //\r
- // The IPv4 address is X.X.X.X\r
- //\r
- if (*Ip4Str == '.') {\r
- if (Index == 3) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else {\r
- if (Index != 3) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- //\r
- // Convert the string to IPv4 address. AsciiStrDecimalToUintn stops at the\r
- // first character that is not a valid decimal character, '.' or '\0' here.\r
- //\r
- NodeVal = AsciiStrDecimalToUintn (TempStr);\r
- if (NodeVal > 0xFF) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Ip4Address->Addr[Index] = (UINT8) NodeVal;\r
-\r
- Ip4Str++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
\r
OUT EFI_IPv6_ADDRESS *Ip6Address\r
)\r
{\r
- UINT8 Index;\r
- CHAR8 *Ip6Str;\r
- CHAR8 *TempStr;\r
- CHAR8 *TempStr2;\r
- UINT8 NodeCnt;\r
- UINT8 TailNodeCnt;\r
- UINT8 AllowedCnt;\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
- LeadZeroCnt = 0;\r
-\r
- //\r
- // An IPv6 address leading with : looks strange.\r
- //\r
- if (*Ip6Str == ':') {\r
- if (*(Ip6Str + 1) != ':') {\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- AllowedCnt = 7;\r
- }\r
- }\r
-\r
- ZeroMem (Ip6Address, sizeof (EFI_IPv6_ADDRESS));\r
-\r
- NodeCnt = 0;\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
- while ((*Ip6Str != '\0') && (*Ip6Str != ':')) {\r
- Ip6Str++;\r
- }\r
-\r
- if ((*Ip6Str == '\0') && (Index != 14)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*Ip6Str == ':') {\r
- if (*(Ip6Str + 1) == ':') {\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
- TempStr2 = Ip6Str + 2;\r
- while ((*TempStr2 != '\0')) {\r
- if (*TempStr2 == ':') {\r
- if (*(TempStr2 + 1) == ':') {\r
- //\r
- // :: can only appear once in IPv6 address.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- TailNodeCnt++;\r
- if (TailNodeCnt >= (AllowedCnt - NodeCnt)) {\r
- //\r
- // :: indicates one or more groups of 16 bits of zeros.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- TempStr2++;\r
- }\r
-\r
- Short = TRUE;\r
- Update = TRUE;\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
- //\r
- // There are more than 8 groups of 16 bits of zeros.\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Convert the string to IPv6 address. AsciiStrHexToUintn stops at the first\r
- // character that is not a valid hexadecimal character, ':' or '\0' here.\r
- //\r
- NodeVal = AsciiStrHexToUintn (TempStr);\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
+ RETURN_STATUS Status;\r
+ CHAR8 *EndPointer;\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
- // Skip the groups of zeros by ::\r
- //\r
- if (Short && Update) {\r
- Index = (UINT8) (16 - (TailNodeCnt + 2) * 2);\r
- Update = FALSE;\r
- }\r
- }\r
-\r
- if ((!Short && Index != 16) || (*Ip6Str != '\0')) {\r
+ Status = AsciiStrToIpv6Address (String, &EndPointer, Ip6Address, NULL);\r
+ if (RETURN_ERROR (Status) || (*EndPointer != '\0')) {\r
return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ return EFI_SUCCESS;\r
}\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
\r
\r
@retval EFI_SUCCESS Convert to IPv4 address successfully.\r
@retval EFI_INVALID_PARAMETER The string is mal-formated or Ip4Address is NULL.\r
- @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.\r
\r
**/\r
EFI_STATUS\r
OUT EFI_IPv4_ADDRESS *Ip4Address\r
)\r
{\r
- CHAR8 *Ip4Str;\r
- UINTN StringSize;\r
- EFI_STATUS Status;\r
+ RETURN_STATUS Status;\r
+ CHAR16 *EndPointer;\r
\r
- if ((String == NULL) || (Ip4Address == NULL)) {\r
+ Status = StrToIpv4Address (String, &EndPointer, Ip4Address, NULL);\r
+ if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) {\r
return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ return EFI_SUCCESS;\r
}\r
-\r
- StringSize = StrLen (String) + 1;\r
- Ip4Str = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));\r
- if (Ip4Str == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- UnicodeStrToAsciiStrS (String, Ip4Str, StringSize);\r
-\r
- Status = NetLibAsciiStrToIp4 (Ip4Str, Ip4Address);\r
-\r
- FreePool (Ip4Str);\r
-\r
- return Status;\r
}\r
\r
\r
\r
@retval EFI_SUCCESS Convert to IPv6 address successfully.\r
@retval EFI_INVALID_PARAMETER The string is mal-formated or Ip6Address is NULL.\r
- @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.\r
\r
**/\r
EFI_STATUS\r
OUT EFI_IPv6_ADDRESS *Ip6Address\r
)\r
{\r
- CHAR8 *Ip6Str;\r
- UINTN StringSize;\r
- EFI_STATUS Status;\r
+ RETURN_STATUS Status;\r
+ CHAR16 *EndPointer;\r
\r
- if ((String == NULL) || (Ip6Address == NULL)) {\r
+ Status = StrToIpv6Address (String, &EndPointer, Ip6Address, NULL);\r
+ if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) {\r
return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ return EFI_SUCCESS;\r
}\r
-\r
- StringSize = StrLen (String) + 1;\r
- Ip6Str = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));\r
- if (Ip6Str == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- UnicodeStrToAsciiStrS (String, Ip6Str, StringSize);\r
-\r
- Status = NetLibAsciiStrToIp6 (Ip6Str, Ip6Address);\r
-\r
- FreePool (Ip6Str);\r
-\r
- return Status;\r
}\r
\r
/**\r
\r
@retval EFI_SUCCESS Convert to IPv6 address successfully.\r
@retval EFI_INVALID_PARAMETER The string is mal-formated or Ip6Address is NULL.\r
- @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.\r
\r
**/\r
EFI_STATUS\r
OUT UINT8 *PrefixLength\r
)\r
{\r
- CHAR8 *Ip6Str;\r
- UINTN StringSize;\r
- CHAR8 *PrefixStr;\r
- CHAR8 *TempStr;\r
- EFI_STATUS Status;\r
- UINT8 Length;\r
-\r
- if ((String == NULL) || (Ip6Address == NULL) || (PrefixLength == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- StringSize = StrLen (String) + 1;\r
- Ip6Str = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));\r
- if (Ip6Str == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- UnicodeStrToAsciiStrS (String, Ip6Str, StringSize);\r
-\r
- //\r
- // Get the sub string describing prefix length.\r
- //\r
- TempStr = Ip6Str;\r
- while (*TempStr != '\0' && (*TempStr != '/')) {\r
- TempStr++;\r
- }\r
+ RETURN_STATUS Status;\r
+ CHAR16 *EndPointer;\r
\r
- if (*TempStr == '/') {\r
- PrefixStr = TempStr + 1;\r
+ Status = StrToIpv6Address (String, &EndPointer, Ip6Address, PrefixLength);\r
+ if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) {\r
+ return EFI_INVALID_PARAMETER;\r
} else {\r
- PrefixStr = NULL;\r
- }\r
-\r
- //\r
- // Get the sub string describing IPv6 address and convert it.\r
- //\r
- *TempStr = '\0';\r
-\r
- Status = NetLibAsciiStrToIp6 (Ip6Str, Ip6Address);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
-\r
- //\r
- // If input string doesn't indicate the prefix length, return 0xff.\r
- //\r
- Length = 0xFF;\r
-\r
- //\r
- // Convert the string to prefix length\r
- //\r
- if (PrefixStr != NULL) {\r
-\r
- Status = EFI_INVALID_PARAMETER;\r
- Length = 0;\r
- while (*PrefixStr != '\0') {\r
- if (NET_IS_DIGIT (*PrefixStr)) {\r
- Length = (UINT8) (Length * 10 + (*PrefixStr - '0'));\r
- if (Length > IP6_PREFIX_MAX) {\r
- goto Exit;\r
- }\r
- } else {\r
- goto Exit;\r
- }\r
-\r
- PrefixStr++;\r
- }\r
+ return EFI_SUCCESS;\r
}\r
-\r
- *PrefixLength = Length;\r
- Status = EFI_SUCCESS;\r
-\r
-Exit:\r
-\r
- FreePool (Ip6Str);\r
- return Status;\r
}\r
\r
/**\r
return EFI_NOT_FOUND;\r
}\r
Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress;\r
- SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength);\r
+ SmbiosEnd.Raw = (UINT8 *) ((UINTN) SmbiosTable->TableAddress + SmbiosTable->TableLength);\r
}\r
\r
do {\r