summaryrefslogtreecommitdiff
path: root/StdLib/EfiSocketLib/Udp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'StdLib/EfiSocketLib/Udp4.c')
-rw-r--r--StdLib/EfiSocketLib/Udp4.c1232
1 files changed, 0 insertions, 1232 deletions
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
deleted file mode 100644
index ef2f9e321b..0000000000
--- a/StdLib/EfiSocketLib/Udp4.c
+++ /dev/null
@@ -1,1232 +0,0 @@
-/** @file
- Implement the UDP4 driver support for the socket layer.
-
- Copyright (c) 2011 - 2015, Intel Corporation
- All rights reserved. This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Socket.h"
-
-
-/**
- Get the local socket address
-
- This routine returns the IPv4 address and UDP port number associated
- with the local socket.
-
- This routine is called by ::EslSocketGetLocalAddress to determine the
- network address for the SOCK_DGRAM socket.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
-
- @param [out] pSockAddr Network address to receive the local system address
-
-**/
-VOID
-EslUdp4LocalAddressGet (
- IN ESL_PORT * pPort,
- OUT struct sockaddr * pSockAddr
- )
-{
- struct sockaddr_in * pLocalAddress;
- ESL_UDP4_CONTEXT * pUdp4;
-
- DBG_ENTER ( );
-
- //
- // Return the local address
- //
- pUdp4 = &pPort->Context.Udp4;
- pLocalAddress = (struct sockaddr_in *)pSockAddr;
- pLocalAddress->sin_family = AF_INET;
- pLocalAddress->sin_port = SwapBytes16 ( pUdp4->ConfigData.StationPort );
- CopyMem ( &pLocalAddress->sin_addr,
- &pUdp4->ConfigData.StationAddress.Addr[0],
- sizeof ( pLocalAddress->sin_addr ));
-
- DBG_EXIT ( );
-}
-
-
-/**
- Set the local port address.
-
- This routine sets the local port address.
-
- This support routine is called by ::EslSocketPortAllocate.
-
- @param [in] pPort Address of an ESL_PORT structure
- @param [in] pSockAddr Address of a sockaddr structure that contains the
- connection point on the local machine. An IPv4 address
- of INADDR_ANY specifies that the connection is made to
- all of the network stacks on the platform. Specifying a
- specific IPv4 address restricts the connection to the
- network stack supporting that address. Specifying zero
- for the port causes the network layer to assign a port
- number from the dynamic range. Specifying a specific
- port number causes the network layer to use that port.
-
- @param [in] bBindTest TRUE = run bind testing
-
- @retval EFI_SUCCESS The operation was successful
-
- **/
-EFI_STATUS
-EslUdp4LocalAddressSet (
- IN ESL_PORT * pPort,
- IN CONST struct sockaddr * pSockAddr,
- IN BOOLEAN bBindTest
- )
-{
- EFI_UDP4_CONFIG_DATA * pConfig;
- CONST struct sockaddr_in * pIpAddress;
- CONST UINT8 * pIpv4Address;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Validate the address
- //
- pIpAddress = (struct sockaddr_in *)pSockAddr;
- if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {
- //
- // The local address must not be the broadcast address
- //
- Status = EFI_INVALID_PARAMETER;
- pPort->pSocket->errno = EADDRNOTAVAIL;
- }
- else {
- //
- // Set the local address
- //
- pIpAddress = (struct sockaddr_in *)pSockAddr;
- pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;
- pConfig = &pPort->Context.Udp4.ConfigData;
- pConfig->StationAddress.Addr[0] = pIpv4Address[0];
- pConfig->StationAddress.Addr[1] = pIpv4Address[1];
- pConfig->StationAddress.Addr[2] = pIpv4Address[2];
- pConfig->StationAddress.Addr[3] = pIpv4Address[3];
-
- //
- // Determine if the default address is used
- //
- pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );
-
- //
- // Set the subnet mask
- //
- if ( pConfig->UseDefaultAddress ) {
- pConfig->SubnetMask.Addr[0] = 0;
- pConfig->SubnetMask.Addr[1] = 0;
- pConfig->SubnetMask.Addr[2] = 0;
- pConfig->SubnetMask.Addr[3] = 0;
- }
- else {
- pConfig->SubnetMask.Addr[0] = 0xff;
- pConfig->SubnetMask.Addr[1] = ( 128 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
- pConfig->SubnetMask.Addr[2] = ( 192 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
- pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
- }
-
- //
- // Validate the IP address
- //
- pConfig->StationPort = 0;
- Status = bBindTest ? EslSocketBindTest ( pPort, EADDRNOTAVAIL )
- : EFI_SUCCESS;
- if ( !EFI_ERROR ( Status )) {
- //
- // Set the port number
- //
- pConfig->StationPort = SwapBytes16 ( pIpAddress->sin_port );
-
- //
- // Display the local address
- //
- DEBUG (( DEBUG_BIND,
- "0x%08x: Port, Local UDP4 Address: %d.%d.%d.%d:%d\r\n",
- pPort,
- pConfig->StationAddress.Addr[0],
- pConfig->StationAddress.Addr[1],
- pConfig->StationAddress.Addr[2],
- pConfig->StationAddress.Addr[3],
- pConfig->StationPort ));
- }
- }
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
- Free a receive packet
-
- This routine performs the network specific operations necessary
- to free a receive packet.
-
- This routine is called by ::EslSocketPortCloseTxDone to free a
- receive packet.
-
- @param [in] pPacket Address of an ::ESL_PACKET structure.
- @param [in, out] pRxBytes Address of the count of RX bytes
-
-**/
-VOID
-EslUdp4PacketFree (
- IN ESL_PACKET * pPacket,
- IN OUT size_t * pRxBytes
- )
-{
- EFI_UDP4_RECEIVE_DATA * pRxData;
-
- DBG_ENTER ( );
-
- //
- // Account for the receive bytes
- //
- pRxData = pPacket->Op.Udp4Rx.pRxData;
- *pRxBytes -= pRxData->DataLength;
-
- //
- // Disconnect the buffer from the packet
- //
- pPacket->Op.Udp4Rx.pRxData = NULL;
-
- //
- // Return the buffer to the UDP4 driver
- //
- gBS->SignalEvent ( pRxData->RecycleSignal );
- DBG_EXIT ( );
-}
-
-
-/**
- Initialize the network specific portions of an ::ESL_PORT structure.
-
- This routine initializes the network specific portions of an
- ::ESL_PORT structure for use by the socket.
-
- This support routine is called by ::EslSocketPortAllocate
- to connect the socket with the underlying network adapter
- running the UDPv4 protocol.
-
- @param [in] pPort Address of an ESL_PORT structure
- @param [in] DebugFlags Flags for debug messages
-
- @retval EFI_SUCCESS - Socket successfully created
-
- **/
-EFI_STATUS
-EslUdp4PortAllocate (
- IN ESL_PORT * pPort,
- IN UINTN DebugFlags
- )
-{
- EFI_UDP4_CONFIG_DATA * pConfig;
- ESL_SOCKET * pSocket;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Initialize the port
- //
- pSocket = pPort->pSocket;
- pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Udp4Tx.TxData );
- pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Udp4Tx.Event );
- pSocket->TxTokenOffset = OFFSET_OF ( EFI_UDP4_COMPLETION_TOKEN, Packet.TxData );
-
- //
- // Save the cancel, receive and transmit addresses
- //
- pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.UDPv4->Configure;
- pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Cancel;
- pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.UDPv4->Poll;
- pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Receive;
- pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.UDPv4->Transmit;
-
- //
- // Set the configuration flags
- //
- pConfig = &pPort->Context.Udp4.ConfigData;
- pConfig->TimeToLive = 255;
- pConfig->AcceptAnyPort = FALSE;
- pConfig->AcceptBroadcast = FALSE;
- pConfig->AcceptPromiscuous = FALSE;
- pConfig->AllowDuplicatePort = TRUE;
- pConfig->DoNotFragment = FALSE;
- Status = EFI_SUCCESS;
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
- Receive data from a network connection.
-
- This routine attempts to return buffered data to the caller. The
- data is removed from the urgent queue if the message flag MSG_OOB
- is specified, otherwise data is removed from the normal queue.
- See the \ref ReceiveEngine section.
-
- This routine is called by ::EslSocketReceive to handle the network
- specific receive operation to support SOCK_DGRAM sockets.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
-
- @param [in] pPacket Address of an ::ESL_PACKET structure.
-
- @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed
-
- @param [in] BufferLength Length of the the buffer
-
- @param [in] pBuffer Address of a buffer to receive the data.
-
- @param [in] pDataLength Number of received data bytes in the buffer.
-
- @param [out] pAddress Network address to receive the remote system address
-
- @param [out] pSkipBytes Address to receive the number of bytes skipped
-
- @return Returns the address of the next free byte in the buffer.
-
- **/
-UINT8 *
-EslUdp4Receive (
- IN ESL_PORT * pPort,
- IN ESL_PACKET * pPacket,
- IN BOOLEAN * pbConsumePacket,
- IN size_t BufferLength,
- IN UINT8 * pBuffer,
- OUT size_t * pDataLength,
- OUT struct sockaddr * pAddress,
- OUT size_t * pSkipBytes
- )
-{
- size_t DataBytes;
- struct sockaddr_in * pRemoteAddress;
- EFI_UDP4_RECEIVE_DATA * pRxData;
-
- DBG_ENTER ( );
-
- pRxData = pPacket->Op.Udp4Rx.pRxData;
- //
- // Return the remote system address if requested
- //
- if ( NULL != pAddress ) {
- //
- // Build the remote address
- //
- DEBUG (( DEBUG_RX,
- "Getting packet remote address: %d.%d.%d.%d:%d\r\n",
- pRxData->UdpSession.SourceAddress.Addr[0],
- pRxData->UdpSession.SourceAddress.Addr[1],
- pRxData->UdpSession.SourceAddress.Addr[2],
- pRxData->UdpSession.SourceAddress.Addr[3],
- pRxData->UdpSession.SourcePort ));
- pRemoteAddress = (struct sockaddr_in *)pAddress;
- CopyMem ( &pRemoteAddress->sin_addr,
- &pRxData->UdpSession.SourceAddress.Addr[0],
- sizeof ( pRemoteAddress->sin_addr ));
- pRemoteAddress->sin_port = SwapBytes16 ( pRxData->UdpSession.SourcePort );
- }
-
- //
- // Copy the received data
- //
- pBuffer = EslSocketCopyFragmentedBuffer ( pRxData->FragmentCount,
- (EFI_IP4_FRAGMENT_DATA *)&pRxData->FragmentTable[0],
- BufferLength,
- pBuffer,
- &DataBytes );
-
- //
- // Determine if the data is being read
- //
- if ( *pbConsumePacket ) {
- //
- // Display for the bytes consumed
- //
- DEBUG (( DEBUG_RX,
- "0x%08x: Port account for 0x%08x bytes\r\n",
- pPort,
- DataBytes ));
-
- //
- // Account for any discarded data
- //
- *pSkipBytes = pRxData->DataLength - DataBytes;
- }
-
- //
- // Return the data length and the buffer address
- //
- *pDataLength = DataBytes;
- DBG_EXIT_HEX ( pBuffer );
- return pBuffer;
-}
-
-
-/**
- Get the remote socket address
-
- This routine returns the address of the remote connection point
- associated with the SOCK_DGRAM socket.
-
- This routine is called by ::EslSocketGetPeerAddress to detemine
- the UDPv4 address and port number associated with the network adapter.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
-
- @param [out] pAddress Network address to receive the remote system address
-
-**/
-VOID
-EslUdp4RemoteAddressGet (
- IN ESL_PORT * pPort,
- OUT struct sockaddr * pAddress
- )
-{
- struct sockaddr_in * pRemoteAddress;
- ESL_UDP4_CONTEXT * pUdp4;
-
- DBG_ENTER ( );
-
- //
- // Return the remote address
- //
- pUdp4 = &pPort->Context.Udp4;
- pRemoteAddress = (struct sockaddr_in *)pAddress;
- pRemoteAddress->sin_family = AF_INET;
- pRemoteAddress->sin_port = SwapBytes16 ( pUdp4->ConfigData.RemotePort );
- CopyMem ( &pRemoteAddress->sin_addr,
- &pUdp4->ConfigData.RemoteAddress.Addr[0],
- sizeof ( pRemoteAddress->sin_addr ));
-
- DBG_EXIT ( );
-}
-
-
-/**
- Set the remote address
-
- This routine sets the remote address in the port.
-
- This routine is called by ::EslSocketConnect to specify the
- remote network address.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
-
- @param [in] pSockAddr Network address of the remote system.
-
- @param [in] SockAddrLength Length in bytes of the network address.
-
- @retval EFI_SUCCESS The operation was successful
-
- **/
-EFI_STATUS
-EslUdp4RemoteAddressSet (
- IN ESL_PORT * pPort,
- IN CONST struct sockaddr * pSockAddr,
- IN socklen_t SockAddrLength
- )
-{
- CONST struct sockaddr_in * pRemoteAddress;
- ESL_UDP4_CONTEXT * pUdp4;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Set the remote address
- //
- pUdp4 = &pPort->Context.Udp4;
- pRemoteAddress = (struct sockaddr_in *)pSockAddr;
- pUdp4->ConfigData.RemoteAddress.Addr[0] = (UINT8)( pRemoteAddress->sin_addr.s_addr );
- pUdp4->ConfigData.RemoteAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );
- pUdp4->ConfigData.RemoteAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );
- pUdp4->ConfigData.RemoteAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );
- pUdp4->ConfigData.RemotePort = SwapBytes16 ( pRemoteAddress->sin_port );
- pPort->pSocket->bAddressSet = TRUE;
- Status = EFI_SUCCESS;
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
- Process the receive completion
-
- This routine keeps the UDPv4 driver's buffer and queues it in
- in FIFO order to the data queue. The UDP4 driver's buffer will
- be returned by either ::EslUdp4Receive or ::EslSocketPortCloseTxDone.
- See the \ref ReceiveEngine section.
-
- This routine is called by the UDPv4 driver when data is
- received.
-
- @param [in] Event The receive completion event
-
- @param [in] pIo Address of an ::ESL_IO_MGMT structure
-
-**/
-VOID
-EslUdp4RxComplete (
- IN EFI_EVENT Event,
- IN ESL_IO_MGMT * pIo
- )
-{
- size_t LengthInBytes;
- ESL_PACKET * pPacket;
- EFI_UDP4_RECEIVE_DATA * pRxData;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Get the operation status.
- //
- Status = pIo->Token.Udp4Rx.Status;
-
- //
- // Get the packet length
- //
- pRxData = pIo->Token.Udp4Rx.Packet.RxData;
- LengthInBytes = pRxData->DataLength;
-
- //
- // +--------------------+ +-----------------------+
- // | ESL_IO_MGMT | | Data Buffer |
- // | | | (Driver owned) |
- // | +---------------+ +-----------------------+
- // | | Token | ^
- // | | Rx Event | |
- // | | | +-----------------------+
- // | | RxData --> | EFI_UDP4_RECEIVE_DATA |
- // +----+---------------+ | (Driver owned) |
- // +-----------------------+
- // +--------------------+ ^
- // | ESL_PACKET | .
- // | | .
- // | +---------------+ .
- // | | pRxData --> NULL .......
- // +----+---------------+
- //
- //
- // Save the data in the packet
- //
- pPacket = pIo->pPacket;
- pPacket->Op.Udp4Rx.pRxData = pRxData;
-
- //
- // Complete this request
- //
- EslSocketRxComplete ( pIo, Status, LengthInBytes, FALSE );
- DBG_EXIT ( );
-}
-
-
-/**
- Determine if the socket is configured.
-
- This routine uses the flag ESL_SOCKET::bConfigured to determine
- if the network layer's configuration routine has been called.
- This routine calls the bind and configuration routines if they
- were not already called. After the port is configured, the
- \ref ReceiveEngine is started.
-
- This routine is called by EslSocketIsConfigured to verify
- that the socket is configured.
-
- @param [in] pSocket Address of an ::ESL_SOCKET structure
-
- @retval EFI_SUCCESS - The port is connected
- @retval EFI_NOT_STARTED - The port is not connected
-
- **/
- EFI_STATUS
- EslUdp4SocketIsConfigured (
- IN ESL_SOCKET * pSocket
- )
-{
- EFI_UDP4_CONFIG_DATA * pConfigData;
- ESL_PORT * pPort;
- ESL_PORT * pNextPort;
- ESL_UDP4_CONTEXT * pUdp4;
- EFI_UDP4_PROTOCOL * pUdp4Protocol;
- EFI_STATUS Status;
- struct sockaddr_in LocalAddress;
-
- DBG_ENTER ( );
-
- //
- // Assume success
- //
- Status = EFI_SUCCESS;
-
- //
- // Configure the port if necessary
- //
- if ( !pSocket->bConfigured ) {
- //
- // Fill in the port list if necessary
- //
- pSocket->errno = ENETDOWN;
- if ( NULL == pSocket->pPortList ) {
- LocalAddress.sin_len = sizeof ( LocalAddress );
- LocalAddress.sin_family = AF_INET;
- LocalAddress.sin_addr.s_addr = 0;
- LocalAddress.sin_port = 0;
- Status = EslSocketBind ( &pSocket->SocketProtocol,
- (struct sockaddr *)&LocalAddress,
- LocalAddress.sin_len,
- &pSocket->errno );
- }
-
- //
- // Walk the port list
- //
- pPort = pSocket->pPortList;
- while ( NULL != pPort ) {
- //
- // Attempt to configure the port
- //
- pNextPort = pPort->pLinkSocket;
- pUdp4 = &pPort->Context.Udp4;
- pUdp4Protocol = pPort->pProtocol.UDPv4;
- pConfigData = &pUdp4->ConfigData;
- DEBUG (( DEBUG_TX,
- "0x%08x: pPort Configuring for %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d\r\n",
- pPort,
- pConfigData->StationAddress.Addr[0],
- pConfigData->StationAddress.Addr[1],
- pConfigData->StationAddress.Addr[2],
- pConfigData->StationAddress.Addr[3],
- pConfigData->StationPort,
- pConfigData->RemoteAddress.Addr[0],
- pConfigData->RemoteAddress.Addr[1],
- pConfigData->RemoteAddress.Addr[2],
- pConfigData->RemoteAddress.Addr[3],
- pConfigData->RemotePort ));
- Status = pUdp4Protocol->Configure ( pUdp4Protocol,
- pConfigData );
- if ( !EFI_ERROR ( Status )) {
- //
- // Update the configuration data
- //
- Status = pUdp4Protocol->GetModeData ( pUdp4Protocol,
- pConfigData,
- NULL,
- NULL,
- NULL );
- }
- if ( EFI_ERROR ( Status )) {
- if ( !pSocket->bConfigured ) {
- DEBUG (( DEBUG_LISTEN,
- "ERROR - Failed to configure the Udp4 port, Status: %r\r\n",
- Status ));
- switch ( Status ) {
- case EFI_ACCESS_DENIED:
- pSocket->errno = EACCES;
- break;
-
- default:
- case EFI_DEVICE_ERROR:
- pSocket->errno = EIO;
- break;
-
- case EFI_INVALID_PARAMETER:
- pSocket->errno = EADDRNOTAVAIL;
- break;
-
- case EFI_NO_MAPPING:
- pSocket->errno = EAFNOSUPPORT;
- break;
-
- case EFI_OUT_OF_RESOURCES:
- pSocket->errno = ENOBUFS;
- break;
-
- case EFI_UNSUPPORTED:
- pSocket->errno = EOPNOTSUPP;
- break;
- }
- }
- }
- else {
- DEBUG (( DEBUG_TX,
- "0x%08x: pPort Configured for %d.%d.%d.%d:%d --> %d.%d.%d.%d:%d\r\n",
- pPort,
- pConfigData->StationAddress.Addr[0],
- pConfigData->StationAddress.Addr[1],
- pConfigData->StationAddress.Addr[2],
- pConfigData->StationAddress.Addr[3],
- pConfigData->StationPort,
- pConfigData->RemoteAddress.Addr[0],
- pConfigData->RemoteAddress.Addr[1],
- pConfigData->RemoteAddress.Addr[2],
- pConfigData->RemoteAddress.Addr[3],
- pConfigData->RemotePort ));
- pPort->bConfigured = TRUE;
- pSocket->bConfigured = TRUE;
-
- //
- // Start the first read on the port
- //
- EslSocketRxStart ( pPort );
-
- //
- // The socket is connected
- //
- pSocket->State = SOCKET_STATE_CONNECTED;
- pSocket->errno = 0;
- }
-
- //
- // Set the next port
- //
- pPort = pNextPort;
- }
- }
-
- //
- // Determine the socket configuration status
- //
- Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;
-
- //
- // Return the port connected state.
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
- Buffer data for transmission over a network connection.
-
- This routine buffers data for the transmit engine in the normal
- data queue. When the \ref TransmitEngine has resources, this
- routine will start the transmission of the next buffer on the
- network connection.
-
- This routine is called by ::EslSocketTransmit to buffer
- data for transmission. The data is copied into a local buffer
- freeing the application buffer for reuse upon return. When
- necessary, this routine starts the transmit engine that
- performs the data transmission on the network connection. The
- transmit engine transmits the data a packet at a time over the
- network connection.
-
- Transmission errors are returned during the next transmission or
- during the close operation. Only buffering errors are returned
- during the current transmission attempt.
-
- @param [in] pSocket Address of an ::ESL_SOCKET structure
-
- @param [in] Flags Message control flags
-
- @param [in] BufferLength Length of the the buffer
-
- @param [in] pBuffer Address of a buffer to receive the data.
-
- @param [in] pDataLength Number of received data bytes in the buffer.
-
- @param [in] pAddress Network address of the remote system address
-
- @param [in] AddressLength Length of the remote network address structure
-
- @retval EFI_SUCCESS - Socket data successfully buffered
-
-**/
-EFI_STATUS
-EslUdp4TxBuffer (
- IN ESL_SOCKET * pSocket,
- IN int Flags,
- IN size_t BufferLength,
- IN CONST UINT8 * pBuffer,
- OUT size_t * pDataLength,
- IN const struct sockaddr * pAddress,
- IN socklen_t AddressLength
- )
-{
- ESL_PACKET * pPacket;
- ESL_PACKET * pPreviousPacket;
- ESL_PORT * pPort;
- const struct sockaddr_in * pRemoteAddress;
- ESL_UDP4_CONTEXT * pUdp4;
- size_t * pTxBytes;
- ESL_UDP4_TX_DATA * pTxData;
- EFI_STATUS Status;
- EFI_TPL TplPrevious;
-
- DBG_ENTER ( );
-
- //
- // Assume failure
- //
- Status = EFI_UNSUPPORTED;
- pSocket->errno = ENOTCONN;
- *pDataLength = 0;
-
- //
- // Verify that the socket is connected
- //
- if ( SOCKET_STATE_CONNECTED == pSocket->State ) {
- //
- // Verify that there is enough room to buffer another
- // transmit operation
- //
- pTxBytes = &pSocket->TxBytes;
- if ( pSocket->MaxTxBuf > *pTxBytes ) {
- //
- // Locate the port
- //
- pPort = pSocket->pPortList;
- while ( NULL != pPort ) {
- //
- // Determine the queue head
- //
- pUdp4 = &pPort->Context.Udp4;
-
- //
- // Attempt to allocate the packet
- //
- Status = EslSocketPacketAllocate ( &pPacket,
- sizeof ( pPacket->Op.Udp4Tx )
- - sizeof ( pPacket->Op.Udp4Tx.Buffer )
- + BufferLength,
- 0,
- DEBUG_TX );
- if ( !EFI_ERROR ( Status )) {
- //
- // Initialize the transmit operation
- //
- pTxData = &pPacket->Op.Udp4Tx;
- pTxData->TxData.GatewayAddress = NULL;
- pTxData->TxData.UdpSessionData = NULL;
- pTxData->TxData.DataLength = (UINT32) BufferLength;
- pTxData->TxData.FragmentCount = 1;
- pTxData->TxData.FragmentTable[0].FragmentLength = (UINT32) BufferLength;
- pTxData->TxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Udp4Tx.Buffer[0];
- pTxData->RetransmitCount = 0;
-
- //
- // Set the remote system address if necessary
- //
- pTxData->TxData.UdpSessionData = NULL;
- if ( NULL != pAddress ) {
- pRemoteAddress = (const struct sockaddr_in *)pAddress;
- pTxData->Session.SourceAddress.Addr[0] = pUdp4->ConfigData.StationAddress.Addr[0];
- pTxData->Session.SourceAddress.Addr[1] = pUdp4->ConfigData.StationAddress.Addr[1];
- pTxData->Session.SourceAddress.Addr[2] = pUdp4->ConfigData.StationAddress.Addr[2];
- pTxData->Session.SourceAddress.Addr[3] = pUdp4->ConfigData.StationAddress.Addr[3];
- pTxData->Session.SourcePort = 0;
- pTxData->Session.DestinationAddress.Addr[0] = (UINT8)pRemoteAddress->sin_addr.s_addr;
- pTxData->Session.DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );
- pTxData->Session.DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );
- pTxData->Session.DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );
- pTxData->Session.DestinationPort = SwapBytes16 ( pRemoteAddress->sin_port );
-
- //
- // Use the remote system address when sending this packet
- //
- pTxData->TxData.UdpSessionData = &pTxData->Session;
- }
-
- //
- // Copy the data into the buffer
- //
- CopyMem ( &pPacket->Op.Udp4Tx.Buffer[0],
- pBuffer,
- BufferLength );
-
- //
- // Synchronize with the socket layer
- //
- RAISE_TPL ( TplPrevious, TPL_SOCKETS );
-
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d bytes from 0x%08x to %d.%d.%d.%d:%d\r\n",
- BufferLength,
- pBuffer,
- pTxData->Session.DestinationAddress.Addr[0],
- pTxData->Session.DestinationAddress.Addr[1],
- pTxData->Session.DestinationAddress.Addr[2],
- pTxData->Session.DestinationAddress.Addr[3],
- pTxData->Session.DestinationPort ));
-
- //
- // Queue the data for transmission
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
-
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- pPacket = pSocket->pTxPacketListHead;
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
-
- //
- // Ignore any transmit error
- //
- if ( EFI_ERROR ( pSocket->TxError )) {
- DEBUG (( DEBUG_TX,
- "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
- pPort,
- pPacket,
- pSocket->TxError ));
- }
- pSocket->TxError = EFI_SUCCESS;
- }
-
- //
- // Release the socket layer synchronization
- //
- RESTORE_TPL ( TplPrevious );
- }
- else {
- //
- // Packet allocation failed
- //
- pSocket->errno = ENOMEM;
- break;
- }
-
- //
- // Set the next port
- //
- pPort = pPort->pLinkSocket;
- }
- }
- else {
- //
- // Not enough buffer space available
- //
- pSocket->errno = EAGAIN;
- Status = EFI_NOT_READY;
- }
- }
-
- //
- // Return the operation status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
- Process the transmit completion
-
- This routine use ::EslSocketTxComplete to perform the transmit
- completion processing for data packets.
-
- This routine is called by the UDPv4 network layer when a data
- transmit request completes.
-
- @param [in] Event The normal transmit completion event
-
- @param [in] pIo Address of an ::ESL_IO_MGMT structure
-
-**/
-VOID
-EslUdp4TxComplete (
- IN EFI_EVENT Event,
- IN ESL_IO_MGMT * pIo
- )
-{
- UINT32 LengthInBytes;
- ESL_PORT * pPort;
- ESL_PACKET * pPacket;
- ESL_SOCKET * pSocket;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Locate the active transmit packet
- //
- pPacket = pIo->pPacket;
- pPort = pIo->pPort;
- pSocket = pPort->pSocket;
-
- //
- // Get the transmit length and status
- //
- LengthInBytes = pPacket->Op.Udp4Tx.TxData.DataLength;
- pSocket->TxBytes -= LengthInBytes;
- Status = pIo->Token.Udp4Tx.Status;
-
- //
- // Ignore the transmit error
- //
- if ( EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_TX,
- "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
- pPort,
- pPacket,
- Status ));
- Status = EFI_SUCCESS;
- }
-
- //
- // Complete the transmit operation
- //
- EslSocketTxComplete ( pIo,
- LengthInBytes,
- Status,
- "UDP ",
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- DBG_EXIT ( );
-}
-
-
-/**
- Verify the adapter's IP address
-
- This support routine is called by EslSocketBindTest.
-
- @param [in] pPort Address of an ::ESL_PORT structure.
- @param [in] pConfigData Address of the configuration data
-
- @retval EFI_SUCCESS - The IP address is valid
- @retval EFI_NOT_STARTED - The IP address is invalid
-
- **/
-EFI_STATUS
-EslUdp4VerifyLocalIpAddress (
- IN ESL_PORT * pPort,
- IN EFI_UDP4_CONFIG_DATA * pConfigData
- )
-{
- UINTN DataSize;
- EFI_IP4_CONFIG2_INTERFACE_INFO * pIfInfo;
- EFI_IP4_CONFIG2_PROTOCOL * pIpConfig2Protocol;
- ESL_SERVICE * pService;
- EFI_STATUS Status;
-
- DBG_ENTER ( );
-
- //
- // Use break instead of goto
- //
- pIfInfo = NULL;
- for ( ; ; ) {
- //
- // Determine if the IP address is specified
- //
- DEBUG (( DEBUG_BIND,
- "UseDefaultAddress: %s\r\n",
- pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
- DEBUG (( DEBUG_BIND,
- "Requested IP address: %d.%d.%d.%d\r\n",
- pConfigData->StationAddress.Addr [ 0 ],
- pConfigData->StationAddress.Addr [ 1 ],
- pConfigData->StationAddress.Addr [ 2 ],
- pConfigData->StationAddress.Addr [ 3 ]));
- if ( pConfigData->UseDefaultAddress
- || (( 0 == pConfigData->StationAddress.Addr [ 0 ])
- && ( 0 == pConfigData->StationAddress.Addr [ 1 ])
- && ( 0 == pConfigData->StationAddress.Addr [ 2 ])
- && ( 0 == pConfigData->StationAddress.Addr [ 3 ])))
- {
- Status = EFI_SUCCESS;
- break;
- }
-
- //
- // Open the configuration protocol
- //
- pService = pPort->pService;
- Status = gBS->OpenProtocol (
- pService->Controller,
- &gEfiIp4Config2ProtocolGuid,
- (VOID **)&pIpConfig2Protocol,
- NULL,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if ( EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_ERROR,
- "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
- Status ));
- break;
- }
-
- //
- // Get the interface information size
- //
- DataSize = 0;
- Status = pIpConfig2Protocol->GetData (
- pIpConfig2Protocol,
- Ip4Config2DataTypeInterfaceInfo,
- &DataSize,
- NULL
- );
- if ( EFI_BUFFER_TOO_SMALL != Status ) {
- DEBUG (( DEBUG_ERROR,
- "ERROR - Failed to get the interface information size, Status: %r\r\n",
- Status ));
- break;
- }
-
- //
- // Allocate the interface information buffer
- //
- pIfInfo = AllocatePool ( DataSize );
- if ( NULL == pIfInfo ) {
- DEBUG (( DEBUG_ERROR,
- "ERROR - Not enough memory to allocate the interface information buffer!\r\n" ));
- Status = EFI_OUT_OF_RESOURCES;
- break;
- }
-
- //
- // Get the interface info.
- //
- Status = pIpConfig2Protocol->GetData (
- pIpConfig2Protocol,
- Ip4Config2DataTypeInterfaceInfo,
- &DataSize,
- pIfInfo
- );
- if ( EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_ERROR,
- "ERROR - Failed to return the interface info, Status: %r\r\n",
- Status ));
- break;
- }
-
- //
- // Display the current configuration
- //
- DEBUG (( DEBUG_BIND,
- "Actual adapter IP address: %d.%d.%d.%d\r\n",
- pIfInfo->StationAddress.Addr [ 0 ],
- pIfInfo->StationAddress.Addr [ 1 ],
- pIfInfo->StationAddress.Addr [ 2 ],
- pIfInfo->StationAddress.Addr [ 3 ]));
-
- //
- // Assume the port is not configured
- //
- Status = EFI_SUCCESS;
- if (( pConfigData->StationAddress.Addr [ 0 ] == pIfInfo->StationAddress.Addr [ 0 ])
- && ( pConfigData->StationAddress.Addr [ 1 ] == pIfInfo->StationAddress.Addr [ 1 ])
- && ( pConfigData->StationAddress.Addr [ 2 ] == pIfInfo->StationAddress.Addr [ 2 ])
- && ( pConfigData->StationAddress.Addr [ 3 ] == pIfInfo->StationAddress.Addr [ 3 ])) {
- break;
- }
-
- //
- // The IP address did not match
- //
- Status = EFI_NOT_STARTED;
- break;
- }
-
- //
- // Free the buffer if necessary
- //
- if ( NULL != pIfInfo ) {
- FreePool ( pIfInfo );
- }
-
- //
- // Return the IP address status
- //
- DBG_EXIT_STATUS ( Status );
- return Status;
-}
-
-
-/**
- Interface between the socket layer and the network specific
- code that supports SOCK_DGRAM sockets over UDPv4.
-**/
-CONST ESL_PROTOCOL_API cEslUdp4Api = {
- "UDPv4",
- IPPROTO_UDP,
- OFFSET_OF ( ESL_PORT, Context.Udp4.ConfigData ),
- OFFSET_OF ( ESL_LAYER, pUdp4List ),
- OFFSET_OF ( struct sockaddr_in, sin_zero ),
- sizeof ( struct sockaddr_in ),
- AF_INET,
- sizeof (((ESL_PACKET *)0 )->Op.Udp4Rx ),
- sizeof (((ESL_PACKET *)0 )->Op.Udp4Rx ),
- OFFSET_OF ( ESL_IO_MGMT, Token.Udp4Rx.Packet.RxData ),
- FALSE,
- EADDRINUSE,
- NULL, // Accept
- NULL, // ConnectPoll
- NULL, // ConnectStart
- EslUdp4SocketIsConfigured,
- EslUdp4LocalAddressGet,
- EslUdp4LocalAddressSet,
- NULL, // Listen
- NULL, // OptionGet
- NULL, // OptionSet
- EslUdp4PacketFree,
- EslUdp4PortAllocate,
- NULL, // PortClose,
- NULL, // PortCloseOp
- TRUE,
- EslUdp4Receive,
- EslUdp4RemoteAddressGet,
- EslUdp4RemoteAddressSet,
- EslUdp4RxComplete,
- NULL, // RxStart
- EslUdp4TxBuffer,
- EslUdp4TxComplete,
- NULL, // TxOobComplete
- (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslUdp4VerifyLocalIpAddress
-};