]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Udp4.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / StdLib / EfiSocketLib / Udp4.c
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
deleted file mode 100644 (file)
index eafa014..0000000
+++ /dev/null
@@ -1,1226 +0,0 @@
-/** @file\r
-  Implement the UDP4 driver support for the socket layer.\r
-\r
-  Copyright (c) 2011 - 2015, 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 IPv4 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
-EslUdp4LocalAddressGet (\r
-  IN ESL_PORT * pPort,\r
-  OUT struct sockaddr * pSockAddr\r
-  )\r
-{\r
-  struct sockaddr_in * pLocalAddress;\r
-  ESL_UDP4_CONTEXT * pUdp4;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Return the local address\r
-  //\r
-  pUdp4 = &pPort->Context.Udp4;\r
-  pLocalAddress = (struct sockaddr_in *)pSockAddr;\r
-  pLocalAddress->sin_family = AF_INET;\r
-  pLocalAddress->sin_port = SwapBytes16 ( pUdp4->ConfigData.StationPort );\r
-  CopyMem ( &pLocalAddress->sin_addr,\r
-            &pUdp4->ConfigData.StationAddress.Addr[0],\r
-            sizeof ( pLocalAddress->sin_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 IPv4 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 IPv4 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
-EslUdp4LocalAddressSet (\r
-  IN ESL_PORT * pPort,\r
-  IN CONST struct sockaddr * pSockAddr,\r
-  IN BOOLEAN bBindTest\r
-  )\r
-{\r
-  EFI_UDP4_CONFIG_DATA * pConfig;\r
-  CONST struct sockaddr_in * pIpAddress;\r
-  CONST UINT8 * pIpv4Address;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Validate the address\r
-  //\r
-  pIpAddress = (struct sockaddr_in *)pSockAddr;\r
-  if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {\r
-    //\r
-    //  The local address must not be the broadcast address\r
-    //\r
-    Status = EFI_INVALID_PARAMETER;\r
-    pPort->pSocket->errno = EADDRNOTAVAIL;\r
-  }\r
-  else {\r
-    //\r
-    //  Set the local address\r
-    //\r
-    pIpAddress = (struct sockaddr_in *)pSockAddr;\r
-    pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;\r
-    pConfig = &pPort->Context.Udp4.ConfigData;\r
-    pConfig->StationAddress.Addr[0] = pIpv4Address[0];\r
-    pConfig->StationAddress.Addr[1] = pIpv4Address[1];\r
-    pConfig->StationAddress.Addr[2] = pIpv4Address[2];\r
-    pConfig->StationAddress.Addr[3] = pIpv4Address[3];\r
-\r
-    //\r
-    //  Determine if the default address is used\r
-    //\r
-    pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );\r
-    \r
-    //\r
-    //  Set the subnet mask\r
-    //\r
-    if ( pConfig->UseDefaultAddress ) {\r
-      pConfig->SubnetMask.Addr[0] = 0;\r
-      pConfig->SubnetMask.Addr[1] = 0;\r
-      pConfig->SubnetMask.Addr[2] = 0;\r
-      pConfig->SubnetMask.Addr[3] = 0;\r
-    }\r
-    else {\r
-      pConfig->SubnetMask.Addr[0] = 0xff;\r
-      pConfig->SubnetMask.Addr[1] = ( 128 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;\r
-      pConfig->SubnetMask.Addr[2] = ( 192 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;\r
-      pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;\r
-    }\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->sin_port );\r
-\r
-      //\r
-      //  Display the local address\r
-      //\r
-      DEBUG (( DEBUG_BIND,\r
-                "0x%08x: Port, Local UDP4 Address: %d.%d.%d.%d:%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->StationPort ));\r
-    }\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
-EslUdp4PacketFree (\r
-  IN ESL_PACKET * pPacket,\r
-  IN OUT size_t * pRxBytes\r
-  )\r
-{\r
-  EFI_UDP4_RECEIVE_DATA * pRxData;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Account for the receive bytes\r
-  //\r
-  pRxData = pPacket->Op.Udp4Rx.pRxData;\r
-  *pRxBytes -= pRxData->DataLength;\r
-\r
-  //\r
-  //  Disconnect the buffer from the packet\r
-  //\r
-  pPacket->Op.Udp4Rx.pRxData = NULL;\r
-\r
-  //\r
-  //  Return the buffer to the UDP4 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
-EslUdp4PortAllocate (\r
-  IN ESL_PORT * pPort,\r
-  IN UINTN DebugFlags\r
-  )\r
-{\r
-  EFI_UDP4_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.Udp4Tx.TxData );\r
-  pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Udp4Tx.Event );\r
-  pSocket->TxTokenOffset = OFFSET_OF ( EFI_UDP4_COMPLETION_TOKEN, Packet.TxData );\r
-\r
-  //\r
-  //  Save the cancel, receive and transmit addresses\r
-  //\r
-  pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.UDPv4->Configure;\r
-  pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Cancel;\r
-  pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.UDPv4->Poll;\r
-  pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Receive;\r
-  pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Transmit;\r
-\r
-  //\r
-  //  Set the configuration flags\r
-  //\r
-  pConfig = &pPort->Context.Udp4.ConfigData;\r
-  pConfig->TimeToLive = 255;\r
-  pConfig->AcceptAnyPort = FALSE;\r
-  pConfig->AcceptBroadcast = FALSE;\r
-  pConfig->AcceptPromiscuous = FALSE;\r
-  pConfig->AllowDuplicatePort = TRUE;\r
-  pConfig->DoNotFragment = FALSE;\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
-EslUdp4Receive (\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_in * pRemoteAddress;\r
-  EFI_UDP4_RECEIVE_DATA * pRxData;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  pRxData = pPacket->Op.Udp4Rx.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: %d.%d.%d.%d:%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.SourcePort ));\r
-    pRemoteAddress = (struct sockaddr_in *)pAddress;\r
-    CopyMem ( &pRemoteAddress->sin_addr,\r
-              &pRxData->UdpSession.SourceAddress.Addr[0],\r
-              sizeof ( pRemoteAddress->sin_addr ));\r
-    pRemoteAddress->sin_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
-EslUdp4RemoteAddressGet (\r
-  IN ESL_PORT * pPort,\r
-  OUT struct sockaddr * pAddress\r
-  )\r
-{\r
-  struct sockaddr_in * pRemoteAddress;\r
-  ESL_UDP4_CONTEXT * pUdp4;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Return the remote address\r
-  //\r
-  pUdp4 = &pPort->Context.Udp4;\r
-  pRemoteAddress = (struct sockaddr_in *)pAddress;\r
-  pRemoteAddress->sin_family = AF_INET;\r
-  pRemoteAddress->sin_port = SwapBytes16 ( pUdp4->ConfigData.RemotePort );\r
-  CopyMem ( &pRemoteAddress->sin_addr,\r
-            &pUdp4->ConfigData.RemoteAddress.Addr[0],\r
-            sizeof ( pRemoteAddress->sin_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
-EslUdp4RemoteAddressSet (\r
-  IN ESL_PORT * pPort,\r
-  IN CONST struct sockaddr * pSockAddr,\r
-  IN socklen_t SockAddrLength\r
-  )\r
-{\r
-  CONST struct sockaddr_in * pRemoteAddress;\r
-  ESL_UDP4_CONTEXT * pUdp4;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Set the remote address\r
-  //\r
-  pUdp4 = &pPort->Context.Udp4;\r
-  pRemoteAddress = (struct sockaddr_in *)pSockAddr;\r
-  pUdp4->ConfigData.RemoteAddress.Addr[0] = (UINT8)( pRemoteAddress->sin_addr.s_addr );\r
-  pUdp4->ConfigData.RemoteAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
-  pUdp4->ConfigData.RemoteAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
-  pUdp4->ConfigData.RemoteAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\r
-  pUdp4->ConfigData.RemotePort = SwapBytes16 ( pRemoteAddress->sin_port );\r
-  pPort->pSocket->bAddressSet = TRUE;\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 UDP4 driver's buffer will\r
-  be returned by either ::EslUdp4Receive 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
-EslUdp4RxComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_IO_MGMT * pIo\r
-  )\r
-{\r
-  size_t LengthInBytes;\r
-  ESL_PACKET * pPacket;\r
-  EFI_UDP4_RECEIVE_DATA * pRxData;\r
-  EFI_STATUS Status;\r
-  \r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Get the operation status.\r
-  //\r
-  Status = pIo->Token.Udp4Rx.Status;\r
-  \r
-  //\r
-  //  Get the packet length\r
-  //\r
-  pRxData = pIo->Token.Udp4Rx.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_UDP4_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.Udp4Rx.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
- EslUdp4SocketIsConfigured (\r
-  IN ESL_SOCKET * pSocket\r
-  )\r
-{\r
-  EFI_UDP4_CONFIG_DATA * pConfigData;\r
-  ESL_PORT * pPort;\r
-  ESL_PORT * pNextPort;\r
-  ESL_UDP4_CONTEXT * pUdp4;\r
-  EFI_UDP4_PROTOCOL * pUdp4Protocol;\r
-  EFI_STATUS Status;\r
-  struct sockaddr_in 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
-      LocalAddress.sin_len = sizeof ( LocalAddress );\r
-      LocalAddress.sin_family = AF_INET;\r
-      LocalAddress.sin_addr.s_addr = 0;\r
-      LocalAddress.sin_port = 0;\r
-      Status = EslSocketBind ( &pSocket->SocketProtocol,\r
-                               (struct sockaddr *)&LocalAddress,\r
-                               LocalAddress.sin_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
-      pUdp4 = &pPort->Context.Udp4;\r
-      pUdp4Protocol = pPort->pProtocol.UDPv4;\r
-      pConfigData = &pUdp4->ConfigData;\r
-      DEBUG (( DEBUG_TX,\r
-                "0x%08x: pPort Configuring for %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d\r\n",\r
-                pPort,\r
-                pConfigData->StationAddress.Addr[0],\r
-                pConfigData->StationAddress.Addr[1],\r
-                pConfigData->StationAddress.Addr[2],\r
-                pConfigData->StationAddress.Addr[3],\r
-                pConfigData->StationPort,\r
-                pConfigData->RemoteAddress.Addr[0],\r
-                pConfigData->RemoteAddress.Addr[1],\r
-                pConfigData->RemoteAddress.Addr[2],\r
-                pConfigData->RemoteAddress.Addr[3],\r
-                pConfigData->RemotePort ));\r
-      Status = pUdp4Protocol->Configure ( pUdp4Protocol,\r
-                                          pConfigData );\r
-      if ( !EFI_ERROR ( Status )) {\r
-        //\r
-        //  Update the configuration data\r
-        //\r
-        Status = pUdp4Protocol->GetModeData ( pUdp4Protocol,\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 Udp4 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 %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d\r\n",\r
-                  pPort,\r
-                  pConfigData->StationAddress.Addr[0],\r
-                  pConfigData->StationAddress.Addr[1],\r
-                  pConfigData->StationAddress.Addr[2],\r
-                  pConfigData->StationAddress.Addr[3],\r
-                  pConfigData->StationPort,\r
-                  pConfigData->RemoteAddress.Addr[0],\r
-                  pConfigData->RemoteAddress.Addr[1],\r
-                  pConfigData->RemoteAddress.Addr[2],\r
-                  pConfigData->RemoteAddress.Addr[3],\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
-EslUdp4TxBuffer (\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_in * pRemoteAddress;\r
-  ESL_UDP4_CONTEXT * pUdp4;\r
-  size_t * pTxBytes;\r
-  ESL_UDP4_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
-        pUdp4 = &pPort->Context.Udp4;\r
-\r
-        //\r
-        //  Attempt to allocate the packet\r
-        //\r
-        Status = EslSocketPacketAllocate ( &pPacket,\r
-                                           sizeof ( pPacket->Op.Udp4Tx )\r
-                                           - sizeof ( pPacket->Op.Udp4Tx.Buffer )\r
-                                           + BufferLength,\r
-                                           0,\r
-                                           DEBUG_TX );\r
-        if ( !EFI_ERROR ( Status )) {\r
-          //\r
-          //  Initialize the transmit operation\r
-          //\r
-          pTxData = &pPacket->Op.Udp4Tx;\r
-          pTxData->TxData.GatewayAddress = NULL;\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.Udp4Tx.Buffer[0];\r
-          pTxData->RetransmitCount = 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_in *)pAddress;\r
-            pTxData->Session.SourceAddress.Addr[0] = pUdp4->ConfigData.StationAddress.Addr[0];\r
-            pTxData->Session.SourceAddress.Addr[1] = pUdp4->ConfigData.StationAddress.Addr[1];\r
-            pTxData->Session.SourceAddress.Addr[2] = pUdp4->ConfigData.StationAddress.Addr[2];\r
-            pTxData->Session.SourceAddress.Addr[3] = pUdp4->ConfigData.StationAddress.Addr[3];\r
-            pTxData->Session.SourcePort = 0;\r
-            pTxData->Session.DestinationAddress.Addr[0] = (UINT8)pRemoteAddress->sin_addr.s_addr;\r
-            pTxData->Session.DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
-            pTxData->Session.DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
-            pTxData->Session.DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\r
-            pTxData->Session.DestinationPort = SwapBytes16 ( pRemoteAddress->sin_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.Udp4Tx.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 %d.%d.%d.%d:%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.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
-            pPacket = pSocket->pTxPacketListHead;\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
-EslUdp4TxComplete (\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.Udp4Tx.TxData.DataLength;\r
-  pSocket->TxBytes -= LengthInBytes;\r
-  Status = pIo->Token.Udp4Tx.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
-EslUdp4VerifyLocalIpAddress (\r
-  IN ESL_PORT * pPort,\r
-  IN EFI_UDP4_CONFIG_DATA * pConfigData\r
-  )\r
-{\r
-  UINTN DataSize;\r
-  EFI_IP4_CONFIG2_INTERFACE_INFO * pIfInfo;\r
-  EFI_IP4_CONFIG2_PROTOCOL * pIpConfig2Protocol;\r
-  ESL_SERVICE * pService;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Use break instead of goto\r
-  //\r
-  pIfInfo = NULL;\r
-  for ( ; ; ) {\r
-    //\r
-    //  Determine if the IP address is specified\r
-    //\r
-    DEBUG (( DEBUG_BIND,\r
-              "UseDefaultAddress: %s\r\n",\r
-              pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));\r
-    DEBUG (( DEBUG_BIND,\r
-              "Requested IP address: %d.%d.%d.%d\r\n",\r
-              pConfigData->StationAddress.Addr [ 0 ],\r
-              pConfigData->StationAddress.Addr [ 1 ],\r
-              pConfigData->StationAddress.Addr [ 2 ],\r
-              pConfigData->StationAddress.Addr [ 3 ]));\r
-    if ( pConfigData->UseDefaultAddress\r
-      || (( 0 == pConfigData->StationAddress.Addr [ 0 ])\r
-      && ( 0 == pConfigData->StationAddress.Addr [ 1 ])\r
-      && ( 0 == pConfigData->StationAddress.Addr [ 2 ])\r
-      && ( 0 == pConfigData->StationAddress.Addr [ 3 ])))\r
-    {\r
-      Status = EFI_SUCCESS;\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Open the configuration protocol\r
-    //\r
-    pService = pPort->pService;\r
-    Status = gBS->OpenProtocol ( \r
-                    pService->Controller,\r
-                    &gEfiIp4Config2ProtocolGuid,\r
-                    (VOID **)&pIpConfig2Protocol,\r
-                    NULL,\r
-                    NULL,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL \r
-                    );\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 interface information size\r
-    //\r
-    DataSize = 0;\r
-    Status = pIpConfig2Protocol->GetData ( \r
-                                   pIpConfig2Protocol,\r
-                                   Ip4Config2DataTypeInterfaceInfo,\r
-                                   &DataSize,\r
-                                   NULL\r
-                                   );\r
-    if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - Failed to get the interface information size, Status: %r\r\n",\r
-                Status ));\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Allocate the interface information buffer\r
-    //\r
-    pIfInfo = AllocatePool ( DataSize );\r
-    if ( NULL == pIfInfo ) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - Not enough memory to allocate the interface information buffer!\r\n" ));\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Get the interface info.\r
-    //\r
-    Status = pIpConfig2Protocol->GetData ( \r
-                                  pIpConfig2Protocol,\r
-                                  Ip4Config2DataTypeInterfaceInfo,\r
-                                  &DataSize,\r
-                                  pIfInfo\r
-                                  );\r
-    if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - Failed to return the interface info, 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: %d.%d.%d.%d\r\n",\r
-              pIfInfo->StationAddress.Addr [ 0 ],\r
-              pIfInfo->StationAddress.Addr [ 1 ],\r
-              pIfInfo->StationAddress.Addr [ 2 ],\r
-              pIfInfo->StationAddress.Addr [ 3 ]));\r
-\r
-    //\r
-    //  Assume the port is not configured\r
-    //\r
-    Status = EFI_SUCCESS;\r
-    if (( pConfigData->StationAddress.Addr [ 0 ] == pIfInfo->StationAddress.Addr [ 0 ])\r
-      && ( pConfigData->StationAddress.Addr [ 1 ] == pIfInfo->StationAddress.Addr [ 1 ])\r
-      && ( pConfigData->StationAddress.Addr [ 2 ] == pIfInfo->StationAddress.Addr [ 2 ])\r
-      && ( pConfigData->StationAddress.Addr [ 3 ] == pIfInfo->StationAddress.Addr [ 3 ])) {\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 != pIfInfo ) {\r
-    FreePool ( pIfInfo );\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 cEslUdp4Api = {\r
-  "UDPv4",\r
-  IPPROTO_UDP,\r
-  OFFSET_OF ( ESL_PORT, Context.Udp4.ConfigData ),\r
-  OFFSET_OF ( ESL_LAYER, pUdp4List ),\r
-  OFFSET_OF ( struct sockaddr_in, sin_zero ),\r
-  sizeof ( struct sockaddr_in ),\r
-  AF_INET,\r
-  sizeof (((ESL_PACKET *)0 )->Op.Udp4Rx ),\r
-  sizeof (((ESL_PACKET *)0 )->Op.Udp4Rx ),\r
-  OFFSET_OF ( ESL_IO_MGMT, Token.Udp4Rx.Packet.RxData ),\r
-  FALSE,\r
-  EADDRINUSE,\r
-  NULL,   //  Accept\r
-  NULL,   //  ConnectPoll\r
-  NULL,   //  ConnectStart\r
-  EslUdp4SocketIsConfigured,\r
-  EslUdp4LocalAddressGet,\r
-  EslUdp4LocalAddressSet,\r
-  NULL,   //  Listen\r
-  NULL,   //  OptionGet\r
-  NULL,   //  OptionSet\r
-  EslUdp4PacketFree,\r
-  EslUdp4PortAllocate,\r
-  NULL,   //  PortClose,\r
-  NULL,   //  PortCloseOp\r
-  TRUE,\r
-  EslUdp4Receive,\r
-  EslUdp4RemoteAddressGet,\r
-  EslUdp4RemoteAddressSet,\r
-  EslUdp4RxComplete,\r
-  NULL,   //  RxStart\r
-  EslUdp4TxBuffer,\r
-  EslUdp4TxComplete,\r
-  NULL,   //  TxOobComplete\r
-  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslUdp4VerifyLocalIpAddress\r
-};\r