}\r
else {\r
pConfig->SubnetMask.Addr[0] = 0xff;\r
- pConfig->SubnetMask.Addr[1] = 0xff;\r
- pConfig->SubnetMask.Addr[2] = 0xff;\r
- pConfig->SubnetMask.Addr[3] = 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
//\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
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
//\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
NULL );\r
}\r
if ( EFI_ERROR ( Status )) {\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
+ 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
+ case EFI_INVALID_PARAMETER:\r
+ pSocket->errno = EADDRNOTAVAIL;\r
+ break;\r
\r
- case EFI_NO_MAPPING:\r
- pSocket->errno = EAFNOSUPPORT;\r
- break;\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
+ case EFI_OUT_OF_RESOURCES:\r
+ pSocket->errno = ENOBUFS;\r
+ break;\r
\r
- case EFI_UNSUPPORTED:\r
- pSocket->errno = EOPNOTSUPP;\r
- break;\r
+ case EFI_UNSUPPORTED:\r
+ pSocket->errno = EOPNOTSUPP;\r
+ break;\r
+ }\r
}\r
}\r
else {\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
// The socket is connected\r
//\r
pSocket->State = SOCKET_STATE_CONNECTED;\r
+ pSocket->errno = 0;\r
}\r
\r
//\r
//\r
pPort = pNextPort;\r
}\r
-\r
- //\r
- // Determine the configuration status\r
- //\r
- if ( NULL != pSocket->pPortList ) {\r
- pSocket->bConfigured = TRUE;\r
- }\r
}\r
\r
//\r
// Determine the socket configuration status\r
//\r
- if ( !EFI_ERROR ( Status )) {\r
- Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
- }\r
+ Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
\r
//\r
// Return the port connected state.\r
//\r
if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
//\r
- // Locate the port\r
+ // Verify that there is enough room to buffer another\r
+ // transmit operation\r
//\r
- pPort = pSocket->pPortList;\r
- if ( NULL != pPort ) {\r
+ pTxBytes = &pSocket->TxBytes;\r
+ if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
//\r
- // Determine the queue head\r
+ // Locate the port\r
//\r
- pIp4 = &pPort->Context.Ip4;\r
- pTxBytes = &pSocket->TxBytes;\r
+ pPort = pSocket->pPortList;\r
+ while ( NULL != pPort ) {\r
+ //\r
+ // Determine the queue head\r
+ //\r
+ pIp4 = &pPort->Context.Ip4;\r
\r
- //\r
- // Verify that there is enough room to buffer another\r
- // transmit operation\r
- //\r
- if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
//\r
// Attempt to allocate the packet\r
//\r
RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
\r
//\r
- // Stop transmission after an error\r
+ // Display the request\r
//\r
- if ( !EFI_ERROR ( pSocket->TxError )) {\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
+ 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
- // 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
+ // 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
- //\r
- // Previous transmit error\r
- // Stop transmission\r
- //\r
- Status = pSocket->TxError;\r
- pSocket->errno = EIO;\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
- // Free the packet\r
+ // Ignore any transmit error\r
//\r
- EslSocketPacketFree ( pPacket, DEBUG_TX );\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
// Packet allocation failed\r
//\r
pSocket->errno = ENOMEM;\r
+ break;\r
}\r
- }\r
- else {\r
+\r
//\r
- // Not enough buffer space available\r
+ // Set the next port\r
//\r
- pSocket->errno = EAGAIN;\r
- Status = EFI_NOT_READY;\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
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
}\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_IPCONFIG_DATA * pIpConfigData;\r
+ EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;\r
+ ESL_SERVICE * pService;\r
+ EFI_STATUS Status;\r
+\r
+ DBG_ENTER ( );\r
+\r
+ //\r
+ // Use break instead of goto\r
+ //\r
+ pIpConfigData = NULL;\r
+ for ( ; ; ) {\r
+ //\r
+ // Determine if the IP address is specified\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "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 ( pService->Controller,\r
+ &gEfiIp4ConfigProtocolGuid,\r
+ (VOID **)&pIpConfigProtocol,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the IP configuration data size\r
+ //\r
+ DataSize = 0;\r
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+ &DataSize,\r
+ NULL );\r
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Allocate the configuration data buffer\r
+ //\r
+ pIpConfigData = AllocatePool ( DataSize );\r
+ if ( NULL == pIpConfigData ) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the IP configuration\r
+ //\r
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+ &DataSize,\r
+ pIpConfigData );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Display the current configuration\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "Actual adapter IP address: %d.%d.%d.%d\r\n",\r
+ pIpConfigData->StationAddress.Addr [ 0 ],\r
+ pIpConfigData->StationAddress.Addr [ 1 ],\r
+ pIpConfigData->StationAddress.Addr [ 2 ],\r
+ pIpConfigData->StationAddress.Addr [ 3 ]));\r
+\r
+ //\r
+ // Assume the port is not configured\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])\r
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])\r
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])\r
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->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 != pIpConfigData ) {\r
+ FreePool ( pIpConfigData );\r
+ }\r
+\r
+ //\r
+ // Return the IP address status\r
+ //\r
+ DBG_EXIT_STATUS ( Status );\r
+ return Status;\r
+}\r
+\r
+\r
/**\r
Interface between the socket layer and the network specific\r
code that supports SOCK_RAW sockets over IPv4.\r
NULL, // RxStart\r
EslIp4TxBuffer,\r
EslIp4TxComplete,\r
- NULL // TxOobComplete\r
+ NULL, // TxOobComplete\r
+ (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslIp4VerifyLocalIpAddress\r
};\r