+++ /dev/null
-/** @file\r
- Implement the UDP4 driver support for the socket layer.\r
-\r
- Copyright (c) 2011, Intel Corporation. All rights reserved.\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Socket.h"\r
-\r
-\r
-/**\r
- Get the local socket address\r
-\r
- This routine returns the IPv6 address and UDP port number associated\r
- with the local socket.\r
-\r
- This routine is called by ::EslSocketGetLocalAddress to determine the\r
- network address for the SOCK_DGRAM socket.\r
-\r
- @param [in] pPort Address of an ::ESL_PORT structure.\r
-\r
- @param [out] pSockAddr Network address to receive the local system address\r
-\r
-**/\r
-VOID\r
-EslUdp6LocalAddressGet (\r
- IN ESL_PORT * pPort,\r
- OUT struct sockaddr * pSockAddr\r
- )\r
-{\r
- struct sockaddr_in6 * pLocalAddress;\r
- ESL_UDP6_CONTEXT * pUdp6;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Return the local address\r
- //\r
- pUdp6 = &pPort->Context.Udp6;\r
- pLocalAddress = (struct sockaddr_in6 *)pSockAddr;\r
- pLocalAddress->sin6_family = AF_INET6;\r
- pLocalAddress->sin6_port = SwapBytes16 ( pUdp6->ConfigData.StationPort );\r
- CopyMem ( &pLocalAddress->sin6_addr,\r
- &pUdp6->ConfigData.StationAddress.Addr[0],\r
- sizeof ( pLocalAddress->sin6_addr ));\r
-\r
- DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
- Set the local port address.\r
-\r
- This routine sets the local port address.\r
-\r
- This support routine is called by ::EslSocketPortAllocate.\r
-\r
- @param [in] pPort Address of an ESL_PORT structure\r
- @param [in] pSockAddr Address of a sockaddr structure that contains the\r
- connection point on the local machine. An IPv6 address\r
- of INADDR_ANY specifies that the connection is made to\r
- all of the network stacks on the platform. Specifying a\r
- specific IPv6 address restricts the connection to the\r
- network stack supporting that address. Specifying zero\r
- for the port causes the network layer to assign a port\r
- number from the dynamic range. Specifying a specific\r
- port number causes the network layer to use that port.\r
-\r
- @param [in] bBindTest TRUE = run bind testing\r
-\r
- @retval EFI_SUCCESS The operation was successful\r
-\r
- **/\r
-EFI_STATUS\r
-EslUdp6LocalAddressSet (\r
- IN ESL_PORT * pPort,\r
- IN CONST struct sockaddr * pSockAddr,\r
- IN BOOLEAN bBindTest\r
- )\r
-{\r
- EFI_UDP6_CONFIG_DATA * pConfig;\r
- CONST struct sockaddr_in6 * pIpAddress;\r
- CONST UINT8 * pIPv6Address;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Set the local address\r
- //\r
- pIpAddress = (struct sockaddr_in6 *)pSockAddr;\r
- pIPv6Address = (UINT8 *)&pIpAddress->sin6_addr;\r
- pConfig = &pPort->Context.Udp6.ConfigData;\r
- CopyMem ( &pConfig->StationAddress,\r
- pIPv6Address,\r
- sizeof ( pConfig->StationAddress ));\r
-\r
- //\r
- // Validate the IP address\r
- //\r
- pConfig->StationPort = 0;\r
- Status = bBindTest ? EslSocketBindTest ( pPort, EADDRNOTAVAIL )\r
- : EFI_SUCCESS;\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Set the port number\r
- //\r
- pConfig->StationPort = SwapBytes16 ( pIpAddress->sin6_port );\r
- pPort->pSocket->bAddressSet = TRUE;\r
-\r
- //\r
- // Display the local address\r
- //\r
- DEBUG (( DEBUG_BIND,\r
- "0x%08x: Port, Local UDP6 Address: [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- pPort,\r
- pConfig->StationAddress.Addr[0],\r
- pConfig->StationAddress.Addr[1],\r
- pConfig->StationAddress.Addr[2],\r
- pConfig->StationAddress.Addr[3],\r
- pConfig->StationAddress.Addr[4],\r
- pConfig->StationAddress.Addr[5],\r
- pConfig->StationAddress.Addr[6],\r
- pConfig->StationAddress.Addr[7],\r
- pConfig->StationAddress.Addr[8],\r
- pConfig->StationAddress.Addr[9],\r
- pConfig->StationAddress.Addr[10],\r
- pConfig->StationAddress.Addr[11],\r
- pConfig->StationAddress.Addr[12],\r
- pConfig->StationAddress.Addr[13],\r
- pConfig->StationAddress.Addr[14],\r
- pConfig->StationAddress.Addr[15],\r
- pConfig->StationPort ));\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Free a receive packet\r
-\r
- This routine performs the network specific operations necessary\r
- to free a receive packet.\r
-\r
- This routine is called by ::EslSocketPortCloseTxDone to free a\r
- receive packet.\r
-\r
- @param [in] pPacket Address of an ::ESL_PACKET structure.\r
- @param [in, out] pRxBytes Address of the count of RX bytes\r
-\r
-**/\r
-VOID\r
-EslUdp6PacketFree (\r
- IN ESL_PACKET * pPacket,\r
- IN OUT size_t * pRxBytes\r
- )\r
-{\r
- EFI_UDP6_RECEIVE_DATA * pRxData;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Account for the receive bytes\r
- //\r
- pRxData = pPacket->Op.Udp6Rx.pRxData;\r
- *pRxBytes -= pRxData->DataLength;\r
-\r
- //\r
- // Disconnect the buffer from the packet\r
- //\r
- pPacket->Op.Udp6Rx.pRxData = NULL;\r
-\r
- //\r
- // Return the buffer to the UDP6 driver\r
- //\r
- gBS->SignalEvent ( pRxData->RecycleSignal );\r
- DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
- Initialize the network specific portions of an ::ESL_PORT structure.\r
-\r
- This routine initializes the network specific portions of an\r
- ::ESL_PORT structure for use by the socket.\r
-\r
- This support routine is called by ::EslSocketPortAllocate\r
- to connect the socket with the underlying network adapter\r
- running the UDPv4 protocol.\r
-\r
- @param [in] pPort Address of an ESL_PORT structure\r
- @param [in] DebugFlags Flags for debug messages\r
-\r
- @retval EFI_SUCCESS - Socket successfully created\r
-\r
- **/\r
-EFI_STATUS\r
-EslUdp6PortAllocate (\r
- IN ESL_PORT * pPort,\r
- IN UINTN DebugFlags\r
- )\r
-{\r
- EFI_UDP6_CONFIG_DATA * pConfig;\r
- ESL_SOCKET * pSocket;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Initialize the port\r
- //\r
- pSocket = pPort->pSocket;\r
- pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Udp6Tx.TxData );\r
- pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Udp6Tx.Event );\r
- pSocket->TxTokenOffset = OFFSET_OF ( EFI_UDP6_COMPLETION_TOKEN, Packet.TxData );\r
-\r
- //\r
- // Save the cancel, receive and transmit addresses\r
- //\r
- pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.UDPv6->Configure;\r
- pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.UDPv6->Cancel;\r
- pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.UDPv6->Poll;\r
- pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv6->Receive;\r
- pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv6->Transmit;\r
-\r
- //\r
- // Do not drop packets\r
- //\r
- pConfig = &pPort->Context.Udp6.ConfigData;\r
- pConfig->ReceiveTimeout = 0;\r
- pConfig->ReceiveTimeout = pConfig->ReceiveTimeout;\r
-\r
- //\r
- // Set the configuration flags\r
- //\r
- pConfig->AllowDuplicatePort = TRUE;\r
- pConfig->AcceptAnyPort = FALSE;\r
- pConfig->AcceptPromiscuous = FALSE;\r
- pConfig->HopLimit = 255;\r
- pConfig->TrafficClass = 0;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Receive data from a network connection.\r
-\r
- This routine attempts to return buffered data to the caller. The\r
- data is removed from the urgent queue if the message flag MSG_OOB\r
- is specified, otherwise data is removed from the normal queue.\r
- See the \ref ReceiveEngine section.\r
-\r
- This routine is called by ::EslSocketReceive to handle the network\r
- specific receive operation to support SOCK_DGRAM sockets.\r
-\r
- @param [in] pPort Address of an ::ESL_PORT structure.\r
-\r
- @param [in] pPacket Address of an ::ESL_PACKET structure.\r
- \r
- @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed\r
- \r
- @param [in] BufferLength Length of the the buffer\r
- \r
- @param [in] pBuffer Address of a buffer to receive the data.\r
- \r
- @param [in] pDataLength Number of received data bytes in the buffer.\r
-\r
- @param [out] pAddress Network address to receive the remote system address\r
-\r
- @param [out] pSkipBytes Address to receive the number of bytes skipped\r
-\r
- @return Returns the address of the next free byte in the buffer.\r
-\r
- **/\r
-UINT8 *\r
-EslUdp6Receive (\r
- IN ESL_PORT * pPort,\r
- IN ESL_PACKET * pPacket,\r
- IN BOOLEAN * pbConsumePacket,\r
- IN size_t BufferLength,\r
- IN UINT8 * pBuffer,\r
- OUT size_t * pDataLength,\r
- OUT struct sockaddr * pAddress,\r
- OUT size_t * pSkipBytes\r
- )\r
-{\r
- size_t DataBytes;\r
- struct sockaddr_in6 * pRemoteAddress;\r
- EFI_UDP6_RECEIVE_DATA * pRxData;\r
-\r
- DBG_ENTER ( );\r
-\r
- pRxData = pPacket->Op.Udp6Rx.pRxData;\r
- //\r
- // Return the remote system address if requested\r
- //\r
- if ( NULL != pAddress ) {\r
- //\r
- // Build the remote address\r
- //\r
- DEBUG (( DEBUG_RX,\r
- "Getting packet remote address: [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- pRxData->UdpSession.SourceAddress.Addr[0],\r
- pRxData->UdpSession.SourceAddress.Addr[1],\r
- pRxData->UdpSession.SourceAddress.Addr[2],\r
- pRxData->UdpSession.SourceAddress.Addr[3],\r
- pRxData->UdpSession.SourceAddress.Addr[4],\r
- pRxData->UdpSession.SourceAddress.Addr[5],\r
- pRxData->UdpSession.SourceAddress.Addr[6],\r
- pRxData->UdpSession.SourceAddress.Addr[7],\r
- pRxData->UdpSession.SourceAddress.Addr[8],\r
- pRxData->UdpSession.SourceAddress.Addr[9],\r
- pRxData->UdpSession.SourceAddress.Addr[10],\r
- pRxData->UdpSession.SourceAddress.Addr[11],\r
- pRxData->UdpSession.SourceAddress.Addr[12],\r
- pRxData->UdpSession.SourceAddress.Addr[13],\r
- pRxData->UdpSession.SourceAddress.Addr[14],\r
- pRxData->UdpSession.SourceAddress.Addr[15],\r
- pRxData->UdpSession.SourcePort ));\r
- pRemoteAddress = (struct sockaddr_in6 *)pAddress;\r
- CopyMem ( &pRemoteAddress->sin6_addr,\r
- &pRxData->UdpSession.SourceAddress.Addr[0],\r
- sizeof ( pRemoteAddress->sin6_addr ));\r
- pRemoteAddress->sin6_port = SwapBytes16 ( pRxData->UdpSession.SourcePort );\r
- }\r
-\r
- //\r
- // Copy the received data\r
- //\r
- pBuffer = EslSocketCopyFragmentedBuffer ( pRxData->FragmentCount,\r
- (EFI_IP4_FRAGMENT_DATA *)&pRxData->FragmentTable[0],\r
- BufferLength,\r
- pBuffer,\r
- &DataBytes );\r
-\r
- //\r
- // Determine if the data is being read\r
- //\r
- if ( *pbConsumePacket ) {\r
- //\r
- // Display for the bytes consumed\r
- //\r
- DEBUG (( DEBUG_RX,\r
- "0x%08x: Port account for 0x%08x bytes\r\n",\r
- pPort,\r
- DataBytes ));\r
-\r
- //\r
- // Account for any discarded data\r
- //\r
- *pSkipBytes = pRxData->DataLength - DataBytes;\r
- }\r
-\r
- //\r
- // Return the data length and the buffer address\r
- //\r
- *pDataLength = DataBytes;\r
- DBG_EXIT_HEX ( pBuffer );\r
- return pBuffer;\r
-}\r
-\r
-\r
-/**\r
- Get the remote socket address\r
-\r
- This routine returns the address of the remote connection point\r
- associated with the SOCK_DGRAM socket.\r
-\r
- This routine is called by ::EslSocketGetPeerAddress to detemine\r
- the UDPv4 address and port number associated with the network adapter.\r
-\r
- @param [in] pPort Address of an ::ESL_PORT structure.\r
-\r
- @param [out] pAddress Network address to receive the remote system address\r
-\r
-**/\r
-VOID\r
-EslUdp6RemoteAddressGet (\r
- IN ESL_PORT * pPort,\r
- OUT struct sockaddr * pAddress\r
- )\r
-{\r
- struct sockaddr_in6 * pRemoteAddress;\r
- ESL_UDP6_CONTEXT * pUdp6;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Return the remote address\r
- //\r
- pUdp6 = &pPort->Context.Udp6;\r
- pRemoteAddress = (struct sockaddr_in6 *)pAddress;\r
- pRemoteAddress->sin6_family = AF_INET6;\r
- pRemoteAddress->sin6_port = SwapBytes16 ( pUdp6->ConfigData.RemotePort );\r
- CopyMem ( &pRemoteAddress->sin6_addr,\r
- &pUdp6->ConfigData.RemoteAddress.Addr[0],\r
- sizeof ( pRemoteAddress->sin6_addr ));\r
-\r
- DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
- Set the remote address\r
-\r
- This routine sets the remote address in the port.\r
-\r
- This routine is called by ::EslSocketConnect to specify the\r
- remote network address.\r
-\r
- @param [in] pPort Address of an ::ESL_PORT structure.\r
-\r
- @param [in] pSockAddr Network address of the remote system.\r
-\r
- @param [in] SockAddrLength Length in bytes of the network address.\r
-\r
- @retval EFI_SUCCESS The operation was successful\r
-\r
- **/\r
-EFI_STATUS\r
-EslUdp6RemoteAddressSet (\r
- IN ESL_PORT * pPort,\r
- IN CONST struct sockaddr * pSockAddr,\r
- IN socklen_t SockAddrLength\r
- )\r
-{\r
- CONST struct sockaddr_in6 * pRemoteAddress;\r
- ESL_UDP6_CONTEXT * pUdp6;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Set the remote address\r
- //\r
- pUdp6 = &pPort->Context.Udp6;\r
- pRemoteAddress = (struct sockaddr_in6 *)pSockAddr;\r
- CopyMem ( &pUdp6->ConfigData.RemoteAddress,\r
- &pRemoteAddress->sin6_addr,\r
- sizeof ( pUdp6->ConfigData.RemoteAddress ));\r
- pUdp6->ConfigData.RemotePort = SwapBytes16 ( pRemoteAddress->sin6_port );\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Process the receive completion\r
-\r
- This routine keeps the UDPv4 driver's buffer and queues it in\r
- in FIFO order to the data queue. The UDP6 driver's buffer will\r
- be returned by either ::EslUdp6Receive or ::EslSocketPortCloseTxDone.\r
- See the \ref ReceiveEngine section.\r
-\r
- This routine is called by the UDPv4 driver when data is\r
- received.\r
-\r
- @param [in] Event The receive completion event\r
-\r
- @param [in] pIo Address of an ::ESL_IO_MGMT structure\r
-\r
-**/\r
-VOID\r
-EslUdp6RxComplete (\r
- IN EFI_EVENT Event,\r
- IN ESL_IO_MGMT * pIo\r
- )\r
-{\r
- size_t LengthInBytes;\r
- ESL_PACKET * pPacket;\r
- EFI_UDP6_RECEIVE_DATA * pRxData;\r
- EFI_STATUS Status;\r
- \r
- DBG_ENTER ( );\r
-\r
- //\r
- // Get the operation status.\r
- //\r
- Status = pIo->Token.Udp6Rx.Status;\r
- \r
- //\r
- // Get the packet length\r
- //\r
- pRxData = pIo->Token.Udp6Rx.Packet.RxData;\r
- LengthInBytes = pRxData->DataLength;\r
-\r
- //\r
- // +--------------------+ +-----------------------+\r
- // | ESL_IO_MGMT | | Data Buffer |\r
- // | | | (Driver owned) |\r
- // | +---------------+ +-----------------------+\r
- // | | Token | ^\r
- // | | Rx Event | |\r
- // | | | +-----------------------+\r
- // | | RxData --> | EFI_UDP6_RECEIVE_DATA |\r
- // +----+---------------+ | (Driver owned) |\r
- // +-----------------------+\r
- // +--------------------+ ^\r
- // | ESL_PACKET | .\r
- // | | .\r
- // | +---------------+ .\r
- // | | pRxData --> NULL .......\r
- // +----+---------------+\r
- //\r
- //\r
- // Save the data in the packet\r
- //\r
- pPacket = pIo->pPacket;\r
- pPacket->Op.Udp6Rx.pRxData = pRxData;\r
-\r
- //\r
- // Complete this request\r
- //\r
- EslSocketRxComplete ( pIo, Status, LengthInBytes, FALSE );\r
- DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
- Determine if the socket is configured.\r
-\r
- This routine uses the flag ESL_SOCKET::bConfigured to determine\r
- if the network layer's configuration routine has been called.\r
- This routine calls the bind and configuration routines if they\r
- were not already called. After the port is configured, the\r
- \ref ReceiveEngine is started.\r
-\r
- This routine is called by EslSocketIsConfigured to verify\r
- that the socket is configured.\r
-\r
- @param [in] pSocket Address of an ::ESL_SOCKET structure\r
-\r
- @retval EFI_SUCCESS - The port is connected\r
- @retval EFI_NOT_STARTED - The port is not connected\r
-\r
- **/\r
- EFI_STATUS\r
- EslUdp6SocketIsConfigured (\r
- IN ESL_SOCKET * pSocket\r
- )\r
-{\r
- EFI_UDP6_CONFIG_DATA * pConfigData;\r
- ESL_PORT * pPort;\r
- ESL_PORT * pNextPort;\r
- ESL_UDP6_CONTEXT * pUdp6;\r
- EFI_UDP6_PROTOCOL * pUdp6Protocol;\r
- EFI_STATUS Status;\r
- struct sockaddr_in6 LocalAddress;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Assume success\r
- //\r
- Status = EFI_SUCCESS;\r
-\r
- //\r
- // Configure the port if necessary\r
- //\r
- if ( !pSocket->bConfigured ) {\r
- //\r
- // Fill in the port list if necessary\r
- //\r
- pSocket->errno = ENETDOWN;\r
- if ( NULL == pSocket->pPortList ) {\r
- ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));\r
- LocalAddress.sin6_len = sizeof ( LocalAddress );\r
- LocalAddress.sin6_family = AF_INET6;\r
- Status = EslSocketBind ( &pSocket->SocketProtocol,\r
- (struct sockaddr *)&LocalAddress,\r
- LocalAddress.sin6_len,\r
- &pSocket->errno );\r
- }\r
-\r
- //\r
- // Walk the port list\r
- //\r
- pPort = pSocket->pPortList;\r
- while ( NULL != pPort ) {\r
- //\r
- // Attempt to configure the port\r
- //\r
- pNextPort = pPort->pLinkSocket;\r
- pUdp6 = &pPort->Context.Udp6;\r
- pUdp6Protocol = pPort->pProtocol.UDPv6;\r
- pConfigData = &pUdp6->ConfigData;\r
- DEBUG (( DEBUG_TX,\r
- "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",\r
- pPort,\r
- pConfigData->StationAddress.Addr[0],\r
- pConfigData->StationAddress.Addr[1],\r
- pConfigData->StationAddress.Addr[2],\r
- pConfigData->StationAddress.Addr[3],\r
- pConfigData->StationAddress.Addr[4],\r
- pConfigData->StationAddress.Addr[5],\r
- pConfigData->StationAddress.Addr[6],\r
- pConfigData->StationAddress.Addr[7],\r
- pConfigData->StationAddress.Addr[8],\r
- pConfigData->StationAddress.Addr[9],\r
- pConfigData->StationAddress.Addr[10],\r
- pConfigData->StationAddress.Addr[11],\r
- pConfigData->StationAddress.Addr[12],\r
- pConfigData->StationAddress.Addr[13],\r
- pConfigData->StationAddress.Addr[14],\r
- pConfigData->StationAddress.Addr[15],\r
- pConfigData->StationPort ));\r
- DEBUG (( DEBUG_TX,\r
- "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- pConfigData->RemoteAddress.Addr[0],\r
- pConfigData->RemoteAddress.Addr[1],\r
- pConfigData->RemoteAddress.Addr[2],\r
- pConfigData->RemoteAddress.Addr[3],\r
- pConfigData->RemoteAddress.Addr[4],\r
- pConfigData->RemoteAddress.Addr[5],\r
- pConfigData->RemoteAddress.Addr[6],\r
- pConfigData->RemoteAddress.Addr[7],\r
- pConfigData->RemoteAddress.Addr[8],\r
- pConfigData->RemoteAddress.Addr[9],\r
- pConfigData->RemoteAddress.Addr[10],\r
- pConfigData->RemoteAddress.Addr[11],\r
- pConfigData->RemoteAddress.Addr[12],\r
- pConfigData->RemoteAddress.Addr[13],\r
- pConfigData->RemoteAddress.Addr[14],\r
- pConfigData->RemoteAddress.Addr[15],\r
- pConfigData->RemotePort ));\r
- Status = pUdp6Protocol->Configure ( pUdp6Protocol,\r
- pConfigData );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Update the configuration data\r
- //\r
- Status = pUdp6Protocol->GetModeData ( pUdp6Protocol,\r
- pConfigData,\r
- NULL,\r
- NULL,\r
- NULL );\r
- }\r
- if ( EFI_ERROR ( Status )) {\r
- if ( !pSocket->bConfigured ) {\r
- DEBUG (( DEBUG_LISTEN,\r
- "ERROR - Failed to configure the Udp6 port, Status: %r\r\n",\r
- Status ));\r
- switch ( Status ) {\r
- case EFI_ACCESS_DENIED:\r
- pSocket->errno = EACCES;\r
- break;\r
-\r
- default:\r
- case EFI_DEVICE_ERROR:\r
- pSocket->errno = EIO;\r
- break;\r
-\r
- case EFI_INVALID_PARAMETER:\r
- pSocket->errno = EADDRNOTAVAIL;\r
- break;\r
-\r
- case EFI_NO_MAPPING:\r
- pSocket->errno = EAFNOSUPPORT;\r
- break;\r
-\r
- case EFI_OUT_OF_RESOURCES:\r
- pSocket->errno = ENOBUFS;\r
- break;\r
-\r
- case EFI_UNSUPPORTED:\r
- pSocket->errno = EOPNOTSUPP;\r
- break;\r
- }\r
- }\r
- }\r
- else {\r
- DEBUG (( DEBUG_TX,\r
- "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",\r
- pPort,\r
- pConfigData->StationAddress.Addr[0],\r
- pConfigData->StationAddress.Addr[1],\r
- pConfigData->StationAddress.Addr[2],\r
- pConfigData->StationAddress.Addr[3],\r
- pConfigData->StationAddress.Addr[4],\r
- pConfigData->StationAddress.Addr[5],\r
- pConfigData->StationAddress.Addr[6],\r
- pConfigData->StationAddress.Addr[7],\r
- pConfigData->StationAddress.Addr[8],\r
- pConfigData->StationAddress.Addr[9],\r
- pConfigData->StationAddress.Addr[10],\r
- pConfigData->StationAddress.Addr[11],\r
- pConfigData->StationAddress.Addr[12],\r
- pConfigData->StationAddress.Addr[13],\r
- pConfigData->StationAddress.Addr[14],\r
- pConfigData->StationAddress.Addr[15],\r
- pConfigData->StationPort ));\r
- DEBUG (( DEBUG_TX,\r
- "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- pConfigData->RemoteAddress.Addr[0],\r
- pConfigData->RemoteAddress.Addr[1],\r
- pConfigData->RemoteAddress.Addr[2],\r
- pConfigData->RemoteAddress.Addr[3],\r
- pConfigData->RemoteAddress.Addr[4],\r
- pConfigData->RemoteAddress.Addr[5],\r
- pConfigData->RemoteAddress.Addr[6],\r
- pConfigData->RemoteAddress.Addr[7],\r
- pConfigData->RemoteAddress.Addr[8],\r
- pConfigData->RemoteAddress.Addr[9],\r
- pConfigData->RemoteAddress.Addr[10],\r
- pConfigData->RemoteAddress.Addr[11],\r
- pConfigData->RemoteAddress.Addr[12],\r
- pConfigData->RemoteAddress.Addr[13],\r
- pConfigData->RemoteAddress.Addr[14],\r
- pConfigData->RemoteAddress.Addr[15],\r
- pConfigData->RemotePort ));\r
- pPort->bConfigured = TRUE;\r
- pSocket->bConfigured = TRUE;\r
-\r
- //\r
- // Start the first read on the port\r
- //\r
- EslSocketRxStart ( pPort );\r
-\r
- //\r
- // The socket is connected\r
- //\r
- pSocket->State = SOCKET_STATE_CONNECTED;\r
- pSocket->errno = 0;\r
- }\r
-\r
- //\r
- // Set the next port\r
- //\r
- pPort = pNextPort;\r
- }\r
- }\r
-\r
- //\r
- // Determine the socket configuration status\r
- //\r
- Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
- \r
- //\r
- // Return the port connected state.\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Buffer data for transmission over a network connection.\r
-\r
- This routine buffers data for the transmit engine in the normal\r
- data queue. When the \ref TransmitEngine has resources, this\r
- routine will start the transmission of the next buffer on the\r
- network connection.\r
-\r
- This routine is called by ::EslSocketTransmit to buffer\r
- data for transmission. The data is copied into a local buffer\r
- freeing the application buffer for reuse upon return. When\r
- necessary, this routine starts the transmit engine that\r
- performs the data transmission on the network connection. The\r
- transmit engine transmits the data a packet at a time over the\r
- network connection.\r
-\r
- Transmission errors are returned during the next transmission or\r
- during the close operation. Only buffering errors are returned\r
- during the current transmission attempt.\r
-\r
- @param [in] pSocket Address of an ::ESL_SOCKET structure\r
-\r
- @param [in] Flags Message control flags\r
-\r
- @param [in] BufferLength Length of the the buffer\r
-\r
- @param [in] pBuffer Address of a buffer to receive the data.\r
-\r
- @param [in] pDataLength Number of received data bytes in the buffer.\r
-\r
- @param [in] pAddress Network address of the remote system address\r
-\r
- @param [in] AddressLength Length of the remote network address structure\r
-\r
- @retval EFI_SUCCESS - Socket data successfully buffered\r
-\r
-**/\r
-EFI_STATUS\r
-EslUdp6TxBuffer (\r
- IN ESL_SOCKET * pSocket,\r
- IN int Flags,\r
- IN size_t BufferLength,\r
- IN CONST UINT8 * pBuffer,\r
- OUT size_t * pDataLength,\r
- IN const struct sockaddr * pAddress,\r
- IN socklen_t AddressLength\r
- )\r
-{\r
- ESL_PACKET * pPacket;\r
- ESL_PACKET * pPreviousPacket;\r
- ESL_PORT * pPort;\r
- const struct sockaddr_in6 * pRemoteAddress;\r
- ESL_UDP6_CONTEXT * pUdp6;\r
- size_t * pTxBytes;\r
- ESL_UDP6_TX_DATA * pTxData;\r
- EFI_STATUS Status;\r
- EFI_TPL TplPrevious;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Assume failure\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- pSocket->errno = ENOTCONN;\r
- *pDataLength = 0;\r
-\r
- //\r
- // Verify that the socket is connected\r
- //\r
- if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
- //\r
- // Verify that there is enough room to buffer another\r
- // transmit operation\r
- //\r
- pTxBytes = &pSocket->TxBytes;\r
- if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
- //\r
- // Locate the port\r
- //\r
- pPort = pSocket->pPortList;\r
- while ( NULL != pPort ) {\r
- //\r
- // Determine the queue head\r
- //\r
- pUdp6 = &pPort->Context.Udp6;\r
-\r
- //\r
- // Attempt to allocate the packet\r
- //\r
- Status = EslSocketPacketAllocate ( &pPacket,\r
- sizeof ( pPacket->Op.Udp6Tx )\r
- - sizeof ( pPacket->Op.Udp6Tx.Buffer )\r
- + BufferLength,\r
- 0,\r
- DEBUG_TX );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Initialize the transmit operation\r
- //\r
- pTxData = &pPacket->Op.Udp6Tx;\r
- pTxData->TxData.UdpSessionData = NULL;\r
- pTxData->TxData.DataLength = (UINT32) BufferLength;\r
- pTxData->TxData.FragmentCount = 1;\r
- pTxData->TxData.FragmentTable[0].FragmentLength = (UINT32) BufferLength;\r
- pTxData->TxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Udp6Tx.Buffer[0];\r
-\r
- //\r
- // Set the remote system address if necessary\r
- //\r
- pTxData->TxData.UdpSessionData = NULL;\r
- if ( NULL != pAddress ) {\r
- pRemoteAddress = (const struct sockaddr_in6 *)pAddress;\r
- CopyMem ( &pTxData->Session.SourceAddress,\r
- &pUdp6->ConfigData.StationAddress,\r
- sizeof ( pTxData->Session.SourceAddress ));\r
- pTxData->Session.SourcePort = 0;\r
- CopyMem ( &pTxData->Session.DestinationAddress,\r
- &pRemoteAddress->sin6_addr,\r
- sizeof ( pTxData->Session.DestinationAddress ));\r
- pTxData->Session.DestinationPort = SwapBytes16 ( pRemoteAddress->sin6_port );\r
-\r
- //\r
- // Use the remote system address when sending this packet\r
- //\r
- pTxData->TxData.UdpSessionData = &pTxData->Session;\r
- }\r
-\r
- //\r
- // Copy the data into the buffer\r
- //\r
- CopyMem ( &pPacket->Op.Udp6Tx.Buffer[0],\r
- pBuffer,\r
- BufferLength );\r
-\r
- //\r
- // Synchronize with the socket layer\r
- //\r
- RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
-\r
- //\r
- // Display the request\r
- //\r
- DEBUG (( DEBUG_TX,\r
- "Send %d bytes from 0x%08x to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
- BufferLength,\r
- pBuffer,\r
- pTxData->Session.DestinationAddress.Addr[0],\r
- pTxData->Session.DestinationAddress.Addr[1],\r
- pTxData->Session.DestinationAddress.Addr[2],\r
- pTxData->Session.DestinationAddress.Addr[3],\r
- pTxData->Session.DestinationAddress.Addr[4],\r
- pTxData->Session.DestinationAddress.Addr[5],\r
- pTxData->Session.DestinationAddress.Addr[6],\r
- pTxData->Session.DestinationAddress.Addr[7],\r
- pTxData->Session.DestinationAddress.Addr[8],\r
- pTxData->Session.DestinationAddress.Addr[9],\r
- pTxData->Session.DestinationAddress.Addr[10],\r
- pTxData->Session.DestinationAddress.Addr[11],\r
- pTxData->Session.DestinationAddress.Addr[12],\r
- pTxData->Session.DestinationAddress.Addr[13],\r
- pTxData->Session.DestinationAddress.Addr[14],\r
- pTxData->Session.DestinationAddress.Addr[15],\r
- pTxData->Session.DestinationPort ));\r
-\r
- //\r
- // Queue the data for transmission\r
- //\r
- pPacket->pNext = NULL;\r
- pPreviousPacket = pSocket->pTxPacketListTail;\r
- if ( NULL == pPreviousPacket ) {\r
- pSocket->pTxPacketListHead = pPacket;\r
- }\r
- else {\r
- pPreviousPacket->pNext = pPacket;\r
- }\r
- pSocket->pTxPacketListTail = pPacket;\r
- DEBUG (( DEBUG_TX,\r
- "0x%08x: Packet on transmit list\r\n",\r
- pPacket ));\r
-\r
- //\r
- // Account for the buffered data\r
- //\r
- *pTxBytes += BufferLength;\r
- *pDataLength = BufferLength;\r
-\r
- //\r
- // Start the transmit engine if it is idle\r
- //\r
- if ( NULL != pPort->pTxFree ) {\r
- EslSocketTxStart ( pPort,\r
- &pSocket->pTxPacketListHead,\r
- &pSocket->pTxPacketListTail,\r
- &pPort->pTxActive,\r
- &pPort->pTxFree );\r
-\r
- //\r
- // Ignore any transmit error\r
- //\r
- if ( EFI_ERROR ( pSocket->TxError )) {\r
- DEBUG (( DEBUG_TX,\r
- "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",\r
- pPort,\r
- pPacket,\r
- pSocket->TxError ));\r
- }\r
- pSocket->TxError = EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Release the socket layer synchronization\r
- //\r
- RESTORE_TPL ( TplPrevious );\r
- }\r
- else {\r
- //\r
- // Packet allocation failed\r
- //\r
- pSocket->errno = ENOMEM;\r
- break;\r
- }\r
-\r
- //\r
- // Set the next port\r
- //\r
- pPort = pPort->pLinkSocket;\r
- }\r
- }\r
- else {\r
- //\r
- // Not enough buffer space available\r
- //\r
- pSocket->errno = EAGAIN;\r
- Status = EFI_NOT_READY;\r
- }\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Process the transmit completion\r
-\r
- This routine use ::EslSocketTxComplete to perform the transmit\r
- completion processing for data packets.\r
-\r
- This routine is called by the UDPv4 network layer when a data\r
- transmit request completes.\r
-\r
- @param [in] Event The normal transmit completion event\r
-\r
- @param [in] pIo Address of an ::ESL_IO_MGMT structure\r
-\r
-**/\r
-VOID\r
-EslUdp6TxComplete (\r
- IN EFI_EVENT Event,\r
- IN ESL_IO_MGMT * pIo\r
- )\r
-{\r
- UINT32 LengthInBytes;\r
- ESL_PORT * pPort;\r
- ESL_PACKET * pPacket;\r
- ESL_SOCKET * pSocket;\r
- EFI_STATUS Status;\r
- \r
- DBG_ENTER ( );\r
- \r
- //\r
- // Locate the active transmit packet\r
- //\r
- pPacket = pIo->pPacket;\r
- pPort = pIo->pPort;\r
- pSocket = pPort->pSocket;\r
-\r
- //\r
- // Get the transmit length and status\r
- //\r
- LengthInBytes = pPacket->Op.Udp6Tx.TxData.DataLength;\r
- pSocket->TxBytes -= LengthInBytes;\r
- Status = pIo->Token.Udp6Tx.Status;\r
-\r
- //\r
- // Ignore the transmit error\r
- //\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_TX,\r
- "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",\r
- pPort,\r
- pPacket,\r
- Status ));\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Complete the transmit operation\r
- //\r
- EslSocketTxComplete ( pIo,\r
- LengthInBytes,\r
- Status,\r
- "UDP ",\r
- &pSocket->pTxPacketListHead,\r
- &pSocket->pTxPacketListTail,\r
- &pPort->pTxActive,\r
- &pPort->pTxFree );\r
- DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
- Verify the adapter's IP address\r
-\r
- This support routine is called by EslSocketBindTest.\r
-\r
- @param [in] pPort Address of an ::ESL_PORT structure.\r
- @param [in] pConfigData Address of the configuration data\r
-\r
- @retval EFI_SUCCESS - The IP address is valid\r
- @retval EFI_NOT_STARTED - The IP address is invalid\r
-\r
- **/\r
-EFI_STATUS\r
-EslUdp6VerifyLocalIpAddress (\r
- IN ESL_PORT * pPort,\r
- IN EFI_UDP6_CONFIG_DATA * pConfigData\r
- )\r
-{\r
- UINTN AddressCount;\r
- EFI_IP6_ADDRESS_INFO * pAddressInfo;\r
- UINTN DataSize;\r
- EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;\r
- EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;\r
- ESL_SERVICE * pService;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Use break instead of goto\r
- //\r
- pIpConfigData = NULL;\r
- for ( ; ; ) {\r
- //\r
- // Determine if the IP address is specified\r
- //\r
- DEBUG (( DEBUG_BIND,\r
- "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
- pConfigData->StationAddress.Addr[0],\r
- pConfigData->StationAddress.Addr[1],\r
- pConfigData->StationAddress.Addr[2],\r
- pConfigData->StationAddress.Addr[3],\r
- pConfigData->StationAddress.Addr[4],\r
- pConfigData->StationAddress.Addr[5],\r
- pConfigData->StationAddress.Addr[6],\r
- pConfigData->StationAddress.Addr[7],\r
- pConfigData->StationAddress.Addr[8],\r
- pConfigData->StationAddress.Addr[9],\r
- pConfigData->StationAddress.Addr[10],\r
- pConfigData->StationAddress.Addr[11],\r
- pConfigData->StationAddress.Addr[12],\r
- pConfigData->StationAddress.Addr[13],\r
- pConfigData->StationAddress.Addr[14],\r
- pConfigData->StationAddress.Addr[15]));\r
- if (( 0 == pConfigData->StationAddress.Addr [ 0 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 1 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 2 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 3 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 4 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 5 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 6 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 7 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 8 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 9 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 10 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 11 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 12 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 13 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 14 ])\r
- && ( 0 == pConfigData->StationAddress.Addr [ 15 ]))\r
- {\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
-\r
- //\r
- // Open the configuration protocol\r
- //\r
- pService = pPort->pService;\r
- Status = gBS->OpenProtocol ( pService->Controller,\r
- &gEfiIp6ConfigProtocolGuid,\r
- (VOID **)&pIpConfigProtocol,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - IP Configuration Protocol not available, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
-\r
- //\r
- // Get the IP configuration data size\r
- //\r
- DataSize = 0;\r
- Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
- Ip6ConfigDataTypeInterfaceInfo,\r
- &DataSize,\r
- NULL );\r
- if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
-\r
- //\r
- // Allocate the configuration data buffer\r
- //\r
- pIpConfigData = AllocatePool ( DataSize );\r
- if ( NULL == pIpConfigData ) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));\r
- Status = EFI_OUT_OF_RESOURCES;\r
- break;\r
- }\r
-\r
- //\r
- // Get the IP configuration\r
- //\r
- Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
- Ip6ConfigDataTypeInterfaceInfo,\r
- &DataSize,\r
- pIpConfigData );\r
- if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR,\r
- "ERROR - Failed to return IP Configuration data, Status: %r\r\n",\r
- Status ));\r
- break;\r
- }\r
-\r
- //\r
- // Display the current configuration\r
- //\r
- DEBUG (( DEBUG_BIND,\r
- "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
- pIpConfigData->HwAddress.Addr [ 0 ],\r
- pIpConfigData->HwAddress.Addr [ 1 ],\r
- pIpConfigData->HwAddress.Addr [ 2 ],\r
- pIpConfigData->HwAddress.Addr [ 3 ],\r
- pIpConfigData->HwAddress.Addr [ 4 ],\r
- pIpConfigData->HwAddress.Addr [ 5 ],\r
- pIpConfigData->HwAddress.Addr [ 6 ],\r
- pIpConfigData->HwAddress.Addr [ 7 ],\r
- pIpConfigData->HwAddress.Addr [ 8 ],\r
- pIpConfigData->HwAddress.Addr [ 9 ],\r
- pIpConfigData->HwAddress.Addr [ 10 ],\r
- pIpConfigData->HwAddress.Addr [ 11 ],\r
- pIpConfigData->HwAddress.Addr [ 12 ],\r
- pIpConfigData->HwAddress.Addr [ 13 ],\r
- pIpConfigData->HwAddress.Addr [ 14 ],\r
- pIpConfigData->HwAddress.Addr [ 15 ]));\r
-\r
- //\r
- // Validate the hardware address\r
- //\r
- Status = EFI_SUCCESS;\r
- if (( 16 == pIpConfigData->HwAddressSize )\r
- && ( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])\r
- && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])\r
- && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])\r
- && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])\r
- && ( pConfigData->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])\r
- && ( pConfigData->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])\r
- && ( pConfigData->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])\r
- && ( pConfigData->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])\r
- && ( pConfigData->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])\r
- && ( pConfigData->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])\r
- && ( pConfigData->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])\r
- && ( pConfigData->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])\r
- && ( pConfigData->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])\r
- && ( pConfigData->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])\r
- && ( pConfigData->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])\r
- && ( pConfigData->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {\r
- break;\r
- }\r
-\r
- //\r
- // Walk the list of other IP addresses assigned to this adapter\r
- //\r
- for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {\r
- pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];\r
-\r
- //\r
- // Display the IP address\r
- //\r
- DEBUG (( DEBUG_BIND,\r
- "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
- pAddressInfo->Address.Addr [ 0 ],\r
- pAddressInfo->Address.Addr [ 1 ],\r
- pAddressInfo->Address.Addr [ 2 ],\r
- pAddressInfo->Address.Addr [ 3 ],\r
- pAddressInfo->Address.Addr [ 4 ],\r
- pAddressInfo->Address.Addr [ 5 ],\r
- pAddressInfo->Address.Addr [ 6 ],\r
- pAddressInfo->Address.Addr [ 7 ],\r
- pAddressInfo->Address.Addr [ 8 ],\r
- pAddressInfo->Address.Addr [ 9 ],\r
- pAddressInfo->Address.Addr [ 10 ],\r
- pAddressInfo->Address.Addr [ 11 ],\r
- pAddressInfo->Address.Addr [ 12 ],\r
- pAddressInfo->Address.Addr [ 13 ],\r
- pAddressInfo->Address.Addr [ 14 ],\r
- pAddressInfo->Address.Addr [ 15 ]));\r
-\r
- //\r
- // Validate the IP address\r
- //\r
- if (( pConfigData->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])\r
- && ( pConfigData->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])\r
- && ( pConfigData->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])\r
- && ( pConfigData->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])\r
- && ( pConfigData->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])\r
- && ( pConfigData->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])\r
- && ( pConfigData->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])\r
- && ( pConfigData->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])\r
- && ( pConfigData->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])\r
- && ( pConfigData->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])\r
- && ( pConfigData->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])\r
- && ( pConfigData->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])\r
- && ( pConfigData->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])\r
- && ( pConfigData->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])\r
- && ( pConfigData->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])\r
- && ( pConfigData->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {\r
- break;\r
- }\r
- }\r
- if ( pIpConfigData->AddressInfoCount > AddressCount ) {\r
- break;\r
- }\r
-\r
- //\r
- // The IP address did not match\r
- //\r
- Status = EFI_NOT_STARTED;\r
- break;\r
- }\r
-\r
- //\r
- // Free the buffer if necessary\r
- //\r
- if ( NULL != pIpConfigData ) {\r
- FreePool ( pIpConfigData );\r
- }\r
-\r
- //\r
- // Return the IP address status\r
- //\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Interface between the socket layer and the network specific\r
- code that supports SOCK_DGRAM sockets over UDPv4.\r
-**/\r
-CONST ESL_PROTOCOL_API cEslUdp6Api = {\r
- "UDPv6",\r
- IPPROTO_UDP,\r
- OFFSET_OF ( ESL_PORT, Context.Udp6.ConfigData ),\r
- OFFSET_OF ( ESL_LAYER, pUdp6List ),\r
- sizeof ( struct sockaddr_in6 ),\r
- sizeof ( struct sockaddr_in6 ),\r
- AF_INET6,\r
- sizeof (((ESL_PACKET *)0 )->Op.Udp6Rx ),\r
- sizeof (((ESL_PACKET *)0 )->Op.Udp6Rx ),\r
- OFFSET_OF ( ESL_IO_MGMT, Token.Udp6Rx.Packet.RxData ),\r
- FALSE,\r
- EADDRINUSE,\r
- NULL, // Accept\r
- NULL, // ConnectPoll\r
- NULL, // ConnectStart\r
- EslUdp6SocketIsConfigured,\r
- EslUdp6LocalAddressGet,\r
- EslUdp6LocalAddressSet,\r
- NULL, // Listen\r
- NULL, // OptionGet\r
- NULL, // OptionSet\r
- EslUdp6PacketFree,\r
- EslUdp6PortAllocate,\r
- NULL, // PortClose,\r
- NULL, // PortCloseOp\r
- TRUE,\r
- EslUdp6Receive,\r
- EslUdp6RemoteAddressGet,\r
- EslUdp6RemoteAddressSet,\r
- EslUdp6RxComplete,\r
- NULL, // RxStart\r
- EslUdp6TxBuffer,\r
- EslUdp6TxComplete,\r
- NULL, // TxOobComplete\r
- (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslUdp6VerifyLocalIpAddress\r
-};\r