/** @file\r
Network library.\r
\r
-Copyright (c) 2005 - 2007, Intel Corporation.<BR>\r
+Copyright (c) 2005 - 2009, Intel Corporation.<BR>\r
All rights reserved. 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
\r
#include <Uefi.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/Dpc.h>\r
\r
#include <Guid/NicIp4ConfigNvData.h>\r
\r
#include <Library/HiiLib.h>\r
#include <Library/PrintLib.h>\r
\r
-EFI_DPC_PROTOCOL *mDpc = NULL;\r
-\r
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mNetLibHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};\r
\r
-#define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2\r
+#define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE\r
\r
//\r
// All the supported IP4 maskes in host byte order.\r
\r
EFI_IPv4_ADDRESS mZeroIp4Addr = {{0, 0, 0, 0}};\r
\r
+//\r
+// Any error level digitally larger than mNetDebugLevelMax \r
+// will be silently discarded.\r
+//\r
+UINTN mNetDebugLevelMax = NETDEBUG_LEVEL_ERROR;\r
+UINT32 mSyslogPacketSeq = 0xDEADBEEF;\r
+\r
+// \r
+// You can change mSyslogDstMac mSyslogDstIp and mSyslogSrcIp \r
+// here to direct the syslog packets to the syslog deamon. The \r
+// default is broadcast to both the ethernet and IP. \r
+//\r
+UINT8 mSyslogDstMac[NET_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
+UINT32 mSyslogDstIp = 0xffffffff;\r
+UINT32 mSyslogSrcIp = 0;\r
+\r
+CHAR8 *\r
+mMonthName[] = {\r
+ "Jan",\r
+ "Feb",\r
+ "Mar",\r
+ "Apr",\r
+ "May",\r
+ "Jun",\r
+ "Jul",\r
+ "Aug",\r
+ "Sep",\r
+ "Oct",\r
+ "Nov",\r
+ "Dec"\r
+};\r
+\r
+/**\r
+ Locate the handles that support SNP, then open one of them \r
+ to send the syslog packets. The caller isn't required to close\r
+ the SNP after use because the SNP is opened by HandleProtocol.\r
+\r
+ @return The point to SNP if one is properly openned. Otherwise NULL\r
+\r
+**/\r
+EFI_SIMPLE_NETWORK_PROTOCOL *\r
+SyslogLocateSnp (\r
+ VOID\r
+ )\r
+{\r
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *Handles;\r
+ UINTN HandleCount;\r
+ UINTN Index;\r
+\r
+ //\r
+ // Locate the handles which has SNP installed.\r
+ //\r
+ Handles = NULL;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiSimpleNetworkProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &Handles\r
+ );\r
+\r
+ if (EFI_ERROR (Status) || (HandleCount == 0)) {\r
+ return NULL;\r
+ }\r
+ \r
+ //\r
+ // Try to open one of the ethernet SNP protocol to send packet\r
+ //\r
+ Snp = NULL;\r
+ \r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (\r
+ Handles[Index],\r
+ &gEfiSimpleNetworkProtocolGuid,\r
+ (VOID **) &Snp\r
+ );\r
+\r
+ if ((Status == EFI_SUCCESS) && (Snp != NULL) && \r
+ (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) &&\r
+ (Snp->Mode->MaxPacketSize >= NET_SYSLOG_PACKET_LEN)) {\r
+ \r
+ break;\r
+ }\r
+\r
+ Snp = NULL;\r
+ }\r
+\r
+ FreePool (Handles);\r
+ return Snp;\r
+}\r
+\r
+/**\r
+ Transmit a syslog packet synchronously through SNP. The Packet\r
+ already has the ethernet header prepended. This function should \r
+ fill in the source MAC because it will try to locate a SNP each\r
+ time it is called to avoid the problem if SNP is unloaded.\r
+ This code snip is copied from MNP. \r
+\r
+ @param[in] Packet - The Syslog packet \r
+ @param[in] Length - The length of the packet\r
+\r
+ @retval EFI_DEVICE_ERROR - Failed to locate a usable SNP protocol\r
+ @retval EFI_TIMEOUT - Timeout happened to send the packet.\r
+ @retval EFI_SUCCESS - Packet is sent.\r
+ \r
+**/\r
+EFI_STATUS\r
+SyslogSendPacket (\r
+ IN CHAR8 *Packet,\r
+ IN UINT32 Length\r
+ )\r
+{\r
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
+ ETHER_HEAD *Ether;\r
+ EFI_STATUS Status;\r
+ EFI_EVENT TimeoutEvent;\r
+ UINT8 *TxBuf;\r
+\r
+ Snp = SyslogLocateSnp ();\r
+\r
+ if (Snp == NULL) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Ether = (ETHER_HEAD *) Packet;\r
+ CopyMem (Ether->SrcMac, Snp->Mode->CurrentAddress.Addr, NET_ETHER_ADDR_LEN);\r
+\r
+ //\r
+ // Start the timeout event.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ TPL_NOTIFY,\r
+ NULL,\r
+ NULL,\r
+ &TimeoutEvent\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ for (;;) {\r
+ //\r
+ // Transmit the packet through SNP.\r
+ //\r
+ Status = Snp->Transmit (Snp, 0, Length, Packet, NULL, NULL, NULL);\r
+\r
+ if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ break;\r
+ }\r
+ \r
+ //\r
+ // If Status is EFI_SUCCESS, the packet is put in the transmit queue.\r
+ // if Status is EFI_NOT_READY, the transmit engine of the network\r
+ // interface is busy. Both need to sync SNP.\r
+ //\r
+ TxBuf = NULL;\r
+\r
+ do {\r
+ //\r
+ // Get the recycled transmit buffer status.\r
+ //\r
+ Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf);\r
+\r
+ if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
+ Status = EFI_TIMEOUT;\r
+ break;\r
+ }\r
+\r
+ } while (TxBuf == NULL);\r
+\r
+ if ((Status == EFI_SUCCESS) || (Status == EFI_TIMEOUT)) {\r
+ break;\r
+ }\r
+ \r
+ //\r
+ // Status is EFI_NOT_READY. Restart the timer event and\r
+ // call Snp->Transmit again.\r
+ //\r
+ gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);\r
+ }\r
+\r
+ gBS->SetTimer (TimeoutEvent, TimerCancel, 0);\r
+\r
+ON_EXIT:\r
+ gBS->CloseEvent (TimeoutEvent);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Build a syslog packet, including the Ethernet/Ip/Udp headers \r
+ and user's message. \r
+ \r
+ @param[in] Level - Syslog servity level\r
+ @param[in] Module - The module that generates the log\r
+ @param[in] File - The file that contains the current log\r
+ @param[in] Line - The line of code in the File that contains the current log\r
+ @param[in] Message - The log message\r
+ @param[in] BufLen - The lenght of the Buf\r
+ @param[out] Buf - The buffer to put the packet data\r
+\r
+Returns:\r
+\r
+ The length of the syslog packet built.\r
+\r
+**/\r
+UINT32\r
+SyslogBuildPacket (\r
+ IN UINT32 Level,\r
+ IN UINT8 *Module,\r
+ IN UINT8 *File,\r
+ IN UINT32 Line,\r
+ IN UINT8 *Message,\r
+ IN UINT32 BufLen,\r
+ OUT CHAR8 *Buf \r
+ )\r
+{\r
+ ETHER_HEAD *Ether;\r
+ IP4_HEAD *Ip4;\r
+ EFI_UDP_HEADER *Udp4;\r
+ EFI_TIME Time;\r
+ UINT32 Pri;\r
+ UINT32 Len;\r
+\r
+ //\r
+ // Fill in the Ethernet header. Leave alone the source MAC. \r
+ // SyslogSendPacket will fill in the address for us.\r
+ //\r
+ Ether = (ETHER_HEAD *) Buf;\r
+ CopyMem (Ether->DstMac, mSyslogDstMac, NET_ETHER_ADDR_LEN);\r
+ ZeroMem (Ether->SrcMac, NET_ETHER_ADDR_LEN);\r
+\r
+ Ether->EtherType = HTONS (0x0800); // IPv4 protocol\r
+\r
+ Buf += sizeof (ETHER_HEAD);\r
+ BufLen -= sizeof (ETHER_HEAD);\r
+\r
+ //\r
+ // Fill in the IP header\r
+ //\r
+ Ip4 = (IP4_HEAD *) Buf;\r
+ Ip4->HeadLen = 5;\r
+ Ip4->Ver = 4;\r
+ Ip4->Tos = 0;\r
+ Ip4->TotalLen = 0;\r
+ Ip4->Id = (UINT16) mSyslogPacketSeq;\r
+ Ip4->Fragment = 0;\r
+ Ip4->Ttl = 16;\r
+ Ip4->Protocol = 0x11;\r
+ Ip4->Checksum = 0;\r
+ Ip4->Src = mSyslogSrcIp;\r
+ Ip4->Dst = mSyslogDstIp;\r
+\r
+ Buf += sizeof (IP4_HEAD);\r
+ BufLen -= sizeof (IP4_HEAD);\r
+\r
+ //\r
+ // Fill in the UDP header, Udp checksum is optional. Leave it zero.\r
+ //\r
+ Udp4 = (EFI_UDP_HEADER *) Buf;\r
+ Udp4->SrcPort = HTONS (514);\r
+ Udp4->DstPort = HTONS (514);\r
+ Udp4->Length = 0;\r
+ Udp4->Checksum = 0;\r
+\r
+ Buf += sizeof (EFI_UDP_HEADER);\r
+ BufLen -= sizeof (EFI_UDP_HEADER);\r
+\r
+ //\r
+ // Build the syslog message body with <PRI> Timestamp machine module Message\r
+ //\r
+ Pri = ((NET_SYSLOG_FACILITY & 31) << 3) | (Level & 7);\r
+ gRT->GetTime (&Time, NULL);\r
+\r
+ //\r
+ // Use %a to format the ASCII strings, %s to format UNICODE strings\r
+ //\r
+ Len = 0;\r
+ Len += (UINT32) AsciiSPrint (\r
+ Buf,\r
+ BufLen,\r
+ "<%d> %a %d %d:%d:%d ",\r
+ Pri,\r
+ mMonthName [Time.Month-1], \r
+ Time.Day,\r
+ Time.Hour,\r
+ Time.Minute,\r
+ Time.Second\r
+ );\r
+ Len--;\r
+\r
+ Len += (UINT32) AsciiSPrint (\r
+ Buf + Len, \r
+ BufLen - Len, \r
+ "Tiano %a: %a (Line: %d File: %a)", \r
+ Module,\r
+ Message,\r
+ Line,\r
+ File\r
+ );\r
+ Len--;\r
+\r
+ //\r
+ // OK, patch the IP length/checksum and UDP length fields.\r
+ //\r
+ Len += sizeof (EFI_UDP_HEADER);\r
+ Udp4->Length = HTONS ((UINT16) Len);\r
+\r
+ Len += sizeof (IP4_HEAD);\r
+ Ip4->TotalLen = HTONS ((UINT16) Len);\r
+ Ip4->Checksum = (UINT16) (~NetblockChecksum ((UINT8 *) Ip4, sizeof (IP4_HEAD)));\r
+\r
+ return Len + sizeof (ETHER_HEAD);\r
+}\r
+\r
+/**\r
+ Allocate a buffer, then format the message to it. This is a \r
+ help function for the NET_DEBUG_XXX macros. The PrintArg of \r
+ these macros treats the variable length print parameters as a \r
+ single parameter, and pass it to the NetDebugASPrint. For\r
+ example, NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name))\r
+ if extracted to: \r
+ \r
+ NetDebugOutput (\r
+ NETDEBUG_LEVEL_TRACE, \r
+ "Tcp", \r
+ __FILE__,\r
+ __LINE__,\r
+ NetDebugASPrint ("State transit to %a\n", Name) \r
+ ) \r
+ \r
+ @param Format The ASCII format string.\r
+ @param ... The variable length parameter whose format is determined \r
+ by the Format string.\r
+\r
+ @return The buffer containing the formatted message,\r
+ or NULL if failed to allocate memory.\r
+\r
+**/\r
+CHAR8 *\r
+NetDebugASPrint (\r
+ IN CHAR8 *Format,\r
+ ...\r
+ )\r
+{\r
+ VA_LIST Marker;\r
+ CHAR8 *Buf;\r
+\r
+ Buf = (CHAR8 *) AllocatePool (NET_DEBUG_MSG_LEN);\r
+\r
+ if (Buf == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ VA_START (Marker, Format);\r
+ AsciiVSPrint (Buf, NET_DEBUG_MSG_LEN, Format, Marker);\r
+ VA_END (Marker);\r
+\r
+ return Buf;\r
+}\r
+\r
+/**\r
+ Builds an UDP4 syslog packet and send it using SNP.\r
+\r
+ This function will locate a instance of SNP then send the message through it.\r
+ Because it isn't open the SNP BY_DRIVER, apply caution when using it.\r
+\r
+ @param Level The servity level of the message.\r
+ @param Module The Moudle that generates the log.\r
+ @param File The file that contains the log.\r
+ @param Line The exact line that contains the log.\r
+ @param Message The user message to log.\r
+\r
+ @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet\r
+ @retval EFI_SUCCESS The log is discard because that it is more verbose \r
+ than the mNetDebugLevelMax. Or, it has been sent out.\r
+**/ \r
+EFI_STATUS\r
+NetDebugOutput (\r
+ IN UINT32 Level, \r
+ IN UINT8 *Module,\r
+ IN UINT8 *File,\r
+ IN UINT32 Line,\r
+ IN UINT8 *Message\r
+ )\r
+{\r
+ CHAR8 *Packet;\r
+ UINT32 Len;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check whether the message should be sent out\r
+ //\r
+ if (Message == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Level > mNetDebugLevelMax) {\r
+ Status = EFI_SUCCESS;\r
+ goto ON_EXIT;\r
+ }\r
+ \r
+ //\r
+ // Allocate a maxium of 1024 bytes, the caller should ensure\r
+ // that the message plus the ethernet/ip/udp header is shorter\r
+ // than this\r
+ //\r
+ Packet = (CHAR8 *) AllocatePool (NET_SYSLOG_PACKET_LEN);\r
+\r
+ if (Packet == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ \r
+ //\r
+ // Build the message: Ethernet header + IP header + Udp Header + user data\r
+ //\r
+ Len = SyslogBuildPacket (\r
+ Level,\r
+ Module,\r
+ File,\r
+ Line,\r
+ Message,\r
+ NET_SYSLOG_PACKET_LEN,\r
+ Packet\r
+ );\r
+\r
+ mSyslogPacketSeq++;\r
+ Status = SyslogSendPacket (Packet, Len);\r
+ FreePool (Packet);\r
+\r
+ON_EXIT:\r
+ FreePool (Message);\r
+ return Status;\r
+}\r
/**\r
Return the length of the mask. \r
\r
**/\r
BOOLEAN\r
EFIAPI\r
-Ip4IsUnicast (\r
+NetIp4IsUnicast (\r
IN IP4_ADDR Ip,\r
IN IP4_ADDR NetMask\r
)\r
return TRUE;\r
}\r
\r
+/**\r
+ Check whether the incoming IPv6 address is a valid unicast address.\r
+\r
+ If the address is a multicast address has binary 0xFF at the start, it is not\r
+ a valid unicast address. If the address is unspecified ::, it is not a valid\r
+ unicast address to be assigned to any node. If the address is loopback address\r
+ ::1, it is also not a valid unicast address to be assigned to any physical\r
+ interface. \r
+\r
+ @param[in] Ip6 The IPv6 address to check against.\r
+\r
+ @return TRUE if Ip6 is a valid unicast address on the network, otherwise FALSE.\r
+\r
+**/ \r
+BOOLEAN\r
+NetIp6IsValidUnicast (\r
+ IN EFI_IPv6_ADDRESS *Ip6\r
+ ) \r
+{\r
+ UINT8 Byte;\r
+ UINT8 Index;\r
+ \r
+ if (Ip6->Addr[0] == 0xFF) {\r
+ return FALSE;\r
+ }\r
+\r
+ for (Index = 0; Index < 15; Index++) {\r
+ if (Ip6->Addr[Index] != 0) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ Byte = Ip6->Addr[Index];\r
+\r
+ if (Byte == 0x0 || Byte == 0x1) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE; \r
+}\r
+\r
+/**\r
+ Check whether the incoming Ipv6 address is the unspecified address or not.\r
+\r
+ @param[in] Ip6 - Ip6 address, in network order.\r
+\r
+ @retval TRUE - Yes, unspecified\r
+ @retval FALSE - No\r
+ \r
+**/\r
+BOOLEAN\r
+NetIp6IsUnspecifiedAddr (\r
+ IN EFI_IPv6_ADDRESS *Ip6\r
+ )\r
+{\r
+ UINT8 Index;\r
+\r
+ for (Index = 0; Index < 16; Index++) {\r
+ if (Ip6->Addr[Index] != 0) {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Check whether the incoming Ipv6 address is a link-local address.\r
+\r
+ @param[in] Ip6 - Ip6 address, in network order.\r
+\r
+ @retval TRUE - Yes, link-local address\r
+ @retval FALSE - No\r
+ \r
+**/\r
+BOOLEAN\r
+NetIp6IsLinkLocalAddr (\r
+ IN EFI_IPv6_ADDRESS *Ip6\r
+ )\r
+{\r
+ UINT8 Index;\r
+ \r
+ ASSERT (Ip6 != NULL);\r
+\r
+ if (Ip6->Addr[0] != 0xFE) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if (Ip6->Addr[1] != 0x80) {\r
+ return FALSE;\r
+ }\r
+\r
+ for (Index = 2; Index < 8; Index++) {\r
+ if (Ip6->Addr[Index] != 0) {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Check whether the Ipv6 address1 and address2 are on the connected network.\r
+\r
+ @param[in] Ip1 - Ip6 address1, in network order.\r
+ @param[in] Ip2 - Ip6 address2, in network order.\r
+ @param[in] PrefixLength - The prefix length of the checking net.\r
+\r
+ @retval TRUE - Yes, connected.\r
+ @retval FALSE - No.\r
+ \r
+**/\r
+BOOLEAN\r
+NetIp6IsNetEqual (\r
+ EFI_IPv6_ADDRESS *Ip1,\r
+ EFI_IPv6_ADDRESS *Ip2,\r
+ UINT8 PrefixLength\r
+ )\r
+{\r
+ UINT8 Byte;\r
+ UINT8 Bit;\r
+ UINT8 Mask;\r
+\r
+ ASSERT (Ip1 != NULL && Ip2 != NULL);\r
+ \r
+ if (PrefixLength == 0) {\r
+ return TRUE;\r
+ }\r
+\r
+ Byte = (UINT8) (PrefixLength / 8);\r
+ Bit = (UINT8) (PrefixLength % 8);\r
+ \r
+ if (CompareMem (Ip1, Ip2, Byte) != 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (Bit > 0) {\r
+ Mask = (UINT8) (0xFF << (8 - Bit));\r
+\r
+ if ((Ip1->Addr[Byte] & Mask) != (Ip2->Addr[Byte] & Mask)) {\r
+ return FALSE;\r
+ } \r
+ }\r
+ \r
+ return TRUE;\r
+}\r
+\r
+\r
+/**\r
+ Switches the endianess of an IPv6 address\r
+\r
+ This function swaps the bytes in a 128-bit IPv6 address to switch the value\r
+ from little endian to big endian or vice versa. The byte swapped value is\r
+ returned.\r
+\r
+ @param Ip6 Points to an IPv6 address\r
+\r
+ @return The byte swapped IPv6 address.\r
+\r
+**/\r
+EFI_IPv6_ADDRESS *\r
+Ip6Swap128 (\r
+ EFI_IPv6_ADDRESS *Ip6\r
+ )\r
+{\r
+ UINT64 High;\r
+ UINT64 Low;\r
+\r
+ CopyMem (&High, Ip6, sizeof (UINT64));\r
+ CopyMem (&Low, &Ip6->Addr[8], sizeof (UINT64));\r
+\r
+ High = SwapBytes64 (High);\r
+ Low = SwapBytes64 (Low);\r
+\r
+ CopyMem (Ip6, &Low, sizeof (UINT64));\r
+ CopyMem (&Ip6->Addr[8], &High, sizeof (UINT64));\r
+\r
+ return Ip6;\r
+}\r
\r
/**\r
Initialize a random seed using current time.\r
// Construct config request string header\r
//\r
ConfigHdr = HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, Controller);\r
+ if (ConfigHdr == NULL) {\r
+ return TRUE;\r
+ }\r
\r
Len = StrLen (ConfigHdr);\r
- ConfigResp = AllocateZeroPool (Len + NIC_ITEM_CONFIG_SIZE * 2 + 200);\r
+ ConfigResp = AllocateZeroPool ((Len + NIC_ITEM_CONFIG_SIZE * 2 + 100) * sizeof (CHAR16));\r
if (ConfigResp == NULL) {\r
goto ON_EXIT;\r
}\r
String = ConfigResp + Len;\r
UnicodeSPrint (\r
String, \r
- (8 + 4 + 7 + 4) * sizeof (CHAR16), \r
+ (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16), \r
L"&OFFSET=%04X&WIDTH=%04X", \r
OFFSET_OF (NIC_IP4_CONFIG_INFO, Source), \r
sizeof (UINT32)\r
goto ON_EXIT;\r
}\r
\r
- ConfigInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO));\r
+ ConfigInfo = AllocateZeroPool (sizeof (NIC_ITEM_CONFIG_SIZE));\r
if (ConfigInfo == NULL) {\r
goto ON_EXIT;\r
}\r
Get other info from parameters to make up the whole IPv4 device path node.\r
\r
@param[in, out] Node Pointer to the IPv4 device path node.\r
- @param[in] Controller The handle where the NIC IP4 config protocol resides.\r
+ @param[in] Controller The controller handle.\r
@param[in] LocalIp The local IPv4 address.\r
@param[in] LocalPort The local port.\r
@param[in] RemoteIp The remote IPv4 address.\r
}\r
}\r
\r
+/**\r
+ Create an IPv6 device path node.\r
+ \r
+ The header type of IPv6 device path node is MESSAGING_DEVICE_PATH.\r
+ The header subtype of IPv6 device path node is MSG_IPv6_DP.\r
+ Get other info from parameters to make up the whole IPv6 device path node.\r
+\r
+ @param[in, out] Node Pointer to the IPv6 device path node.\r
+ @param[in] Controller The controller handle.\r
+ @param[in] LocalIp The local IPv6 address.\r
+ @param[in] LocalPort The local port.\r
+ @param[in] RemoteIp The remote IPv6 address.\r
+ @param[in] RemotePort The remote port.\r
+ @param[in] Protocol The protocol type in the IP header.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+NetLibCreateIPv6DPathNode (\r
+ IN OUT IPv6_DEVICE_PATH *Node,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_IPv6_ADDRESS *LocalIp,\r
+ IN UINT16 LocalPort,\r
+ IN EFI_IPv6_ADDRESS *RemoteIp,\r
+ IN UINT16 RemotePort,\r
+ IN UINT16 Protocol\r
+ )\r
+{\r
+ Node->Header.Type = MESSAGING_DEVICE_PATH;\r
+ Node->Header.SubType = MSG_IPv6_DP;\r
+ SetDevicePathNodeLength (&Node->Header, sizeof (IPv6_DEVICE_PATH));\r
+\r
+ CopyMem (&Node->LocalIpAddress, LocalIp, sizeof (EFI_IPv6_ADDRESS));\r
+ CopyMem (&Node->RemoteIpAddress, RemoteIp, sizeof (EFI_IPv6_ADDRESS));\r
+\r
+ Node->LocalPort = LocalPort;\r
+ Node->RemotePort = RemotePort;\r
+\r
+ Node->Protocol = Protocol;\r
+ Node->StaticIpAddress = FALSE;\r
+}\r
\r
/**\r
Find the UNDI/SNP handle from controller and protocol GUID.\r
gBS->FreePool (OpenBuffer);\r
return Handle;\r
}\r
-\r
-/**\r
- Add a Deferred Procedure Call to the end of the DPC queue.\r
-\r
- @param[in] DpcTpl The EFI_TPL that the DPC should be invoked.\r
- @param[in] DpcProcedure Pointer to the DPC's function.\r
- @param[in] DpcContext Pointer to the DPC's context. Passed to DpcProcedure\r
- when DpcProcedure is invoked.\r
-\r
- @retval EFI_SUCCESS The DPC was queued.\r
- @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL, or DpcProcedure\r
- is NULL.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to\r
- add the DPC to the queue.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibQueueDpc (\r
- IN EFI_TPL DpcTpl,\r
- IN EFI_DPC_PROCEDURE DpcProcedure,\r
- IN VOID *DpcContext OPTIONAL\r
- )\r
-{\r
- return mDpc->QueueDpc (mDpc, DpcTpl, DpcProcedure, DpcContext);\r
-}\r
-\r
-/**\r
- Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl\r
- value greater than or equal to the current TPL are invoked in the order that\r
- they were queued. DPCs with higher DpcTpl values are invoked before DPCs with\r
- lower DpcTpl values.\r
-\r
- @retval EFI_SUCCESS One or more DPCs were invoked.\r
- @retval EFI_NOT_FOUND No DPCs were invoked.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibDispatchDpc (\r
- VOID\r
- )\r
-{\r
- return mDpc->DispatchDpc(mDpc);\r
-}\r
-\r
-/**\r
- The constructor function caches the pointer to DPC protocol.\r
-\r
- The constructor function locates DPC protocol from protocol database.\r
- It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\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 constructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibConstructor (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID**) &mDpc);\r
- ASSERT_EFI_ERROR (Status);\r
- ASSERT (mDpc != NULL);\r
-\r
- return Status;\r
-}\r