+++ /dev/null
-/** @file\r
- Implement the IP4 driver support for the socket layer.\r
-\r
- Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-**/\r
-#include "Socket.h"\r
-\r
-\r
-/** Get the local socket address.\r
-\r
- This routine returns the IPv4 address associated with the local\r
- socket.\r
-\r
- This routine is called by ::EslSocketGetLocalAddress to determine the\r
- network address for the SOCK_RAW socket.\r
-\r
- @param [in] pPort Address of an ::ESL_PORT structure.\r
- @param [out] pAddress Network address to receive the local system address\r
-**/\r
-VOID\r
-EslIp4LocalAddressGet (\r
- IN ESL_PORT * pPort,\r
- OUT struct sockaddr * pAddress\r
- )\r
-{\r
- struct sockaddr_in * pLocalAddress;\r
- ESL_IP4_CONTEXT * pIp4;\r
-\r
- DBG_ENTER ( );\r
-\r
- // Return the local address\r
- pIp4 = &pPort->Context.Ip4;\r
- pLocalAddress = (struct sockaddr_in *)pAddress;\r
- pLocalAddress->sin_family = AF_INET;\r
- CopyMem ( &pLocalAddress->sin_addr,\r
- &pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
- sizeof ( pLocalAddress->sin_addr ));\r
-\r
- DBG_EXIT ( );\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
-EFI_STATUS\r
-EslIp4LocalAddressSet (\r
- IN ESL_PORT * pPort,\r
- IN CONST struct sockaddr * pSockAddr,\r
- IN BOOLEAN bBindTest\r
- )\r
-{\r
- EFI_IP4_CONFIG_DATA * pConfig;\r
- CONST struct sockaddr_in * pIpAddress;\r
- CONST UINT8 * pIpv4Address;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- // Validate the address\r
- pIpAddress = (struct sockaddr_in *)pSockAddr;\r
- if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {\r
- // The local address must not be the broadcast address\r
- Status = EFI_INVALID_PARAMETER;\r
- pPort->pSocket->errno = EADDRNOTAVAIL;\r
- }\r
- else {\r
- Status = EFI_SUCCESS;\r
-\r
- // Set the local address\r
- pIpAddress = (struct sockaddr_in *)pSockAddr;\r
- pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;\r
- pConfig = &pPort->Context.Ip4.ModeData.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
- // Determine if the default address is used\r
- pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );\r
-\r
- // Display the local address\r
- DEBUG (( DEBUG_BIND,\r
- "0x%08x: Port, Local IP4 Address: %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
-\r
- // Set the subnet mask\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
- // Return the operation status\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/** Get the option value.\r
-\r
- This routine handles the IPv4 level options.\r
-\r
- The ::EslSocketOptionGet routine calls this routine to retrieve\r
- the IPv4 options one at a time by name.\r
-\r
- @param [in] pSocket Address of an ::ESL_SOCKET structure\r
- @param [in] OptionName Name of the option\r
- @param [out] ppOptionData Buffer to receive address of option value\r
- @param [out] pOptionLength Buffer to receive the option length\r
-\r
- @retval EFI_SUCCESS - Socket data successfully received\r
- **/\r
-EFI_STATUS\r
-EslIp4OptionGet (\r
- IN ESL_SOCKET * pSocket,\r
- IN int OptionName,\r
- OUT CONST void ** __restrict ppOptionData,\r
- OUT socklen_t * __restrict pOptionLength\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- // Assume success\r
- pSocket->errno = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- // Attempt to get the option\r
- switch ( OptionName ) {\r
- default:\r
- // Option not supported\r
- pSocket->errno = ENOPROTOOPT;\r
- Status = EFI_INVALID_PARAMETER;\r
- break;\r
-\r
- case IP_HDRINCL:\r
- *ppOptionData = (void *)&pSocket->bIncludeHeader;\r
- *pOptionLength = sizeof ( pSocket->bIncludeHeader );\r
- break;\r
- }\r
- // Return the operation status\r
- DBG_EXIT_STATUS ( Status );\r
- return Status;\r
-}\r
-\r
-\r
-/** Set the option value.\r
-\r
- This routine handles the IPv4 level options.\r
-\r
- The ::EslSocketOptionSet routine calls this routine to adjust\r
- the IPv4 options one at a time by name.\r
-\r
- @param [in] pSocket Address of an ::ESL_SOCKET structure\r
- @param [in] OptionName Name of the option\r
- @param [in] pOptionValue Buffer containing the option value\r
- @param [in] OptionLength Length of the buffer in bytes\r
-\r
- @retval EFI_SUCCESS - Option successfully set\r
- **/\r
-EFI_STATUS\r
-EslIp4OptionSet (\r
- IN ESL_SOCKET * pSocket,\r
- IN int OptionName,\r
- IN CONST void * pOptionValue,\r
- IN socklen_t OptionLength\r
- )\r
-{\r
- BOOLEAN bTrueFalse;\r
- //socklen_t LengthInBytes;\r
- //UINT8 * pOptionData;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- // Assume success\r
- pSocket->errno = 0;\r
- Status = EFI_SUCCESS;\r
-\r
- // Determine if the option protocol matches\r
- //LengthInBytes = 0;\r
- //pOptionData = NULL;\r
- switch ( OptionName ) {\r
- default:\r
- // Protocol level not supported\r
- DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid protocol option\r\n" ));\r
- pSocket->errno = ENOTSUP;\r
- Status = EFI_UNSUPPORTED;\r
- break;\r
-\r
- case IP_HDRINCL:\r
-\r
- // Validate the option length\r
- if ( sizeof ( UINT32 ) == OptionLength ) {\r
- // Restrict the input to TRUE or FALSE\r
- bTrueFalse = TRUE;\r
- if ( 0 == *(UINT32 *)pOptionValue ) {\r
- bTrueFalse = FALSE;\r
- }\r
- pOptionValue = &bTrueFalse;\r
-\r
- // Set the option value\r
- //pOptionData = (UINT8 *)&pSocket->bIncludeHeader;\r
- //LengthInBytes = sizeof ( pSocket->bIncludeHeader );\r
- }\r
- break;\r
- }\r
- // Return the operation status\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
-EslIp4PacketFree (\r
- IN ESL_PACKET * pPacket,\r
- IN OUT size_t * pRxBytes\r
- )\r
-{\r
- EFI_IP4_RECEIVE_DATA * pRxData;\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Account for the receive bytes\r
- //\r
- pRxData = pPacket->Op.Ip4Rx.pRxData;\r
- *pRxBytes -= pRxData->HeaderLength + pRxData->DataLength;\r
-\r
- //\r
- // Disconnect the buffer from the packet\r
- //\r
- pPacket->Op.Ip4Rx.pRxData = NULL;\r
-\r
- //\r
- // Return the buffer to the IP4 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 IPv4 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
-EslIp4PortAllocate (\r
- IN ESL_PORT * pPort,\r
- IN UINTN DebugFlags\r
- )\r
-{\r
- EFI_IP4_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.Ip4Tx.TxData );\r
- pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Ip4Tx.Event );\r
- pSocket->TxTokenOffset = OFFSET_OF ( EFI_IP4_COMPLETION_TOKEN, Packet.TxData );\r
-\r
- //\r
- // Save the cancel, receive and transmit addresses\r
- //\r
- pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.IPv4->Configure;\r
- pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Cancel;\r
- pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.IPv4->Poll;\r
- pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Receive;\r
- pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Transmit;\r
-\r
- //\r
- // Set the configuration flags\r
- //\r
- pConfig = &pPort->Context.Ip4.ModeData.ConfigData;\r
- pConfig->AcceptIcmpErrors = FALSE;\r
- pConfig->AcceptBroadcast = FALSE;\r
- pConfig->AcceptPromiscuous = FALSE;\r
- pConfig->TypeOfService = 0;\r
- pConfig->TimeToLive = 255;\r
- pConfig->DoNotFragment = FALSE;\r
- pConfig->RawData = FALSE;\r
- pConfig->ReceiveTimeout = 0;\r
- pConfig->TransmitTimeout = 0;\r
-\r
- //\r
- // Set the default protocol\r
- //\r
- pConfig->DefaultProtocol = (UINT8)pSocket->Protocol;\r
- pConfig->AcceptAnyProtocol = (BOOLEAN)( 0 == pConfig->DefaultProtocol );\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_RAW 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
-EslIp4Receive (\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
- size_t HeaderBytes;\r
- size_t LengthInBytes;\r
- struct sockaddr_in * pRemoteAddress;\r
- EFI_IP4_RECEIVE_DATA * pRxData;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Return the remote system address if requested\r
- //\r
- pRxData = pPacket->Op.Ip4Rx.pRxData;\r
- if ( NULL != pAddress ) {\r
- //\r
- // Build the remote address\r
- //\r
- DEBUG (( DEBUG_RX,\r
- "Getting packet remote address: %d.%d.%d.%d\r\n",\r
- pRxData->Header->SourceAddress.Addr[0],\r
- pRxData->Header->SourceAddress.Addr[1],\r
- pRxData->Header->SourceAddress.Addr[2],\r
- pRxData->Header->SourceAddress.Addr[3]));\r
- pRemoteAddress = (struct sockaddr_in *)pAddress;\r
- CopyMem ( &pRemoteAddress->sin_addr,\r
- &pRxData->Header->SourceAddress.Addr[0],\r
- sizeof ( pRemoteAddress->sin_addr ));\r
- }\r
-\r
- //\r
- // Copy the IP header\r
- //\r
- HeaderBytes = pRxData->HeaderLength;\r
- if ( HeaderBytes > BufferLength ) {\r
- HeaderBytes = BufferLength;\r
- }\r
- DEBUG (( DEBUG_RX,\r
- "0x%08x --> 0x%08x: Copy header 0x%08x bytes\r\n",\r
- pRxData->Header,\r
- pBuffer,\r
- HeaderBytes ));\r
- CopyMem ( pBuffer, pRxData->Header, HeaderBytes );\r
- pBuffer += HeaderBytes;\r
- LengthInBytes = HeaderBytes;\r
-\r
- //\r
- // Copy the received data\r
- //\r
- if ( 0 < ( BufferLength - LengthInBytes )) {\r
- pBuffer = EslSocketCopyFragmentedBuffer ( pRxData->FragmentCount,\r
- &pRxData->FragmentTable[0],\r
- BufferLength - LengthInBytes,\r
- pBuffer,\r
- &DataBytes );\r
- LengthInBytes += DataBytes;\r
- }\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
- LengthInBytes ));\r
-\r
- //\r
- // Account for any discarded data\r
- //\r
- *pSkipBytes = pRxData->HeaderLength + pRxData->DataLength - LengthInBytes;\r
- }\r
-\r
- //\r
- // Return the data length and the buffer address\r
- //\r
- *pDataLength = LengthInBytes;\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_RAW socket.\r
-\r
- This routine is called by ::EslSocketGetPeerAddress to detemine\r
- the IPv4 address 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
-EslIp4RemoteAddressGet (\r
- IN ESL_PORT * pPort,\r
- OUT struct sockaddr * pAddress\r
- )\r
-{\r
- struct sockaddr_in * pRemoteAddress;\r
- ESL_IP4_CONTEXT * pIp4;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Return the remote address\r
- //\r
- pIp4 = &pPort->Context.Ip4;\r
- pRemoteAddress = (struct sockaddr_in *)pAddress;\r
- pRemoteAddress->sin_family = AF_INET;\r
- CopyMem ( &pRemoteAddress->sin_addr,\r
- &pIp4->DestinationAddress.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
-EslIp4RemoteAddressSet (\r
- IN ESL_PORT * pPort,\r
- IN CONST struct sockaddr * pSockAddr,\r
- IN socklen_t SockAddrLength\r
- )\r
-{\r
- ESL_IP4_CONTEXT * pIp4;\r
- CONST struct sockaddr_in * pRemoteAddress;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Set the remote address\r
- //\r
- pIp4 = &pPort->Context.Ip4;\r
- pRemoteAddress = (struct sockaddr_in *)pSockAddr;\r
- pIp4->DestinationAddress.Addr[0] = (UINT8)( pRemoteAddress->sin_addr.s_addr );\r
- pIp4->DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
- pIp4->DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
- pIp4->DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\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 IPv4 driver's buffer and queues it in\r
- in FIFO order to the data queue. The IP4 driver's buffer will\r
- be returned by either ::EslIp4Receive or ::EslSocketPortCloseTxDone.\r
- See the \ref ReceiveEngine section.\r
-\r
- This routine is called by the IPv4 driver when data is\r
- received.\r
-\r
- @param [in] Event The receive completion event\r
-\r
- @param [in] pIo The address of an ::ESL_IO_MGMT structure\r
-\r
-**/\r
-VOID\r
-EslIp4RxComplete (\r
- IN EFI_EVENT Event,\r
- IN ESL_IO_MGMT * pIo\r
- )\r
-{\r
- size_t LengthInBytes;\r
- ESL_PACKET * pPacket;\r
- EFI_IP4_RECEIVE_DATA * pRxData;\r
- EFI_STATUS Status;\r
-\r
- DBG_ENTER ( );\r
-\r
- //\r
- // Get the operation status.\r
- //\r
- Status = pIo->Token.Ip4Rx.Status;\r
-\r
- //\r
- // Get the packet length\r
- //\r
- pRxData = pIo->Token.Ip4Rx.Packet.RxData;\r
- LengthInBytes = pRxData->HeaderLength + pRxData->DataLength;\r
-\r
- //{{\r
- // +--------------------+ +----------------------+\r
- // | ESL_IO_MGMT | | Data Buffer |\r
- // | | | (Driver owned) |\r
- // | +---------------+ +----------------------+\r
- // | | Token | ^\r
- // | | Rx Event | |\r
- // | | | +----------------------+\r
- // | | RxData --> | EFI_IP4_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.Ip4Rx.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 ::EslSocketBind and configuration routines\r
- if they were not already called. After the port is configured,\r
- the \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
- EslIp4SocketIsConfigured (\r
- IN ESL_SOCKET * pSocket\r
- )\r
-{\r
- UINTN Index;\r
- ESL_PORT * pPort;\r
- ESL_PORT * pNextPort;\r
- ESL_IP4_CONTEXT * pIp4;\r
- EFI_IP4_PROTOCOL * pIp4Protocol;\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
- // Update the raw setting\r
- //\r
- pIp4 = &pPort->Context.Ip4;\r
- if ( pSocket->bIncludeHeader ) {\r
- //\r
- // IP header will be included with the data on transmit\r
- //\r
- pIp4->ModeData.ConfigData.RawData = TRUE;\r
- }\r
-\r
- //\r
- // Attempt to configure the port\r
- //\r
- pNextPort = pPort->pLinkSocket;\r
- pIp4Protocol = pPort->pProtocol.IPv4;\r
- DEBUG (( DEBUG_TX,\r
- "0x%08x: pPort Configuring for %d.%d.%d.%d --> %d.%d.%d.%d\r\n",\r
- pPort,\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
- pIp4->DestinationAddress.Addr[0],\r
- pIp4->DestinationAddress.Addr[1],\r
- pIp4->DestinationAddress.Addr[2],\r
- pIp4->DestinationAddress.Addr[3]));\r
- Status = pIp4Protocol->Configure ( pIp4Protocol,\r
- &pIp4->ModeData.ConfigData );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Update the configuration data\r
- //\r
- Status = pIp4Protocol->GetModeData ( pIp4Protocol,\r
- &pIp4->ModeData,\r
- NULL,\r
- NULL );\r
- }\r
- if ( EFI_ERROR ( Status )) {\r
- if ( !pSocket->bConfigured ) {\r
- DEBUG (( DEBUG_LISTEN,\r
- "ERROR - Failed to configure the Ip4 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\r\n",\r
- pPort,\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
- pIp4->DestinationAddress.Addr[0],\r
- pIp4->DestinationAddress.Addr[1],\r
- pIp4->DestinationAddress.Addr[2],\r
- pIp4->DestinationAddress.Addr[3]));\r
- DEBUG (( DEBUG_TX,\r
- "Subnet Mask: %d.%d.%d.%d\r\n",\r
- pIp4->ModeData.ConfigData.SubnetMask.Addr[0],\r
- pIp4->ModeData.ConfigData.SubnetMask.Addr[1],\r
- pIp4->ModeData.ConfigData.SubnetMask.Addr[2],\r
- pIp4->ModeData.ConfigData.SubnetMask.Addr[3]));\r
- DEBUG (( DEBUG_TX,\r
- "Route Count: %d\r\n",\r
- pIp4->ModeData.RouteCount ));\r
- for ( Index = 0; pIp4->ModeData.RouteCount > Index; Index++ ) {\r
- if ( 0 == Index ) {\r
- DEBUG (( DEBUG_TX, "Route Table:\r\n" ));\r
- }\r
- DEBUG (( DEBUG_TX,\r
- "%5d: %d.%d.%d.%d, %d.%d.%d.%d ==> %d.%d.%d.%d\r\n",\r
- Index,\r
- pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[0],\r
- pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[1],\r
- pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[2],\r
- pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[3],\r
- pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[0],\r
- pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[1],\r
- pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[2],\r
- pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[3],\r
- pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[0],\r
- pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[1],\r
- pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[2],\r
- pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[3]));\r
- }\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
-EslIp4TxBuffer (\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_IP4_CONTEXT * pIp4;\r
- size_t * pTxBytes;\r
- ESL_IP4_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
- pIp4 = &pPort->Context.Ip4;\r
-\r
- //\r
- // Attempt to allocate the packet\r
- //\r
- Status = EslSocketPacketAllocate ( &pPacket,\r
- sizeof ( pPacket->Op.Ip4Tx )\r
- - sizeof ( pPacket->Op.Ip4Tx.Buffer )\r
- + BufferLength,\r
- 0,\r
- DEBUG_TX );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Initialize the transmit operation\r
- //\r
- pTxData = &pPacket->Op.Ip4Tx;\r
- pTxData->TxData.DestinationAddress.Addr[0] = pIp4->DestinationAddress.Addr[0];\r
- pTxData->TxData.DestinationAddress.Addr[1] = pIp4->DestinationAddress.Addr[1];\r
- pTxData->TxData.DestinationAddress.Addr[2] = pIp4->DestinationAddress.Addr[2];\r
- pTxData->TxData.DestinationAddress.Addr[3] = pIp4->DestinationAddress.Addr[3];\r
- pTxData->TxData.OverrideData = NULL;\r
- pTxData->TxData.OptionsLength = 0;\r
- pTxData->TxData.OptionsBuffer = NULL;\r
- pTxData->TxData.TotalDataLength = (UINT32) BufferLength;\r
- pTxData->TxData.FragmentCount = 1;\r
- pTxData->TxData.FragmentTable[0].FragmentLength = (UINT32) BufferLength;\r
- pTxData->TxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Ip4Tx.Buffer[0];\r
-\r
- //\r
- // Set the remote system address if necessary\r
- //\r
- if ( NULL != pAddress ) {\r
- pRemoteAddress = (const struct sockaddr_in *)pAddress;\r
- pTxData->Override.SourceAddress.Addr[0] = pIp4->ModeData.ConfigData.StationAddress.Addr[0];\r
- pTxData->Override.SourceAddress.Addr[1] = pIp4->ModeData.ConfigData.StationAddress.Addr[1];\r
- pTxData->Override.SourceAddress.Addr[2] = pIp4->ModeData.ConfigData.StationAddress.Addr[2];\r
- pTxData->Override.SourceAddress.Addr[3] = pIp4->ModeData.ConfigData.StationAddress.Addr[3];\r
- pTxData->TxData.DestinationAddress.Addr[0] = (UINT8)pRemoteAddress->sin_addr.s_addr;\r
- pTxData->TxData.DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
- pTxData->TxData.DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
- pTxData->TxData.DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\r
- pTxData->Override.GatewayAddress.Addr[0] = 0;\r
- pTxData->Override.GatewayAddress.Addr[1] = 0;\r
- pTxData->Override.GatewayAddress.Addr[2] = 0;\r
- pTxData->Override.GatewayAddress.Addr[3] = 0;\r
- pTxData->Override.Protocol = (UINT8)pSocket->Protocol;\r
- pTxData->Override.TypeOfService = 0;\r
- pTxData->Override.TimeToLive = 255;\r
- pTxData->Override.DoNotFragment = FALSE;\r
-\r
- //\r
- // Use the remote system address when sending this packet\r
- //\r
- pTxData->TxData.OverrideData = &pTxData->Override;\r
- }\r
-\r
- //\r
- // Copy the data into the buffer\r
- //\r
- CopyMem ( &pPacket->Op.Ip4Tx.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, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",\r
- BufferLength,\r
- pBuffer,\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
- pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
- pTxData->TxData.DestinationAddress.Addr[0],\r
- pTxData->TxData.DestinationAddress.Addr[1],\r
- pTxData->TxData.DestinationAddress.Addr[2],\r
- pTxData->TxData.DestinationAddress.Addr[3]));\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 IPv4 network layer when a data\r
- transmit request completes.\r
-\r
- @param [in] Event The normal transmit completion event\r
-\r
- @param [in] pIo The address of an ::ESL_IO_MGMT structure\r
-\r
-**/\r
-VOID\r
-EslIp4TxComplete (\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.Ip4Tx.TxData.TotalDataLength;\r
- pSocket->TxBytes -= LengthInBytes;\r
- Status = pIo->Token.Ip4Tx.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
- "Raw ",\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
-EslIp4VerifyLocalIpAddress (\r
- IN ESL_PORT * pPort,\r
- IN EFI_IP4_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_RAW sockets over IPv4.\r
-**/\r
-CONST ESL_PROTOCOL_API cEslIp4Api = {\r
- "IPv4",\r
- IPPROTO_IP,\r
- OFFSET_OF ( ESL_PORT, Context.Ip4.ModeData.ConfigData ),\r
- OFFSET_OF ( ESL_LAYER, pIp4List ),\r
- OFFSET_OF ( struct sockaddr_in, sin_zero ),\r
- sizeof ( struct sockaddr_in ),\r
- AF_INET,\r
- sizeof (((ESL_PACKET *)0 )->Op.Ip4Rx ),\r
- sizeof (((ESL_PACKET *)0 )->Op.Ip4Rx ),\r
- OFFSET_OF ( ESL_IO_MGMT, Token.Ip4Rx.Packet.RxData ),\r
- FALSE,\r
- EADDRNOTAVAIL,\r
- NULL, // Accept\r
- NULL, // ConnectPoll\r
- NULL, // ConnectStart\r
- EslIp4SocketIsConfigured,\r
- EslIp4LocalAddressGet,\r
- EslIp4LocalAddressSet,\r
- NULL, // Listen\r
- EslIp4OptionGet,\r
- EslIp4OptionSet,\r
- EslIp4PacketFree,\r
- EslIp4PortAllocate,\r
- NULL, // PortClose\r
- NULL, // PortCloseOp\r
- TRUE,\r
- EslIp4Receive,\r
- EslIp4RemoteAddressGet,\r
- EslIp4RemoteAddressSet,\r
- EslIp4RxComplete,\r
- NULL, // RxStart\r
- EslIp4TxBuffer,\r
- EslIp4TxComplete,\r
- NULL, // TxOobComplete\r
- (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslIp4VerifyLocalIpAddress\r
-};\r