UefiLib\r
\r
[Protocols]\r
+ gEfiIp4ConfigProtocolGuid\r
+ gEfiIp6ConfigProtocolGuid\r
gEfiIp4ProtocolGuid\r
gEfiIp4ServiceBindingProtocolGuid\r
gEfiIp6ProtocolGuid\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
- break;\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
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
+ EslIp4VerifyLocalIpAddress\r
};\r
pConfigData = (VOID *)pBuffer;\r
\r
//\r
- // Attempt to use this configuration\r
+ // Validate that the port is connected\r
//\r
- Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );\r
+ Status = pPort->pSocket->pApi->pfnVerifyLocalIpAddress ( pPort, pBuffer );\r
if ( EFI_ERROR ( Status )) {\r
DEBUG (( DEBUG_WARN | DEBUG_BIND,\r
- "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",\r
+ "WARNING - Port 0x%08x invalid IP address: %r\r\n",\r
pPort,\r
Status ));\r
pPort->pSocket->errno = ErrnoValue;\r
}\r
else {\r
//\r
- // Reset the port\r
+ // Attempt to use this configuration\r
//\r
- Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );\r
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );\r
if ( EFI_ERROR ( Status )) {\r
- DEBUG (( DEBUG_ERROR | DEBUG_BIND,\r
- "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",\r
+ DEBUG (( DEBUG_WARN | DEBUG_BIND,\r
+ "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",\r
pPort,\r
Status ));\r
- ASSERT ( EFI_SUCCESS == Status );\r
+ pPort->pSocket->errno = ErrnoValue;\r
+ }\r
+ else {\r
+ //\r
+ // Reset the port\r
+ //\r
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR | DEBUG_BIND,\r
+ "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",\r
+ pPort,\r
+ Status ));\r
+ ASSERT ( EFI_SUCCESS == Status );\r
+ }\r
}\r
}\r
\r
*ppActive = pIo;\r
}\r
else {\r
+ //\r
+ // Display the transmit error\r
+ //\r
+ DEBUG (( DEBUG_TX | DEBUG_INFO,\r
+ "0x%08x, 0x%08x: pIo, pPacket transmit failure: %r\r\n",\r
+ pIo,\r
+ pPacket,\r
+ Status ));\r
if ( EFI_SUCCESS == pSocket->TxError ) {\r
pSocket->TxError = Status;\r
}\r
\r
+ //\r
+ // Free the IO structure\r
+ //\r
+ pIo->pNext = *ppFree;\r
+ *ppFree = pIo;\r
+\r
//\r
// Discard the transmit buffer\r
//\r
IN ESL_IO_MGMT * pIo\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
+typedef\r
+EFI_STATUS\r
+(* PFN_API_VERIFY_LOCAL_IP_ADDRESS) (\r
+ IN ESL_PORT * pPort,\r
+ IN VOID * pConfigData\r
+ );\r
+\r
/**\r
Socket type control structure\r
\r
PFN_API_TRANSMIT pfnTransmit; ///< Attempt to buffer a packet for transmit\r
PFN_API_TX_COMPLETE pfnTxComplete; ///< TX completion for normal data\r
PFN_API_TX_COMPLETE pfnTxOobComplete; ///< TX completion for urgent data\r
+ PFN_API_VERIFY_LOCAL_IP_ADDRESS pfnVerifyLocalIpAddress; ///< Verify the local IP address\r
} ESL_PROTOCOL_API;\r
\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
+EslTcp4VerifyLocalIpAddress (\r
+ IN ESL_PORT * pPort,\r
+ IN EFI_TCP4_CONFIG_DATA * pConfigData\r
+ )\r
+{\r
+ UINTN DataSize;\r
+ EFI_TCP4_ACCESS_POINT * pAccess;\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
+ pAccess = &pConfigData->AccessPoint;\r
+ DEBUG (( DEBUG_BIND,\r
+ "UseDefaultAddress: %s\r\n",\r
+ pAccess->UseDefaultAddress ? L"TRUE" : L"FALSE" ));\r
+ DEBUG (( DEBUG_BIND,\r
+ "Requested IP address: %d.%d.%d.%d\r\n",\r
+ pAccess->StationAddress.Addr [ 0 ],\r
+ pAccess->StationAddress.Addr [ 1 ],\r
+ pAccess->StationAddress.Addr [ 2 ],\r
+ pAccess->StationAddress.Addr [ 3 ]));\r
+ if ( pAccess->UseDefaultAddress\r
+ || (( 0 == pAccess->StationAddress.Addr [ 0 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 1 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 2 ])\r
+ && ( 0 == pAccess->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 (( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])\r
+ && ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])\r
+ && ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])\r
+ && ( pAccess->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_STREAM and SOCK_SEQPACKET sockets\r
EslTcp4RxStart,\r
EslTcp4TxBuffer,\r
EslTcp4TxComplete,\r
- EslTcp4TxOobComplete\r
+ EslTcp4TxOobComplete,\r
+ EslTcp4VerifyLocalIpAddress\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
+EslTcp6VerifyLocalIpAddress (\r
+ IN ESL_PORT * pPort,\r
+ IN EFI_TCP6_CONFIG_DATA * pConfigData\r
+ )\r
+{\r
+ UINTN AddressCount;\r
+ EFI_IP6_ADDRESS_INFO * pAddressInfo;\r
+ UINTN DataSize;\r
+ EFI_TCP6_ACCESS_POINT * pAccess;\r
+ EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;\r
+ EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;\r
+ ESL_SERVICE * pService;\r
+ EFI_STATUS Status;\r
+\r
+ DBG_ENTER ( );\r
+\r
+ //\r
+ // Use break instead of goto\r
+ //\r
+ pIpConfigData = NULL;\r
+ for ( ; ; ) {\r
+ //\r
+ // Determine if the IP address is specified\r
+ //\r
+ pAccess = &pConfigData->AccessPoint;\r
+ DEBUG (( DEBUG_BIND,\r
+ "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+ pAccess->StationAddress.Addr[0],\r
+ pAccess->StationAddress.Addr[1],\r
+ pAccess->StationAddress.Addr[2],\r
+ pAccess->StationAddress.Addr[3],\r
+ pAccess->StationAddress.Addr[4],\r
+ pAccess->StationAddress.Addr[5],\r
+ pAccess->StationAddress.Addr[6],\r
+ pAccess->StationAddress.Addr[7],\r
+ pAccess->StationAddress.Addr[8],\r
+ pAccess->StationAddress.Addr[9],\r
+ pAccess->StationAddress.Addr[10],\r
+ pAccess->StationAddress.Addr[11],\r
+ pAccess->StationAddress.Addr[12],\r
+ pAccess->StationAddress.Addr[13],\r
+ pAccess->StationAddress.Addr[14],\r
+ pAccess->StationAddress.Addr[15]));\r
+ if (( 0 == pAccess->StationAddress.Addr [ 0 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 1 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 2 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 3 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 4 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 5 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 6 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 7 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 8 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 9 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 10 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 11 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 12 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 13 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 14 ])\r
+ && ( 0 == pAccess->StationAddress.Addr [ 15 ]))\r
+ {\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Open the configuration protocol\r
+ //\r
+ pService = pPort->pService;\r
+ Status = gBS->OpenProtocol ( pService->Controller,\r
+ &gEfiIp6ConfigProtocolGuid,\r
+ (VOID **)&pIpConfigProtocol,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the IP configuration data size\r
+ //\r
+ DataSize = 0;\r
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+ Ip6ConfigDataTypeInterfaceInfo,\r
+ &DataSize,\r
+ NULL );\r
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Allocate the configuration data buffer\r
+ //\r
+ pIpConfigData = AllocatePool ( DataSize );\r
+ if ( NULL == pIpConfigData ) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the IP configuration\r
+ //\r
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+ Ip6ConfigDataTypeInterfaceInfo,\r
+ &DataSize,\r
+ pIpConfigData );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Display the current configuration\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+ pIpConfigData->HwAddress.Addr [ 0 ],\r
+ pIpConfigData->HwAddress.Addr [ 1 ],\r
+ pIpConfigData->HwAddress.Addr [ 2 ],\r
+ pIpConfigData->HwAddress.Addr [ 3 ],\r
+ pIpConfigData->HwAddress.Addr [ 4 ],\r
+ pIpConfigData->HwAddress.Addr [ 5 ],\r
+ pIpConfigData->HwAddress.Addr [ 6 ],\r
+ pIpConfigData->HwAddress.Addr [ 7 ],\r
+ pIpConfigData->HwAddress.Addr [ 8 ],\r
+ pIpConfigData->HwAddress.Addr [ 9 ],\r
+ pIpConfigData->HwAddress.Addr [ 10 ],\r
+ pIpConfigData->HwAddress.Addr [ 11 ],\r
+ pIpConfigData->HwAddress.Addr [ 12 ],\r
+ pIpConfigData->HwAddress.Addr [ 13 ],\r
+ pIpConfigData->HwAddress.Addr [ 14 ],\r
+ pIpConfigData->HwAddress.Addr [ 15 ]));\r
+\r
+ //\r
+ // Validate the hardware address\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ if (( 16 == pIpConfigData->HwAddressSize )\r
+ && ( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])\r
+ && ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])\r
+ && ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])\r
+ && ( pAccess->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])\r
+ && ( pAccess->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])\r
+ && ( pAccess->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])\r
+ && ( pAccess->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])\r
+ && ( pAccess->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])\r
+ && ( pAccess->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])\r
+ && ( pAccess->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])\r
+ && ( pAccess->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])\r
+ && ( pAccess->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])\r
+ && ( pAccess->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])\r
+ && ( pAccess->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])\r
+ && ( pAccess->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])\r
+ && ( pAccess->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Walk the list of other IP addresses assigned to this adapter\r
+ //\r
+ for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {\r
+ pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];\r
+\r
+ //\r
+ // Display the IP address\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+ pAddressInfo->Address.Addr [ 0 ],\r
+ pAddressInfo->Address.Addr [ 1 ],\r
+ pAddressInfo->Address.Addr [ 2 ],\r
+ pAddressInfo->Address.Addr [ 3 ],\r
+ pAddressInfo->Address.Addr [ 4 ],\r
+ pAddressInfo->Address.Addr [ 5 ],\r
+ pAddressInfo->Address.Addr [ 6 ],\r
+ pAddressInfo->Address.Addr [ 7 ],\r
+ pAddressInfo->Address.Addr [ 8 ],\r
+ pAddressInfo->Address.Addr [ 9 ],\r
+ pAddressInfo->Address.Addr [ 10 ],\r
+ pAddressInfo->Address.Addr [ 11 ],\r
+ pAddressInfo->Address.Addr [ 12 ],\r
+ pAddressInfo->Address.Addr [ 13 ],\r
+ pAddressInfo->Address.Addr [ 14 ],\r
+ pAddressInfo->Address.Addr [ 15 ]));\r
+\r
+ //\r
+ // Validate the IP address\r
+ //\r
+ if (( pAccess->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])\r
+ && ( pAccess->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])\r
+ && ( pAccess->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])\r
+ && ( pAccess->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])\r
+ && ( pAccess->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])\r
+ && ( pAccess->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])\r
+ && ( pAccess->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])\r
+ && ( pAccess->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])\r
+ && ( pAccess->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])\r
+ && ( pAccess->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])\r
+ && ( pAccess->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])\r
+ && ( pAccess->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])\r
+ && ( pAccess->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])\r
+ && ( pAccess->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])\r
+ && ( pAccess->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])\r
+ && ( pAccess->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {\r
+ break;\r
+ }\r
+ }\r
+ if ( pIpConfigData->AddressInfoCount > AddressCount ) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // The IP address did not match\r
+ //\r
+ Status = EFI_NOT_STARTED;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Free the buffer if necessary\r
+ //\r
+ if ( NULL != pIpConfigData ) {\r
+ FreePool ( pIpConfigData );\r
+ }\r
+\r
+ //\r
+ // Return the IP address status\r
+ //\r
+ DBG_EXIT_STATUS ( Status );\r
+ return Status;\r
+}\r
+\r
+\r
/**\r
Interface between the socket layer and the network specific\r
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets\r
EslTcp6RxStart,\r
EslTcp6TxBuffer,\r
EslTcp6TxComplete,\r
- EslTcp6TxOobComplete\r
+ EslTcp6TxOobComplete,\r
+ EslTcp6VerifyLocalIpAddress\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 %s bytes from 0x%08x\r\n",\r
- BufferLength,\r
- pBuffer ));\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 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
- // 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
+ pPacket = pSocket->pTxPacketListHead;\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
- break;\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
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
}\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_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_DGRAM sockets over UDPv4.\r
NULL, // RxStart\r
EslUdp4TxBuffer,\r
EslUdp4TxComplete,\r
- NULL // TxOobComplete\r
+ NULL, // TxOobComplete\r
+ EslUdp4VerifyLocalIpAddress\r
};\r
pUdp6Protocol = pPort->pProtocol.UDPv6;\r
pConfigData = &pUdp6->ConfigData;\r
DEBUG (( DEBUG_TX,\r
- "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
+ "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",\r
pPort,\r
pConfigData->StationAddress.Addr[0],\r
pConfigData->StationAddress.Addr[1],\r
pConfigData->StationAddress.Addr[13],\r
pConfigData->StationAddress.Addr[14],\r
pConfigData->StationAddress.Addr[15],\r
- pConfigData->StationPort,\r
+ pConfigData->StationPort ));\r
+ DEBUG (( DEBUG_TX,\r
+ "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
pConfigData->RemoteAddress.Addr[0],\r
pConfigData->RemoteAddress.Addr[1],\r
pConfigData->RemoteAddress.Addr[2],\r
}\r
else {\r
DEBUG (( DEBUG_TX,\r
- "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
+ "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",\r
pPort,\r
pConfigData->StationAddress.Addr[0],\r
pConfigData->StationAddress.Addr[1],\r
pConfigData->StationAddress.Addr[13],\r
pConfigData->StationAddress.Addr[14],\r
pConfigData->StationAddress.Addr[15],\r
- pConfigData->StationPort,\r
+ pConfigData->StationPort ));\r
+ DEBUG (( DEBUG_TX,\r
+ "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
pConfigData->RemoteAddress.Addr[0],\r
pConfigData->RemoteAddress.Addr[1],\r
pConfigData->RemoteAddress.Addr[2],\r
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 %s bytes from 0x%08x\r\n",\r
- BufferLength,\r
- pBuffer ));\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 to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
+ BufferLength,\r
+ pBuffer,\r
+ pTxData->Session.DestinationAddress.Addr[0],\r
+ pTxData->Session.DestinationAddress.Addr[1],\r
+ pTxData->Session.DestinationAddress.Addr[2],\r
+ pTxData->Session.DestinationAddress.Addr[3],\r
+ pTxData->Session.DestinationAddress.Addr[4],\r
+ pTxData->Session.DestinationAddress.Addr[5],\r
+ pTxData->Session.DestinationAddress.Addr[6],\r
+ pTxData->Session.DestinationAddress.Addr[7],\r
+ pTxData->Session.DestinationAddress.Addr[8],\r
+ pTxData->Session.DestinationAddress.Addr[9],\r
+ pTxData->Session.DestinationAddress.Addr[10],\r
+ pTxData->Session.DestinationAddress.Addr[11],\r
+ pTxData->Session.DestinationAddress.Addr[12],\r
+ pTxData->Session.DestinationAddress.Addr[13],\r
+ pTxData->Session.DestinationAddress.Addr[14],\r
+ pTxData->Session.DestinationAddress.Addr[15],\r
+ pTxData->Session.DestinationPort ));\r
\r
- //\r
- // 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
- break;\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
pSocket->TxBytes -= LengthInBytes;\r
Status = pIo->Token.Udp6Tx.Status;\r
\r
+ //\r
+ // Ignore the transmit error\r
+ //\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_TX,\r
+ "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",\r
+ pPort,\r
+ pPacket,\r
+ Status ));\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
//\r
// Complete the transmit operation\r
//\r
}\r
\r
\r
+/**\r
+ Verify the adapter's IP address\r
+\r
+ This support routine is called by EslSocketBindTest.\r
+\r
+ @param [in] pPort Address of an ::ESL_PORT structure.\r
+ @param [in] pConfigData Address of the configuration data\r
+\r
+ @retval EFI_SUCCESS - The IP address is valid\r
+ @retval EFI_NOT_STARTED - The IP address is invalid\r
+\r
+ **/\r
+EFI_STATUS\r
+EslUdp6VerifyLocalIpAddress (\r
+ IN ESL_PORT * pPort,\r
+ IN EFI_UDP6_CONFIG_DATA * pConfigData\r
+ )\r
+{\r
+ UINTN AddressCount;\r
+ EFI_IP6_ADDRESS_INFO * pAddressInfo;\r
+ UINTN DataSize;\r
+ EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;\r
+ EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;\r
+ ESL_SERVICE * pService;\r
+ EFI_STATUS Status;\r
+\r
+ DBG_ENTER ( );\r
+\r
+ //\r
+ // Use break instead of goto\r
+ //\r
+ pIpConfigData = NULL;\r
+ for ( ; ; ) {\r
+ //\r
+ // Determine if the IP address is specified\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+ pConfigData->StationAddress.Addr[0],\r
+ pConfigData->StationAddress.Addr[1],\r
+ pConfigData->StationAddress.Addr[2],\r
+ pConfigData->StationAddress.Addr[3],\r
+ pConfigData->StationAddress.Addr[4],\r
+ pConfigData->StationAddress.Addr[5],\r
+ pConfigData->StationAddress.Addr[6],\r
+ pConfigData->StationAddress.Addr[7],\r
+ pConfigData->StationAddress.Addr[8],\r
+ pConfigData->StationAddress.Addr[9],\r
+ pConfigData->StationAddress.Addr[10],\r
+ pConfigData->StationAddress.Addr[11],\r
+ pConfigData->StationAddress.Addr[12],\r
+ pConfigData->StationAddress.Addr[13],\r
+ pConfigData->StationAddress.Addr[14],\r
+ pConfigData->StationAddress.Addr[15]));\r
+ if (( 0 == pConfigData->StationAddress.Addr [ 0 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 1 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 2 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 3 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 4 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 5 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 6 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 7 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 8 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 9 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 10 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 11 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 12 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 13 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 14 ])\r
+ && ( 0 == pConfigData->StationAddress.Addr [ 15 ]))\r
+ {\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Open the configuration protocol\r
+ //\r
+ pService = pPort->pService;\r
+ Status = gBS->OpenProtocol ( pService->Controller,\r
+ &gEfiIp6ConfigProtocolGuid,\r
+ (VOID **)&pIpConfigProtocol,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the IP configuration data size\r
+ //\r
+ DataSize = 0;\r
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+ Ip6ConfigDataTypeInterfaceInfo,\r
+ &DataSize,\r
+ NULL );\r
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Allocate the configuration data buffer\r
+ //\r
+ pIpConfigData = AllocatePool ( DataSize );\r
+ if ( NULL == pIpConfigData ) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the IP configuration\r
+ //\r
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+ Ip6ConfigDataTypeInterfaceInfo,\r
+ &DataSize,\r
+ pIpConfigData );\r
+ if ( EFI_ERROR ( Status )) {\r
+ DEBUG (( DEBUG_ERROR,\r
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",\r
+ Status ));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Display the current configuration\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+ pIpConfigData->HwAddress.Addr [ 0 ],\r
+ pIpConfigData->HwAddress.Addr [ 1 ],\r
+ pIpConfigData->HwAddress.Addr [ 2 ],\r
+ pIpConfigData->HwAddress.Addr [ 3 ],\r
+ pIpConfigData->HwAddress.Addr [ 4 ],\r
+ pIpConfigData->HwAddress.Addr [ 5 ],\r
+ pIpConfigData->HwAddress.Addr [ 6 ],\r
+ pIpConfigData->HwAddress.Addr [ 7 ],\r
+ pIpConfigData->HwAddress.Addr [ 8 ],\r
+ pIpConfigData->HwAddress.Addr [ 9 ],\r
+ pIpConfigData->HwAddress.Addr [ 10 ],\r
+ pIpConfigData->HwAddress.Addr [ 11 ],\r
+ pIpConfigData->HwAddress.Addr [ 12 ],\r
+ pIpConfigData->HwAddress.Addr [ 13 ],\r
+ pIpConfigData->HwAddress.Addr [ 14 ],\r
+ pIpConfigData->HwAddress.Addr [ 15 ]));\r
+\r
+ //\r
+ // Validate the hardware address\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ if (( 16 == pIpConfigData->HwAddressSize )\r
+ && ( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])\r
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])\r
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])\r
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])\r
+ && ( pConfigData->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])\r
+ && ( pConfigData->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])\r
+ && ( pConfigData->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])\r
+ && ( pConfigData->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])\r
+ && ( pConfigData->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])\r
+ && ( pConfigData->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])\r
+ && ( pConfigData->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])\r
+ && ( pConfigData->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])\r
+ && ( pConfigData->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])\r
+ && ( pConfigData->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])\r
+ && ( pConfigData->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])\r
+ && ( pConfigData->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Walk the list of other IP addresses assigned to this adapter\r
+ //\r
+ for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {\r
+ pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];\r
+\r
+ //\r
+ // Display the IP address\r
+ //\r
+ DEBUG (( DEBUG_BIND,\r
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+ pAddressInfo->Address.Addr [ 0 ],\r
+ pAddressInfo->Address.Addr [ 1 ],\r
+ pAddressInfo->Address.Addr [ 2 ],\r
+ pAddressInfo->Address.Addr [ 3 ],\r
+ pAddressInfo->Address.Addr [ 4 ],\r
+ pAddressInfo->Address.Addr [ 5 ],\r
+ pAddressInfo->Address.Addr [ 6 ],\r
+ pAddressInfo->Address.Addr [ 7 ],\r
+ pAddressInfo->Address.Addr [ 8 ],\r
+ pAddressInfo->Address.Addr [ 9 ],\r
+ pAddressInfo->Address.Addr [ 10 ],\r
+ pAddressInfo->Address.Addr [ 11 ],\r
+ pAddressInfo->Address.Addr [ 12 ],\r
+ pAddressInfo->Address.Addr [ 13 ],\r
+ pAddressInfo->Address.Addr [ 14 ],\r
+ pAddressInfo->Address.Addr [ 15 ]));\r
+\r
+ //\r
+ // Validate the IP address\r
+ //\r
+ if (( pConfigData->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])\r
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])\r
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])\r
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])\r
+ && ( pConfigData->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])\r
+ && ( pConfigData->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])\r
+ && ( pConfigData->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])\r
+ && ( pConfigData->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])\r
+ && ( pConfigData->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])\r
+ && ( pConfigData->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])\r
+ && ( pConfigData->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])\r
+ && ( pConfigData->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])\r
+ && ( pConfigData->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])\r
+ && ( pConfigData->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])\r
+ && ( pConfigData->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])\r
+ && ( pConfigData->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {\r
+ break;\r
+ }\r
+ }\r
+ if ( pIpConfigData->AddressInfoCount > AddressCount ) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // The IP address did not match\r
+ //\r
+ Status = EFI_NOT_STARTED;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Free the buffer if necessary\r
+ //\r
+ if ( NULL != pIpConfigData ) {\r
+ FreePool ( pIpConfigData );\r
+ }\r
+\r
+ //\r
+ // Return the IP address status\r
+ //\r
+ DBG_EXIT_STATUS ( Status );\r
+ return Status;\r
+}\r
+\r
+\r
/**\r
Interface between the socket layer and the network specific\r
code that supports SOCK_DGRAM sockets over UDPv4.\r
NULL, // RxStart\r
EslUdp6TxBuffer,\r
EslUdp6TxComplete,\r
- NULL // TxOobComplete\r
+ NULL, // TxOobComplete\r
+ EslUdp6VerifyLocalIpAddress\r
};\r
#include <Library/UefiLib.h>\r
\r
#include <Protocol/EfiSocket.h>\r
+#include <Protocol/Ip4Config.h>\r
+#include <Protocol/Ip6Config.h>\r
#include <Protocol/ServiceBinding.h>\r
#include <Protocol/Tcp4.h>\r
#include <Protocol/Tcp6.h>\r