[Change summary]:
1. Update NetLib to a combined NetLib support dual network stack: 1) Add Network Debug facility for IPv4 stack. 2) Extend the library APIs to support IPv6 stack: a. NetIp6IsUnspecifiedAddr b. NetIp6IsLinkLocalAddr c. NetIp6IsNetEqual d. NetLibCreateIPv6DPathNode. e. NetIp6PseudoHeadChecksum f. NetIp6IsValidUnicast 3) Update the structure definitions: a. Update NET_BUF to add EFI_IP6_HEADER and EFI_UDP_HEADER b. Add NET_IP6_PSEUDO_HDR 4) Update Ip4IsUnicast to NetIp4IsUnicast 2. Update the impacted modules to adopt the combined NetLib. 3. Clean up coding style errors in all network drivers and libraries. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9391 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -81,6 +81,452 @@ IP4_ADDR gIp4AllMasks[IP4_MASK_NUM] = {
|
||||
|
||||
EFI_IPv4_ADDRESS mZeroIp4Addr = {{0, 0, 0, 0}};
|
||||
|
||||
//
|
||||
// Any error level digitally larger than mNetDebugLevelMax
|
||||
// will be silently discarded.
|
||||
//
|
||||
UINTN mNetDebugLevelMax = NETDEBUG_LEVEL_ERROR;
|
||||
UINT32 mSyslogPacketSeq = 0xDEADBEEF;
|
||||
|
||||
//
|
||||
// You can change mSyslogDstMac mSyslogDstIp and mSyslogSrcIp
|
||||
// here to direct the syslog packets to the syslog deamon. The
|
||||
// default is broadcast to both the ethernet and IP.
|
||||
//
|
||||
UINT8 mSyslogDstMac[NET_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
UINT32 mSyslogDstIp = 0xffffffff;
|
||||
UINT32 mSyslogSrcIp = 0;
|
||||
|
||||
CHAR8 *
|
||||
mMonthName[] = {
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec"
|
||||
};
|
||||
|
||||
/**
|
||||
Locate the handles that support SNP, then open one of them
|
||||
to send the syslog packets. The caller isn't required to close
|
||||
the SNP after use because the SNP is opened by HandleProtocol.
|
||||
|
||||
@return The point to SNP if one is properly openned. Otherwise NULL
|
||||
|
||||
**/
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *
|
||||
SyslogLocateSnp (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *Handles;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Locate the handles which has SNP installed.
|
||||
//
|
||||
Handles = NULL;
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&Handles
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (HandleCount == 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to open one of the ethernet SNP protocol to send packet
|
||||
//
|
||||
Snp = NULL;
|
||||
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
Handles[Index],
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
(VOID **) &Snp
|
||||
);
|
||||
|
||||
if ((Status == EFI_SUCCESS) && (Snp != NULL) &&
|
||||
(Snp->Mode->IfType == NET_IFTYPE_ETHERNET) &&
|
||||
(Snp->Mode->MaxPacketSize >= NET_SYSLOG_PACKET_LEN)) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Snp = NULL;
|
||||
}
|
||||
|
||||
FreePool (Handles);
|
||||
return Snp;
|
||||
}
|
||||
|
||||
/**
|
||||
Transmit a syslog packet synchronously through SNP. The Packet
|
||||
already has the ethernet header prepended. This function should
|
||||
fill in the source MAC because it will try to locate a SNP each
|
||||
time it is called to avoid the problem if SNP is unloaded.
|
||||
This code snip is copied from MNP.
|
||||
|
||||
@param[in] Packet - The Syslog packet
|
||||
@param[in] Length - The length of the packet
|
||||
|
||||
@retval EFI_DEVICE_ERROR - Failed to locate a usable SNP protocol
|
||||
@retval EFI_TIMEOUT - Timeout happened to send the packet.
|
||||
@retval EFI_SUCCESS - Packet is sent.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SyslogSendPacket (
|
||||
IN CHAR8 *Packet,
|
||||
IN UINT32 Length
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
ETHER_HEAD *Ether;
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT TimeoutEvent;
|
||||
UINT8 *TxBuf;
|
||||
|
||||
Snp = SyslogLocateSnp ();
|
||||
|
||||
if (Snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Ether = (ETHER_HEAD *) Packet;
|
||||
CopyMem (Ether->SrcMac, Snp->Mode->CurrentAddress.Addr, NET_ETHER_ADDR_LEN);
|
||||
|
||||
//
|
||||
// Start the timeout event.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER,
|
||||
TPL_NOTIFY,
|
||||
NULL,
|
||||
NULL,
|
||||
&TimeoutEvent
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
//
|
||||
// Transmit the packet through SNP.
|
||||
//
|
||||
Status = Snp->Transmit (Snp, 0, Length, Packet, NULL, NULL, NULL);
|
||||
|
||||
if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// If Status is EFI_SUCCESS, the packet is put in the transmit queue.
|
||||
// if Status is EFI_NOT_READY, the transmit engine of the network
|
||||
// interface is busy. Both need to sync SNP.
|
||||
//
|
||||
TxBuf = NULL;
|
||||
|
||||
do {
|
||||
//
|
||||
// Get the recycled transmit buffer status.
|
||||
//
|
||||
Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf);
|
||||
|
||||
if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
|
||||
Status = EFI_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
} while (TxBuf == NULL);
|
||||
|
||||
if ((Status == EFI_SUCCESS) || (Status == EFI_TIMEOUT)) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Status is EFI_NOT_READY. Restart the timer event and
|
||||
// call Snp->Transmit again.
|
||||
//
|
||||
gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);
|
||||
}
|
||||
|
||||
gBS->SetTimer (TimeoutEvent, TimerCancel, 0);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->CloseEvent (TimeoutEvent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Build a syslog packet, including the Ethernet/Ip/Udp headers
|
||||
and user's message.
|
||||
|
||||
@param[in] Level - Syslog servity level
|
||||
@param[in] Module - The module that generates the log
|
||||
@param[in] File - The file that contains the current log
|
||||
@param[in] Line - The line of code in the File that contains the current log
|
||||
@param[in] Message - The log message
|
||||
@param[in] BufLen - The lenght of the Buf
|
||||
@param[out] Buf - The buffer to put the packet data
|
||||
|
||||
Returns:
|
||||
|
||||
The length of the syslog packet built.
|
||||
|
||||
**/
|
||||
UINT32
|
||||
SyslogBuildPacket (
|
||||
IN UINT32 Level,
|
||||
IN UINT8 *Module,
|
||||
IN UINT8 *File,
|
||||
IN UINT32 Line,
|
||||
IN UINT8 *Message,
|
||||
IN UINT32 BufLen,
|
||||
OUT CHAR8 *Buf
|
||||
)
|
||||
{
|
||||
ETHER_HEAD *Ether;
|
||||
IP4_HEAD *Ip4;
|
||||
EFI_UDP_HEADER *Udp4;
|
||||
EFI_TIME Time;
|
||||
UINT32 Pri;
|
||||
UINT32 Len;
|
||||
|
||||
//
|
||||
// Fill in the Ethernet header. Leave alone the source MAC.
|
||||
// SyslogSendPacket will fill in the address for us.
|
||||
//
|
||||
Ether = (ETHER_HEAD *) Buf;
|
||||
CopyMem (Ether->DstMac, mSyslogDstMac, NET_ETHER_ADDR_LEN);
|
||||
ZeroMem (Ether->SrcMac, NET_ETHER_ADDR_LEN);
|
||||
|
||||
Ether->EtherType = HTONS (0x0800); // IPv4 protocol
|
||||
|
||||
Buf += sizeof (ETHER_HEAD);
|
||||
BufLen -= sizeof (ETHER_HEAD);
|
||||
|
||||
//
|
||||
// Fill in the IP header
|
||||
//
|
||||
Ip4 = (IP4_HEAD *) Buf;
|
||||
Ip4->HeadLen = 5;
|
||||
Ip4->Ver = 4;
|
||||
Ip4->Tos = 0;
|
||||
Ip4->TotalLen = 0;
|
||||
Ip4->Id = (UINT16) mSyslogPacketSeq;
|
||||
Ip4->Fragment = 0;
|
||||
Ip4->Ttl = 16;
|
||||
Ip4->Protocol = 0x11;
|
||||
Ip4->Checksum = 0;
|
||||
Ip4->Src = mSyslogSrcIp;
|
||||
Ip4->Dst = mSyslogDstIp;
|
||||
|
||||
Buf += sizeof (IP4_HEAD);
|
||||
BufLen -= sizeof (IP4_HEAD);
|
||||
|
||||
//
|
||||
// Fill in the UDP header, Udp checksum is optional. Leave it zero.
|
||||
//
|
||||
Udp4 = (EFI_UDP_HEADER *) Buf;
|
||||
Udp4->SrcPort = HTONS (514);
|
||||
Udp4->DstPort = HTONS (514);
|
||||
Udp4->Length = 0;
|
||||
Udp4->Checksum = 0;
|
||||
|
||||
Buf += sizeof (EFI_UDP_HEADER);
|
||||
BufLen -= sizeof (EFI_UDP_HEADER);
|
||||
|
||||
//
|
||||
// Build the syslog message body with <PRI> Timestamp machine module Message
|
||||
//
|
||||
Pri = ((NET_SYSLOG_FACILITY & 31) << 3) | (Level & 7);
|
||||
gRT->GetTime (&Time, NULL);
|
||||
|
||||
//
|
||||
// Use %a to format the ASCII strings, %s to format UNICODE strings
|
||||
//
|
||||
Len = 0;
|
||||
Len += (UINT32) AsciiSPrint (
|
||||
Buf,
|
||||
BufLen,
|
||||
"<%d> %a %d %d:%d:%d ",
|
||||
Pri,
|
||||
mMonthName [Time.Month-1],
|
||||
Time.Day,
|
||||
Time.Hour,
|
||||
Time.Minute,
|
||||
Time.Second
|
||||
);
|
||||
Len--;
|
||||
|
||||
Len += (UINT32) AsciiSPrint (
|
||||
Buf + Len,
|
||||
BufLen - Len,
|
||||
"Tiano %a: %a (Line: %d File: %a)",
|
||||
Module,
|
||||
Message,
|
||||
Line,
|
||||
File
|
||||
);
|
||||
Len--;
|
||||
|
||||
//
|
||||
// OK, patch the IP length/checksum and UDP length fields.
|
||||
//
|
||||
Len += sizeof (EFI_UDP_HEADER);
|
||||
Udp4->Length = HTONS ((UINT16) Len);
|
||||
|
||||
Len += sizeof (IP4_HEAD);
|
||||
Ip4->TotalLen = HTONS ((UINT16) Len);
|
||||
Ip4->Checksum = (UINT16) (~NetblockChecksum ((UINT8 *) Ip4, sizeof (IP4_HEAD)));
|
||||
|
||||
return Len + sizeof (ETHER_HEAD);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocate a buffer, then format the message to it. This is a
|
||||
help function for the NET_DEBUG_XXX macros. The PrintArg of
|
||||
these macros treats the variable length print parameters as a
|
||||
single parameter, and pass it to the NetDebugASPrint. For
|
||||
example, NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name))
|
||||
if extracted to:
|
||||
|
||||
NetDebugOutput (
|
||||
NETDEBUG_LEVEL_TRACE,
|
||||
"Tcp",
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
NetDebugASPrint ("State transit to %a\n", Name)
|
||||
)
|
||||
|
||||
@param Format The ASCII format string.
|
||||
@param ... The variable length parameter whose format is determined
|
||||
by the Format string.
|
||||
|
||||
@return The buffer containing the formatted message,
|
||||
or NULL if failed to allocate memory.
|
||||
|
||||
**/
|
||||
CHAR8 *
|
||||
NetDebugASPrint (
|
||||
IN CHAR8 *Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
VA_LIST Marker;
|
||||
CHAR8 *Buf;
|
||||
|
||||
Buf = (CHAR8 *) AllocatePool (NET_DEBUG_MSG_LEN);
|
||||
|
||||
if (Buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VA_START (Marker, Format);
|
||||
AsciiVSPrint (Buf, NET_DEBUG_MSG_LEN, Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
return Buf;
|
||||
}
|
||||
|
||||
/**
|
||||
Builds an UDP4 syslog packet and send it using SNP.
|
||||
|
||||
This function will locate a instance of SNP then send the message through it.
|
||||
Because it isn't open the SNP BY_DRIVER, apply caution when using it.
|
||||
|
||||
@param Level The servity level of the message.
|
||||
@param Module The Moudle that generates the log.
|
||||
@param File The file that contains the log.
|
||||
@param Line The exact line that contains the log.
|
||||
@param Message The user message to log.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet
|
||||
@retval EFI_SUCCESS The log is discard because that it is more verbose
|
||||
than the mNetDebugLevelMax. Or, it has been sent out.
|
||||
**/
|
||||
EFI_STATUS
|
||||
NetDebugOutput (
|
||||
IN UINT32 Level,
|
||||
IN UINT8 *Module,
|
||||
IN UINT8 *File,
|
||||
IN UINT32 Line,
|
||||
IN UINT8 *Message
|
||||
)
|
||||
{
|
||||
CHAR8 *Packet;
|
||||
UINT32 Len;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Check whether the message should be sent out
|
||||
//
|
||||
if (Message == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Level > mNetDebugLevelMax) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a maxium of 1024 bytes, the caller should ensure
|
||||
// that the message plus the ethernet/ip/udp header is shorter
|
||||
// than this
|
||||
//
|
||||
Packet = (CHAR8 *) AllocatePool (NET_SYSLOG_PACKET_LEN);
|
||||
|
||||
if (Packet == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Build the message: Ethernet header + IP header + Udp Header + user data
|
||||
//
|
||||
Len = SyslogBuildPacket (
|
||||
Level,
|
||||
Module,
|
||||
File,
|
||||
Line,
|
||||
Message,
|
||||
NET_SYSLOG_PACKET_LEN,
|
||||
Packet
|
||||
);
|
||||
|
||||
mSyslogPacketSeq++;
|
||||
Status = SyslogSendPacket (Packet, Len);
|
||||
FreePool (Packet);
|
||||
|
||||
ON_EXIT:
|
||||
FreePool (Message);
|
||||
return Status;
|
||||
}
|
||||
/**
|
||||
Return the length of the mask.
|
||||
|
||||
@ -179,7 +625,7 @@ NetGetIpClass (
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
Ip4IsUnicast (
|
||||
NetIp4IsUnicast (
|
||||
IN IP4_ADDR Ip,
|
||||
IN IP4_ADDR NetMask
|
||||
)
|
||||
@ -218,7 +664,7 @@ Ip4IsUnicast (
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
Ip6IsValidUnicast (
|
||||
NetIp6IsValidUnicast (
|
||||
IN EFI_IPv6_ADDRESS *Ip6
|
||||
)
|
||||
{
|
||||
@ -244,6 +690,113 @@ Ip6IsValidUnicast (
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the incoming Ipv6 address is the unspecified address or not.
|
||||
|
||||
@param[in] Ip6 - Ip6 address, in network order.
|
||||
|
||||
@retval TRUE - Yes, unspecified
|
||||
@retval FALSE - No
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
NetIp6IsUnspecifiedAddr (
|
||||
IN EFI_IPv6_ADDRESS *Ip6
|
||||
)
|
||||
{
|
||||
UINT8 Index;
|
||||
|
||||
for (Index = 0; Index < 16; Index++) {
|
||||
if (Ip6->Addr[Index] != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the incoming Ipv6 address is a link-local address.
|
||||
|
||||
@param[in] Ip6 - Ip6 address, in network order.
|
||||
|
||||
@retval TRUE - Yes, link-local address
|
||||
@retval FALSE - No
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
NetIp6IsLinkLocalAddr (
|
||||
IN EFI_IPv6_ADDRESS *Ip6
|
||||
)
|
||||
{
|
||||
UINT8 Index;
|
||||
|
||||
ASSERT (Ip6 != NULL);
|
||||
|
||||
if (Ip6->Addr[0] != 0xFE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Ip6->Addr[1] != 0x80) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (Index = 2; Index < 8; Index++) {
|
||||
if (Ip6->Addr[Index] != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the Ipv6 address1 and address2 are on the connected network.
|
||||
|
||||
@param[in] Ip1 - Ip6 address1, in network order.
|
||||
@param[in] Ip2 - Ip6 address2, in network order.
|
||||
@param[in] PrefixLength - The prefix length of the checking net.
|
||||
|
||||
@retval TRUE - Yes, connected.
|
||||
@retval FALSE - No.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
NetIp6IsNetEqual (
|
||||
EFI_IPv6_ADDRESS *Ip1,
|
||||
EFI_IPv6_ADDRESS *Ip2,
|
||||
UINT8 PrefixLength
|
||||
)
|
||||
{
|
||||
UINT8 Byte;
|
||||
UINT8 Bit;
|
||||
UINT8 Mask;
|
||||
|
||||
ASSERT (Ip1 != NULL && Ip2 != NULL);
|
||||
|
||||
if (PrefixLength == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Byte = (UINT8) (PrefixLength / 8);
|
||||
Bit = (UINT8) (PrefixLength % 8);
|
||||
|
||||
if (CompareMem (Ip1, Ip2, Byte) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Bit > 0) {
|
||||
Mask = (UINT8) (0xFF << (8 - Bit));
|
||||
|
||||
if ((Ip1->Addr[Byte] & Mask) != (Ip2->Addr[Byte] & Mask)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Switches the endianess of an IPv6 address
|
||||
|
||||
@ -1432,7 +1985,7 @@ ON_EXIT:
|
||||
Get other info from parameters to make up the whole IPv4 device path node.
|
||||
|
||||
@param[in, out] Node Pointer to the IPv4 device path node.
|
||||
@param[in] Controller The handle where the NIC IP4 config protocol resides.
|
||||
@param[in] Controller The controller handle.
|
||||
@param[in] LocalIp The local IPv4 address.
|
||||
@param[in] LocalPort The local port.
|
||||
@param[in] RemoteIp The remote IPv4 address.
|
||||
@ -1473,6 +2026,47 @@ NetLibCreateIPv4DPathNode (
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Create an IPv6 device path node.
|
||||
|
||||
The header type of IPv6 device path node is MESSAGING_DEVICE_PATH.
|
||||
The header subtype of IPv6 device path node is MSG_IPv6_DP.
|
||||
Get other info from parameters to make up the whole IPv6 device path node.
|
||||
|
||||
@param[in, out] Node Pointer to the IPv6 device path node.
|
||||
@param[in] Controller The controller handle.
|
||||
@param[in] LocalIp The local IPv6 address.
|
||||
@param[in] LocalPort The local port.
|
||||
@param[in] RemoteIp The remote IPv6 address.
|
||||
@param[in] RemotePort The remote port.
|
||||
@param[in] Protocol The protocol type in the IP header.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
NetLibCreateIPv6DPathNode (
|
||||
IN OUT IPv6_DEVICE_PATH *Node,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_IPv6_ADDRESS *LocalIp,
|
||||
IN UINT16 LocalPort,
|
||||
IN EFI_IPv6_ADDRESS *RemoteIp,
|
||||
IN UINT16 RemotePort,
|
||||
IN UINT16 Protocol
|
||||
)
|
||||
{
|
||||
Node->Header.Type = MESSAGING_DEVICE_PATH;
|
||||
Node->Header.SubType = MSG_IPv6_DP;
|
||||
SetDevicePathNodeLength (&Node->Header, sizeof (IPv6_DEVICE_PATH));
|
||||
|
||||
CopyMem (&Node->LocalIpAddress, LocalIp, sizeof (EFI_IPv6_ADDRESS));
|
||||
CopyMem (&Node->RemoteIpAddress, RemoteIp, sizeof (EFI_IPv6_ADDRESS));
|
||||
|
||||
Node->LocalPort = LocalPort;
|
||||
Node->RemotePort = RemotePort;
|
||||
|
||||
Node->Protocol = Protocol;
|
||||
Node->StaticIpAddress = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the UNDI/SNP handle from controller and protocol GUID.
|
||||
|
Reference in New Issue
Block a user