Ignore transmit errors for UDPv4, UDPv6 and IPv4.

Support local bind by validating the IP address using the IP configuration protocol.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-by: Ankit Singh3 <Ankit_Singh3@Dell.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14875 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Lee Leahy 2013-11-20 18:31:01 +00:00 committed by lpleahy
parent f79868cd18
commit 2dc09dd50f
9 changed files with 1238 additions and 175 deletions

View File

@ -52,6 +52,8 @@
UefiLib UefiLib
[Protocols] [Protocols]
gEfiIp4ConfigProtocolGuid
gEfiIp6ConfigProtocolGuid
gEfiIp4ProtocolGuid gEfiIp4ProtocolGuid
gEfiIp4ServiceBindingProtocolGuid gEfiIp4ServiceBindingProtocolGuid
gEfiIp6ProtocolGuid gEfiIp6ProtocolGuid

View File

@ -1067,71 +1067,64 @@ EslIp4TxBuffer (
RAISE_TPL ( TplPrevious, TPL_SOCKETS ); RAISE_TPL ( TplPrevious, TPL_SOCKETS );
// //
// Stop transmission after an error // Display the request
// //
if ( !EFI_ERROR ( pSocket->TxError )) { DEBUG (( DEBUG_TX,
// "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
// Display the request BufferLength,
// pBuffer,
DEBUG (( DEBUG_TX, pIp4->ModeData.ConfigData.StationAddress.Addr[0],
"Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n", pIp4->ModeData.ConfigData.StationAddress.Addr[1],
BufferLength, pIp4->ModeData.ConfigData.StationAddress.Addr[2],
pBuffer, pIp4->ModeData.ConfigData.StationAddress.Addr[3],
pIp4->ModeData.ConfigData.StationAddress.Addr[0], pTxData->TxData.DestinationAddress.Addr[0],
pIp4->ModeData.ConfigData.StationAddress.Addr[1], pTxData->TxData.DestinationAddress.Addr[1],
pIp4->ModeData.ConfigData.StationAddress.Addr[2], pTxData->TxData.DestinationAddress.Addr[2],
pIp4->ModeData.ConfigData.StationAddress.Addr[3], pTxData->TxData.DestinationAddress.Addr[3]));
pTxData->TxData.DestinationAddress.Addr[0],
pTxData->TxData.DestinationAddress.Addr[1],
pTxData->TxData.DestinationAddress.Addr[2],
pTxData->TxData.DestinationAddress.Addr[3]));
// //
// Queue the data for transmission // Queue the data for transmission
// //
pPacket->pNext = NULL; pPacket->pNext = NULL;
pPreviousPacket = pSocket->pTxPacketListTail; pPreviousPacket = pSocket->pTxPacketListTail;
if ( NULL == pPreviousPacket ) { if ( NULL == pPreviousPacket ) {
pSocket->pTxPacketListHead = pPacket; pSocket->pTxPacketListHead = pPacket;
}
else {
pPreviousPacket->pNext = pPacket;
}
pSocket->pTxPacketListTail = pPacket;
DEBUG (( DEBUG_TX,
"0x%08x: Packet on transmit list\r\n",
pPacket ));
//
// Account for the buffered data
//
*pTxBytes += BufferLength;
*pDataLength = BufferLength;
//
// Start the transmit engine if it is idle
//
if ( NULL != pPort->pTxFree ) {
EslSocketTxStart ( pPort,
&pSocket->pTxPacketListHead,
&pSocket->pTxPacketListTail,
&pPort->pTxActive,
&pPort->pTxFree );
}
} }
else { else {
// pPreviousPacket->pNext = pPacket;
// Previous transmit error }
// Stop transmission pSocket->pTxPacketListTail = pPacket;
// DEBUG (( DEBUG_TX,
Status = pSocket->TxError; "0x%08x: Packet on transmit list\r\n",
pSocket->errno = EIO; pPacket ));
//
// Account for the buffered data
//
*pTxBytes += BufferLength;
*pDataLength = BufferLength;
//
// Start the transmit engine if it is idle
//
if ( NULL != pPort->pTxFree ) {
EslSocketTxStart ( pPort,
&pSocket->pTxPacketListHead,
&pSocket->pTxPacketListTail,
&pPort->pTxActive,
&pPort->pTxFree );
// //
// Free the packet // Ignore any transmit error
// //
EslSocketPacketFree ( pPacket, DEBUG_TX ); if ( EFI_ERROR ( pSocket->TxError )) {
break; DEBUG (( DEBUG_TX,
"0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
pPort,
pPacket,
pSocket->TxError ));
}
pSocket->TxError = EFI_SUCCESS;
} }
// //
@ -1212,6 +1205,18 @@ EslIp4TxComplete (
pSocket->TxBytes -= LengthInBytes; pSocket->TxBytes -= LengthInBytes;
Status = pIo->Token.Ip4Tx.Status; Status = pIo->Token.Ip4Tx.Status;
//
// Ignore the transmit error
//
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_TX,
"0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
pPort,
pPacket,
Status ));
Status = EFI_SUCCESS;
}
// //
// Complete the transmit operation // Complete the transmit operation
// //
@ -1227,6 +1232,157 @@ EslIp4TxComplete (
} }
/**
Verify the adapter's IP address
This support routine is called by EslSocketBindTest.
@param [in] pPort Address of an ::ESL_PORT structure.
@param [in] pConfigData Address of the configuration data
@retval EFI_SUCCESS - The IP address is valid
@retval EFI_NOT_STARTED - The IP address is invalid
**/
EFI_STATUS
EslIp4VerifyLocalIpAddress (
IN ESL_PORT * pPort,
IN EFI_IP4_CONFIG_DATA * pConfigData
)
{
UINTN DataSize;
EFI_IP4_IPCONFIG_DATA * pIpConfigData;
EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
ESL_SERVICE * pService;
EFI_STATUS Status;
DBG_ENTER ( );
//
// Use break instead of goto
//
pIpConfigData = NULL;
for ( ; ; ) {
//
// Determine if the IP address is specified
//
DEBUG (( DEBUG_BIND,
"UseDefaultAddress: %s\r\n",
pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
DEBUG (( DEBUG_BIND,
"Requested IP address: %d.%d.%d.%d\r\n",
pConfigData->StationAddress.Addr [ 0 ],
pConfigData->StationAddress.Addr [ 1 ],
pConfigData->StationAddress.Addr [ 2 ],
pConfigData->StationAddress.Addr [ 3 ]));
if ( pConfigData->UseDefaultAddress
|| (( 0 == pConfigData->StationAddress.Addr [ 0 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 1 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 2 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 3 ])))
{
Status = EFI_SUCCESS;
break;
}
//
// Open the configuration protocol
//
pService = pPort->pService;
Status = gBS->OpenProtocol ( pService->Controller,
&gEfiIp4ConfigProtocolGuid,
(VOID **)&pIpConfigProtocol,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - IP Configuration Protocol not available, Status: %r\r\n",
Status ));
break;
}
//
// Get the IP configuration data size
//
DataSize = 0;
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
&DataSize,
NULL );
if ( EFI_BUFFER_TOO_SMALL != Status ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
Status ));
break;
}
//
// Allocate the configuration data buffer
//
pIpConfigData = AllocatePool ( DataSize );
if ( NULL == pIpConfigData ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
Status = EFI_OUT_OF_RESOURCES;
break;
}
//
// Get the IP configuration
//
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
&DataSize,
pIpConfigData );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to return IP Configuration data, Status: %r\r\n",
Status ));
break;
}
//
// Display the current configuration
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %d.%d.%d.%d\r\n",
pIpConfigData->StationAddress.Addr [ 0 ],
pIpConfigData->StationAddress.Addr [ 1 ],
pIpConfigData->StationAddress.Addr [ 2 ],
pIpConfigData->StationAddress.Addr [ 3 ]));
//
// Assume the port is not configured
//
Status = EFI_SUCCESS;
if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
&& ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
&& ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
&& ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
break;
}
//
// The IP address did not match
//
Status = EFI_NOT_STARTED;
break;
}
//
// Free the buffer if necessary
//
if ( NULL != pIpConfigData ) {
FreePool ( pIpConfigData );
}
//
// Return the IP address status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/** /**
Interface between the socket layer and the network specific Interface between the socket layer and the network specific
code that supports SOCK_RAW sockets over IPv4. code that supports SOCK_RAW sockets over IPv4.
@ -1265,5 +1421,6 @@ CONST ESL_PROTOCOL_API cEslIp4Api = {
NULL, // RxStart NULL, // RxStart
EslIp4TxBuffer, EslIp4TxBuffer,
EslIp4TxComplete, EslIp4TxComplete,
NULL // TxOobComplete NULL, // TxOobComplete
EslIp4VerifyLocalIpAddress
}; };

View File

@ -1336,27 +1336,40 @@ EslSocketBindTest (
pConfigData = (VOID *)pBuffer; pConfigData = (VOID *)pBuffer;
// //
// Attempt to use this configuration // Validate that the port is connected
// //
Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData ); Status = pPort->pSocket->pApi->pfnVerifyLocalIpAddress ( pPort, pBuffer );
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_WARN | DEBUG_BIND, DEBUG (( DEBUG_WARN | DEBUG_BIND,
"WARNING - Port 0x%08x failed configuration, Status: %r\r\n", "WARNING - Port 0x%08x invalid IP address: %r\r\n",
pPort, pPort,
Status )); Status ));
pPort->pSocket->errno = ErrnoValue; pPort->pSocket->errno = ErrnoValue;
} }
else { else {
// //
// Reset the port // Attempt to use this configuration
// //
Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL ); Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR | DEBUG_BIND, DEBUG (( DEBUG_WARN | DEBUG_BIND,
"ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n", "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",
pPort, pPort,
Status )); Status ));
ASSERT ( EFI_SUCCESS == Status ); pPort->pSocket->errno = ErrnoValue;
}
else {
//
// Reset the port
//
Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR | DEBUG_BIND,
"ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",
pPort,
Status ));
ASSERT ( EFI_SUCCESS == Status );
}
} }
} }
@ -5924,10 +5937,24 @@ EslSocketTxStart (
*ppActive = pIo; *ppActive = pIo;
} }
else { else {
//
// Display the transmit error
//
DEBUG (( DEBUG_TX | DEBUG_INFO,
"0x%08x, 0x%08x: pIo, pPacket transmit failure: %r\r\n",
pIo,
pPacket,
Status ));
if ( EFI_SUCCESS == pSocket->TxError ) { if ( EFI_SUCCESS == pSocket->TxError ) {
pSocket->TxError = Status; pSocket->TxError = Status;
} }
//
// Free the IO structure
//
pIo->pNext = *ppFree;
*ppFree = pIo;
// //
// Discard the transmit buffer // Discard the transmit buffer
// //

View File

@ -920,6 +920,25 @@ VOID
IN ESL_IO_MGMT * pIo IN ESL_IO_MGMT * pIo
); );
/**
Verify the adapter's IP address
This support routine is called by EslSocketBindTest.
@param [in] pPort Address of an ::ESL_PORT structure.
@param [in] pConfigData Address of the configuration data
@retval EFI_SUCCESS - The IP address is valid
@retval EFI_NOT_STARTED - The IP address is invalid
**/
typedef
EFI_STATUS
(* PFN_API_VERIFY_LOCAL_IP_ADDRESS) (
IN ESL_PORT * pPort,
IN VOID * pConfigData
);
/** /**
Socket type control structure Socket type control structure
@ -960,6 +979,7 @@ typedef struct {
PFN_API_TRANSMIT pfnTransmit; ///< Attempt to buffer a packet for transmit PFN_API_TRANSMIT pfnTransmit; ///< Attempt to buffer a packet for transmit
PFN_API_TX_COMPLETE pfnTxComplete; ///< TX completion for normal data PFN_API_TX_COMPLETE pfnTxComplete; ///< TX completion for normal data
PFN_API_TX_COMPLETE pfnTxOobComplete; ///< TX completion for urgent data PFN_API_TX_COMPLETE pfnTxOobComplete; ///< TX completion for urgent data
PFN_API_VERIFY_LOCAL_IP_ADDRESS pfnVerifyLocalIpAddress; ///< Verify the local IP address
} ESL_PROTOCOL_API; } ESL_PROTOCOL_API;

View File

@ -2225,6 +2225,159 @@ EslTcp4TxOobComplete (
} }
/**
Verify the adapter's IP address
This support routine is called by EslSocketBindTest.
@param [in] pPort Address of an ::ESL_PORT structure.
@param [in] pConfigData Address of the configuration data
@retval EFI_SUCCESS - The IP address is valid
@retval EFI_NOT_STARTED - The IP address is invalid
**/
EFI_STATUS
EslTcp4VerifyLocalIpAddress (
IN ESL_PORT * pPort,
IN EFI_TCP4_CONFIG_DATA * pConfigData
)
{
UINTN DataSize;
EFI_TCP4_ACCESS_POINT * pAccess;
EFI_IP4_IPCONFIG_DATA * pIpConfigData;
EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
ESL_SERVICE * pService;
EFI_STATUS Status;
DBG_ENTER ( );
//
// Use break instead of goto
//
pIpConfigData = NULL;
for ( ; ; ) {
//
// Determine if the IP address is specified
//
pAccess = &pConfigData->AccessPoint;
DEBUG (( DEBUG_BIND,
"UseDefaultAddress: %s\r\n",
pAccess->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
DEBUG (( DEBUG_BIND,
"Requested IP address: %d.%d.%d.%d\r\n",
pAccess->StationAddress.Addr [ 0 ],
pAccess->StationAddress.Addr [ 1 ],
pAccess->StationAddress.Addr [ 2 ],
pAccess->StationAddress.Addr [ 3 ]));
if ( pAccess->UseDefaultAddress
|| (( 0 == pAccess->StationAddress.Addr [ 0 ])
&& ( 0 == pAccess->StationAddress.Addr [ 1 ])
&& ( 0 == pAccess->StationAddress.Addr [ 2 ])
&& ( 0 == pAccess->StationAddress.Addr [ 3 ])))
{
Status = EFI_SUCCESS;
break;
}
//
// Open the configuration protocol
//
pService = pPort->pService;
Status = gBS->OpenProtocol ( pService->Controller,
&gEfiIp4ConfigProtocolGuid,
(VOID **)&pIpConfigProtocol,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - IP Configuration Protocol not available, Status: %r\r\n",
Status ));
break;
}
//
// Get the IP configuration data size
//
DataSize = 0;
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
&DataSize,
NULL );
if ( EFI_BUFFER_TOO_SMALL != Status ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
Status ));
break;
}
//
// Allocate the configuration data buffer
//
pIpConfigData = AllocatePool ( DataSize );
if ( NULL == pIpConfigData ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
Status = EFI_OUT_OF_RESOURCES;
break;
}
//
// Get the IP configuration
//
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
&DataSize,
pIpConfigData );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to return IP Configuration data, Status: %r\r\n",
Status ));
break;
}
//
// Display the current configuration
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %d.%d.%d.%d\r\n",
pIpConfigData->StationAddress.Addr [ 0 ],
pIpConfigData->StationAddress.Addr [ 1 ],
pIpConfigData->StationAddress.Addr [ 2 ],
pIpConfigData->StationAddress.Addr [ 3 ]));
//
// Assume the port is not configured
//
Status = EFI_SUCCESS;
if (( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
&& ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
&& ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
&& ( pAccess->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
break;
}
//
// The IP address did not match
//
Status = EFI_NOT_STARTED;
break;
}
//
// Free the buffer if necessary
//
if ( NULL != pIpConfigData ) {
FreePool ( pIpConfigData );
}
//
// Return the IP address status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/** /**
Interface between the socket layer and the network specific Interface between the socket layer and the network specific
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets code that supports SOCK_STREAM and SOCK_SEQPACKET sockets
@ -2264,5 +2417,6 @@ CONST ESL_PROTOCOL_API cEslTcp4Api = {
EslTcp4RxStart, EslTcp4RxStart,
EslTcp4TxBuffer, EslTcp4TxBuffer,
EslTcp4TxComplete, EslTcp4TxComplete,
EslTcp4TxOobComplete EslTcp4TxOobComplete,
EslTcp4VerifyLocalIpAddress
}; };

View File

@ -2294,6 +2294,262 @@ EslTcp6TxOobComplete (
} }
/**
Verify the adapter's IP address
This support routine is called by EslSocketBindTest.
@param [in] pPort Address of an ::ESL_PORT structure.
@param [in] pConfigData Address of the configuration data
@retval EFI_SUCCESS - The IP address is valid
@retval EFI_NOT_STARTED - The IP address is invalid
**/
EFI_STATUS
EslTcp6VerifyLocalIpAddress (
IN ESL_PORT * pPort,
IN EFI_TCP6_CONFIG_DATA * pConfigData
)
{
UINTN AddressCount;
EFI_IP6_ADDRESS_INFO * pAddressInfo;
UINTN DataSize;
EFI_TCP6_ACCESS_POINT * pAccess;
EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;
EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;
ESL_SERVICE * pService;
EFI_STATUS Status;
DBG_ENTER ( );
//
// Use break instead of goto
//
pIpConfigData = NULL;
for ( ; ; ) {
//
// Determine if the IP address is specified
//
pAccess = &pConfigData->AccessPoint;
DEBUG (( DEBUG_BIND,
"Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
pAccess->StationAddress.Addr[0],
pAccess->StationAddress.Addr[1],
pAccess->StationAddress.Addr[2],
pAccess->StationAddress.Addr[3],
pAccess->StationAddress.Addr[4],
pAccess->StationAddress.Addr[5],
pAccess->StationAddress.Addr[6],
pAccess->StationAddress.Addr[7],
pAccess->StationAddress.Addr[8],
pAccess->StationAddress.Addr[9],
pAccess->StationAddress.Addr[10],
pAccess->StationAddress.Addr[11],
pAccess->StationAddress.Addr[12],
pAccess->StationAddress.Addr[13],
pAccess->StationAddress.Addr[14],
pAccess->StationAddress.Addr[15]));
if (( 0 == pAccess->StationAddress.Addr [ 0 ])
&& ( 0 == pAccess->StationAddress.Addr [ 1 ])
&& ( 0 == pAccess->StationAddress.Addr [ 2 ])
&& ( 0 == pAccess->StationAddress.Addr [ 3 ])
&& ( 0 == pAccess->StationAddress.Addr [ 4 ])
&& ( 0 == pAccess->StationAddress.Addr [ 5 ])
&& ( 0 == pAccess->StationAddress.Addr [ 6 ])
&& ( 0 == pAccess->StationAddress.Addr [ 7 ])
&& ( 0 == pAccess->StationAddress.Addr [ 8 ])
&& ( 0 == pAccess->StationAddress.Addr [ 9 ])
&& ( 0 == pAccess->StationAddress.Addr [ 10 ])
&& ( 0 == pAccess->StationAddress.Addr [ 11 ])
&& ( 0 == pAccess->StationAddress.Addr [ 12 ])
&& ( 0 == pAccess->StationAddress.Addr [ 13 ])
&& ( 0 == pAccess->StationAddress.Addr [ 14 ])
&& ( 0 == pAccess->StationAddress.Addr [ 15 ]))
{
Status = EFI_SUCCESS;
break;
}
//
// Open the configuration protocol
//
pService = pPort->pService;
Status = gBS->OpenProtocol ( pService->Controller,
&gEfiIp6ConfigProtocolGuid,
(VOID **)&pIpConfigProtocol,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - IP Configuration Protocol not available, Status: %r\r\n",
Status ));
break;
}
//
// Get the IP configuration data size
//
DataSize = 0;
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
Ip6ConfigDataTypeInterfaceInfo,
&DataSize,
NULL );
if ( EFI_BUFFER_TOO_SMALL != Status ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
Status ));
break;
}
//
// Allocate the configuration data buffer
//
pIpConfigData = AllocatePool ( DataSize );
if ( NULL == pIpConfigData ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
Status = EFI_OUT_OF_RESOURCES;
break;
}
//
// Get the IP configuration
//
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
Ip6ConfigDataTypeInterfaceInfo,
&DataSize,
pIpConfigData );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to return IP Configuration data, Status: %r\r\n",
Status ));
break;
}
//
// Display the current configuration
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
pIpConfigData->HwAddress.Addr [ 0 ],
pIpConfigData->HwAddress.Addr [ 1 ],
pIpConfigData->HwAddress.Addr [ 2 ],
pIpConfigData->HwAddress.Addr [ 3 ],
pIpConfigData->HwAddress.Addr [ 4 ],
pIpConfigData->HwAddress.Addr [ 5 ],
pIpConfigData->HwAddress.Addr [ 6 ],
pIpConfigData->HwAddress.Addr [ 7 ],
pIpConfigData->HwAddress.Addr [ 8 ],
pIpConfigData->HwAddress.Addr [ 9 ],
pIpConfigData->HwAddress.Addr [ 10 ],
pIpConfigData->HwAddress.Addr [ 11 ],
pIpConfigData->HwAddress.Addr [ 12 ],
pIpConfigData->HwAddress.Addr [ 13 ],
pIpConfigData->HwAddress.Addr [ 14 ],
pIpConfigData->HwAddress.Addr [ 15 ]));
//
// Validate the hardware address
//
Status = EFI_SUCCESS;
if (( 16 == pIpConfigData->HwAddressSize )
&& ( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])
&& ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])
&& ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])
&& ( pAccess->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])
&& ( pAccess->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])
&& ( pAccess->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])
&& ( pAccess->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])
&& ( pAccess->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])
&& ( pAccess->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])
&& ( pAccess->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])
&& ( pAccess->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])
&& ( pAccess->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])
&& ( pAccess->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])
&& ( pAccess->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])
&& ( pAccess->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])
&& ( pAccess->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {
break;
}
//
// Walk the list of other IP addresses assigned to this adapter
//
for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {
pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];
//
// Display the IP address
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
pAddressInfo->Address.Addr [ 0 ],
pAddressInfo->Address.Addr [ 1 ],
pAddressInfo->Address.Addr [ 2 ],
pAddressInfo->Address.Addr [ 3 ],
pAddressInfo->Address.Addr [ 4 ],
pAddressInfo->Address.Addr [ 5 ],
pAddressInfo->Address.Addr [ 6 ],
pAddressInfo->Address.Addr [ 7 ],
pAddressInfo->Address.Addr [ 8 ],
pAddressInfo->Address.Addr [ 9 ],
pAddressInfo->Address.Addr [ 10 ],
pAddressInfo->Address.Addr [ 11 ],
pAddressInfo->Address.Addr [ 12 ],
pAddressInfo->Address.Addr [ 13 ],
pAddressInfo->Address.Addr [ 14 ],
pAddressInfo->Address.Addr [ 15 ]));
//
// Validate the IP address
//
if (( pAccess->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])
&& ( pAccess->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])
&& ( pAccess->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])
&& ( pAccess->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])
&& ( pAccess->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])
&& ( pAccess->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])
&& ( pAccess->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])
&& ( pAccess->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])
&& ( pAccess->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])
&& ( pAccess->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])
&& ( pAccess->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])
&& ( pAccess->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])
&& ( pAccess->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])
&& ( pAccess->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])
&& ( pAccess->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])
&& ( pAccess->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {
break;
}
}
if ( pIpConfigData->AddressInfoCount > AddressCount ) {
break;
}
//
// The IP address did not match
//
Status = EFI_NOT_STARTED;
break;
}
//
// Free the buffer if necessary
//
if ( NULL != pIpConfigData ) {
FreePool ( pIpConfigData );
}
//
// Return the IP address status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/** /**
Interface between the socket layer and the network specific Interface between the socket layer and the network specific
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets code that supports SOCK_STREAM and SOCK_SEQPACKET sockets
@ -2333,5 +2589,6 @@ CONST ESL_PROTOCOL_API cEslTcp6Api = {
EslTcp6RxStart, EslTcp6RxStart,
EslTcp6TxBuffer, EslTcp6TxBuffer,
EslTcp6TxComplete, EslTcp6TxComplete,
EslTcp6TxOobComplete EslTcp6TxOobComplete,
EslTcp6VerifyLocalIpAddress
}; };

View File

@ -867,63 +867,62 @@ EslUdp4TxBuffer (
RAISE_TPL ( TplPrevious, TPL_SOCKETS ); RAISE_TPL ( TplPrevious, TPL_SOCKETS );
// //
// Stop transmission after an error // Display the request
// //
if ( !EFI_ERROR ( pSocket->TxError )) { DEBUG (( DEBUG_TX,
// "Send %d bytes from 0x%08x to %d.%d.%d.%d:%d\r\n",
// Display the request BufferLength,
// pBuffer,
DEBUG (( DEBUG_TX, pTxData->Session.DestinationAddress.Addr[0],
"Send %d %s bytes from 0x%08x\r\n", pTxData->Session.DestinationAddress.Addr[1],
BufferLength, pTxData->Session.DestinationAddress.Addr[2],
pBuffer )); pTxData->Session.DestinationAddress.Addr[3],
pTxData->Session.DestinationPort ));
// //
// Queue the data for transmission // Queue the data for transmission
// //
pPacket->pNext = NULL; pPacket->pNext = NULL;
pPreviousPacket = pSocket->pTxPacketListTail; pPreviousPacket = pSocket->pTxPacketListTail;
if ( NULL == pPreviousPacket ) { if ( NULL == pPreviousPacket ) {
pSocket->pTxPacketListHead = pPacket; pSocket->pTxPacketListHead = pPacket;
}
else {
pPreviousPacket->pNext = pPacket;
}
pSocket->pTxPacketListTail = pPacket;
DEBUG (( DEBUG_TX,
"0x%08x: Packet on transmit list\r\n",
pPacket ));
//
// Account for the buffered data
//
*pTxBytes += BufferLength;
*pDataLength = BufferLength;
//
// Start the transmit engine if it is idle
//
if ( NULL != pPort->pTxFree ) {
EslSocketTxStart ( pPort,
&pSocket->pTxPacketListHead,
&pSocket->pTxPacketListTail,
&pPort->pTxActive,
&pPort->pTxFree );
}
} }
else { else {
// pPreviousPacket->pNext = pPacket;
// Previous transmit error }
// Stop transmission pSocket->pTxPacketListTail = pPacket;
// DEBUG (( DEBUG_TX,
Status = pSocket->TxError; "0x%08x: Packet on transmit list\r\n",
pSocket->errno = EIO; pPacket ));
//
// Account for the buffered data
//
*pTxBytes += BufferLength;
*pDataLength = BufferLength;
//
// Start the transmit engine if it is idle
//
if ( NULL != pPort->pTxFree ) {
pPacket = pSocket->pTxPacketListHead;
EslSocketTxStart ( pPort,
&pSocket->pTxPacketListHead,
&pSocket->pTxPacketListTail,
&pPort->pTxActive,
&pPort->pTxFree );
// //
// Free the packet // Ignore any transmit error
// //
EslSocketPacketFree ( pPacket, DEBUG_TX ); if ( EFI_ERROR ( pSocket->TxError )) {
break; DEBUG (( DEBUG_TX,
"0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
pPort,
pPacket,
pSocket->TxError ));
}
pSocket->TxError = EFI_SUCCESS;
} }
// //
@ -1004,6 +1003,18 @@ EslUdp4TxComplete (
pSocket->TxBytes -= LengthInBytes; pSocket->TxBytes -= LengthInBytes;
Status = pIo->Token.Udp4Tx.Status; Status = pIo->Token.Udp4Tx.Status;
//
// Ignore the transmit error
//
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_TX,
"0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
pPort,
pPacket,
Status ));
Status = EFI_SUCCESS;
}
// //
// Complete the transmit operation // Complete the transmit operation
// //
@ -1019,6 +1030,157 @@ EslUdp4TxComplete (
} }
/**
Verify the adapter's IP address
This support routine is called by EslSocketBindTest.
@param [in] pPort Address of an ::ESL_PORT structure.
@param [in] pConfigData Address of the configuration data
@retval EFI_SUCCESS - The IP address is valid
@retval EFI_NOT_STARTED - The IP address is invalid
**/
EFI_STATUS
EslUdp4VerifyLocalIpAddress (
IN ESL_PORT * pPort,
IN EFI_UDP4_CONFIG_DATA * pConfigData
)
{
UINTN DataSize;
EFI_IP4_IPCONFIG_DATA * pIpConfigData;
EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
ESL_SERVICE * pService;
EFI_STATUS Status;
DBG_ENTER ( );
//
// Use break instead of goto
//
pIpConfigData = NULL;
for ( ; ; ) {
//
// Determine if the IP address is specified
//
DEBUG (( DEBUG_BIND,
"UseDefaultAddress: %s\r\n",
pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
DEBUG (( DEBUG_BIND,
"Requested IP address: %d.%d.%d.%d\r\n",
pConfigData->StationAddress.Addr [ 0 ],
pConfigData->StationAddress.Addr [ 1 ],
pConfigData->StationAddress.Addr [ 2 ],
pConfigData->StationAddress.Addr [ 3 ]));
if ( pConfigData->UseDefaultAddress
|| (( 0 == pConfigData->StationAddress.Addr [ 0 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 1 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 2 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 3 ])))
{
Status = EFI_SUCCESS;
break;
}
//
// Open the configuration protocol
//
pService = pPort->pService;
Status = gBS->OpenProtocol ( pService->Controller,
&gEfiIp4ConfigProtocolGuid,
(VOID **)&pIpConfigProtocol,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - IP Configuration Protocol not available, Status: %r\r\n",
Status ));
break;
}
//
// Get the IP configuration data size
//
DataSize = 0;
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
&DataSize,
NULL );
if ( EFI_BUFFER_TOO_SMALL != Status ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
Status ));
break;
}
//
// Allocate the configuration data buffer
//
pIpConfigData = AllocatePool ( DataSize );
if ( NULL == pIpConfigData ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
Status = EFI_OUT_OF_RESOURCES;
break;
}
//
// Get the IP configuration
//
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
&DataSize,
pIpConfigData );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to return IP Configuration data, Status: %r\r\n",
Status ));
break;
}
//
// Display the current configuration
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %d.%d.%d.%d\r\n",
pIpConfigData->StationAddress.Addr [ 0 ],
pIpConfigData->StationAddress.Addr [ 1 ],
pIpConfigData->StationAddress.Addr [ 2 ],
pIpConfigData->StationAddress.Addr [ 3 ]));
//
// Assume the port is not configured
//
Status = EFI_SUCCESS;
if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
&& ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
&& ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
&& ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
break;
}
//
// The IP address did not match
//
Status = EFI_NOT_STARTED;
break;
}
//
// Free the buffer if necessary
//
if ( NULL != pIpConfigData ) {
FreePool ( pIpConfigData );
}
//
// Return the IP address status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/** /**
Interface between the socket layer and the network specific Interface between the socket layer and the network specific
code that supports SOCK_DGRAM sockets over UDPv4. code that supports SOCK_DGRAM sockets over UDPv4.
@ -1057,5 +1219,6 @@ CONST ESL_PROTOCOL_API cEslUdp4Api = {
NULL, // RxStart NULL, // RxStart
EslUdp4TxBuffer, EslUdp4TxBuffer,
EslUdp4TxComplete, EslUdp4TxComplete,
NULL // TxOobComplete NULL, // TxOobComplete
EslUdp4VerifyLocalIpAddress
}; };

View File

@ -609,7 +609,7 @@ EslUdp6RxComplete (
pUdp6Protocol = pPort->pProtocol.UDPv6; pUdp6Protocol = pPort->pProtocol.UDPv6;
pConfigData = &pUdp6->ConfigData; pConfigData = &pUdp6->ConfigData;
DEBUG (( DEBUG_TX, DEBUG (( DEBUG_TX,
"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", "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",
pPort, pPort,
pConfigData->StationAddress.Addr[0], pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1], pConfigData->StationAddress.Addr[1],
@ -627,7 +627,9 @@ EslUdp6RxComplete (
pConfigData->StationAddress.Addr[13], pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14], pConfigData->StationAddress.Addr[14],
pConfigData->StationAddress.Addr[15], pConfigData->StationAddress.Addr[15],
pConfigData->StationPort, pConfigData->StationPort ));
DEBUG (( DEBUG_TX,
"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pConfigData->RemoteAddress.Addr[0], pConfigData->RemoteAddress.Addr[0],
pConfigData->RemoteAddress.Addr[1], pConfigData->RemoteAddress.Addr[1],
pConfigData->RemoteAddress.Addr[2], pConfigData->RemoteAddress.Addr[2],
@ -692,7 +694,7 @@ EslUdp6RxComplete (
} }
else { else {
DEBUG (( DEBUG_TX, DEBUG (( DEBUG_TX,
"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", "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",
pPort, pPort,
pConfigData->StationAddress.Addr[0], pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1], pConfigData->StationAddress.Addr[1],
@ -710,7 +712,9 @@ EslUdp6RxComplete (
pConfigData->StationAddress.Addr[13], pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14], pConfigData->StationAddress.Addr[14],
pConfigData->StationAddress.Addr[15], pConfigData->StationAddress.Addr[15],
pConfigData->StationPort, pConfigData->StationPort ));
DEBUG (( DEBUG_TX,
"[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pConfigData->RemoteAddress.Addr[0], pConfigData->RemoteAddress.Addr[0],
pConfigData->RemoteAddress.Addr[1], pConfigData->RemoteAddress.Addr[1],
pConfigData->RemoteAddress.Addr[2], pConfigData->RemoteAddress.Addr[2],
@ -904,63 +908,73 @@ EslUdp6TxBuffer (
RAISE_TPL ( TplPrevious, TPL_SOCKETS ); RAISE_TPL ( TplPrevious, TPL_SOCKETS );
// //
// Stop transmission after an error // Display the request
// //
if ( !EFI_ERROR ( pSocket->TxError )) { DEBUG (( DEBUG_TX,
// "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",
// Display the request BufferLength,
// pBuffer,
DEBUG (( DEBUG_TX, pTxData->Session.DestinationAddress.Addr[0],
"Send %d %s bytes from 0x%08x\r\n", pTxData->Session.DestinationAddress.Addr[1],
BufferLength, pTxData->Session.DestinationAddress.Addr[2],
pBuffer )); pTxData->Session.DestinationAddress.Addr[3],
pTxData->Session.DestinationAddress.Addr[4],
pTxData->Session.DestinationAddress.Addr[5],
pTxData->Session.DestinationAddress.Addr[6],
pTxData->Session.DestinationAddress.Addr[7],
pTxData->Session.DestinationAddress.Addr[8],
pTxData->Session.DestinationAddress.Addr[9],
pTxData->Session.DestinationAddress.Addr[10],
pTxData->Session.DestinationAddress.Addr[11],
pTxData->Session.DestinationAddress.Addr[12],
pTxData->Session.DestinationAddress.Addr[13],
pTxData->Session.DestinationAddress.Addr[14],
pTxData->Session.DestinationAddress.Addr[15],
pTxData->Session.DestinationPort ));
// //
// Queue the data for transmission // Queue the data for transmission
// //
pPacket->pNext = NULL; pPacket->pNext = NULL;
pPreviousPacket = pSocket->pTxPacketListTail; pPreviousPacket = pSocket->pTxPacketListTail;
if ( NULL == pPreviousPacket ) { if ( NULL == pPreviousPacket ) {
pSocket->pTxPacketListHead = pPacket; pSocket->pTxPacketListHead = pPacket;
}
else {
pPreviousPacket->pNext = pPacket;
}
pSocket->pTxPacketListTail = pPacket;
DEBUG (( DEBUG_TX,
"0x%08x: Packet on transmit list\r\n",
pPacket ));
//
// Account for the buffered data
//
*pTxBytes += BufferLength;
*pDataLength = BufferLength;
//
// Start the transmit engine if it is idle
//
if ( NULL != pPort->pTxFree ) {
EslSocketTxStart ( pPort,
&pSocket->pTxPacketListHead,
&pSocket->pTxPacketListTail,
&pPort->pTxActive,
&pPort->pTxFree );
}
} }
else { else {
// pPreviousPacket->pNext = pPacket;
// Previous transmit error }
// Stop transmission pSocket->pTxPacketListTail = pPacket;
// DEBUG (( DEBUG_TX,
Status = pSocket->TxError; "0x%08x: Packet on transmit list\r\n",
pSocket->errno = EIO; pPacket ));
//
// Account for the buffered data
//
*pTxBytes += BufferLength;
*pDataLength = BufferLength;
//
// Start the transmit engine if it is idle
//
if ( NULL != pPort->pTxFree ) {
EslSocketTxStart ( pPort,
&pSocket->pTxPacketListHead,
&pSocket->pTxPacketListTail,
&pPort->pTxActive,
&pPort->pTxFree );
// //
// Free the packet // Ignore any transmit error
// //
EslSocketPacketFree ( pPacket, DEBUG_TX ); if ( EFI_ERROR ( pSocket->TxError )) {
break; DEBUG (( DEBUG_TX,
"0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
pPort,
pPacket,
pSocket->TxError ));
}
pSocket->TxError = EFI_SUCCESS;
} }
// //
@ -1041,6 +1055,18 @@ EslUdp6TxComplete (
pSocket->TxBytes -= LengthInBytes; pSocket->TxBytes -= LengthInBytes;
Status = pIo->Token.Udp6Tx.Status; Status = pIo->Token.Udp6Tx.Status;
//
// Ignore the transmit error
//
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_TX,
"0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
pPort,
pPacket,
Status ));
Status = EFI_SUCCESS;
}
// //
// Complete the transmit operation // Complete the transmit operation
// //
@ -1056,6 +1082,260 @@ EslUdp6TxComplete (
} }
/**
Verify the adapter's IP address
This support routine is called by EslSocketBindTest.
@param [in] pPort Address of an ::ESL_PORT structure.
@param [in] pConfigData Address of the configuration data
@retval EFI_SUCCESS - The IP address is valid
@retval EFI_NOT_STARTED - The IP address is invalid
**/
EFI_STATUS
EslUdp6VerifyLocalIpAddress (
IN ESL_PORT * pPort,
IN EFI_UDP6_CONFIG_DATA * pConfigData
)
{
UINTN AddressCount;
EFI_IP6_ADDRESS_INFO * pAddressInfo;
UINTN DataSize;
EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;
EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;
ESL_SERVICE * pService;
EFI_STATUS Status;
DBG_ENTER ( );
//
// Use break instead of goto
//
pIpConfigData = NULL;
for ( ; ; ) {
//
// Determine if the IP address is specified
//
DEBUG (( DEBUG_BIND,
"Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1],
pConfigData->StationAddress.Addr[2],
pConfigData->StationAddress.Addr[3],
pConfigData->StationAddress.Addr[4],
pConfigData->StationAddress.Addr[5],
pConfigData->StationAddress.Addr[6],
pConfigData->StationAddress.Addr[7],
pConfigData->StationAddress.Addr[8],
pConfigData->StationAddress.Addr[9],
pConfigData->StationAddress.Addr[10],
pConfigData->StationAddress.Addr[11],
pConfigData->StationAddress.Addr[12],
pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14],
pConfigData->StationAddress.Addr[15]));
if (( 0 == pConfigData->StationAddress.Addr [ 0 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 1 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 2 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 3 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 4 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 5 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 6 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 7 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 8 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 9 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 10 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 11 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 12 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 13 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 14 ])
&& ( 0 == pConfigData->StationAddress.Addr [ 15 ]))
{
Status = EFI_SUCCESS;
break;
}
//
// Open the configuration protocol
//
pService = pPort->pService;
Status = gBS->OpenProtocol ( pService->Controller,
&gEfiIp6ConfigProtocolGuid,
(VOID **)&pIpConfigProtocol,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - IP Configuration Protocol not available, Status: %r\r\n",
Status ));
break;
}
//
// Get the IP configuration data size
//
DataSize = 0;
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
Ip6ConfigDataTypeInterfaceInfo,
&DataSize,
NULL );
if ( EFI_BUFFER_TOO_SMALL != Status ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
Status ));
break;
}
//
// Allocate the configuration data buffer
//
pIpConfigData = AllocatePool ( DataSize );
if ( NULL == pIpConfigData ) {
DEBUG (( DEBUG_ERROR,
"ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
Status = EFI_OUT_OF_RESOURCES;
break;
}
//
// Get the IP configuration
//
Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
Ip6ConfigDataTypeInterfaceInfo,
&DataSize,
pIpConfigData );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to return IP Configuration data, Status: %r\r\n",
Status ));
break;
}
//
// Display the current configuration
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
pIpConfigData->HwAddress.Addr [ 0 ],
pIpConfigData->HwAddress.Addr [ 1 ],
pIpConfigData->HwAddress.Addr [ 2 ],
pIpConfigData->HwAddress.Addr [ 3 ],
pIpConfigData->HwAddress.Addr [ 4 ],
pIpConfigData->HwAddress.Addr [ 5 ],
pIpConfigData->HwAddress.Addr [ 6 ],
pIpConfigData->HwAddress.Addr [ 7 ],
pIpConfigData->HwAddress.Addr [ 8 ],
pIpConfigData->HwAddress.Addr [ 9 ],
pIpConfigData->HwAddress.Addr [ 10 ],
pIpConfigData->HwAddress.Addr [ 11 ],
pIpConfigData->HwAddress.Addr [ 12 ],
pIpConfigData->HwAddress.Addr [ 13 ],
pIpConfigData->HwAddress.Addr [ 14 ],
pIpConfigData->HwAddress.Addr [ 15 ]));
//
// Validate the hardware address
//
Status = EFI_SUCCESS;
if (( 16 == pIpConfigData->HwAddressSize )
&& ( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])
&& ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])
&& ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])
&& ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])
&& ( pConfigData->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])
&& ( pConfigData->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])
&& ( pConfigData->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])
&& ( pConfigData->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])
&& ( pConfigData->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])
&& ( pConfigData->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])
&& ( pConfigData->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])
&& ( pConfigData->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])
&& ( pConfigData->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])
&& ( pConfigData->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])
&& ( pConfigData->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])
&& ( pConfigData->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {
break;
}
//
// Walk the list of other IP addresses assigned to this adapter
//
for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {
pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];
//
// Display the IP address
//
DEBUG (( DEBUG_BIND,
"Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
pAddressInfo->Address.Addr [ 0 ],
pAddressInfo->Address.Addr [ 1 ],
pAddressInfo->Address.Addr [ 2 ],
pAddressInfo->Address.Addr [ 3 ],
pAddressInfo->Address.Addr [ 4 ],
pAddressInfo->Address.Addr [ 5 ],
pAddressInfo->Address.Addr [ 6 ],
pAddressInfo->Address.Addr [ 7 ],
pAddressInfo->Address.Addr [ 8 ],
pAddressInfo->Address.Addr [ 9 ],
pAddressInfo->Address.Addr [ 10 ],
pAddressInfo->Address.Addr [ 11 ],
pAddressInfo->Address.Addr [ 12 ],
pAddressInfo->Address.Addr [ 13 ],
pAddressInfo->Address.Addr [ 14 ],
pAddressInfo->Address.Addr [ 15 ]));
//
// Validate the IP address
//
if (( pConfigData->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])
&& ( pConfigData->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])
&& ( pConfigData->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])
&& ( pConfigData->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])
&& ( pConfigData->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])
&& ( pConfigData->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])
&& ( pConfigData->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])
&& ( pConfigData->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])
&& ( pConfigData->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])
&& ( pConfigData->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])
&& ( pConfigData->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])
&& ( pConfigData->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])
&& ( pConfigData->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])
&& ( pConfigData->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])
&& ( pConfigData->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])
&& ( pConfigData->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {
break;
}
}
if ( pIpConfigData->AddressInfoCount > AddressCount ) {
break;
}
//
// The IP address did not match
//
Status = EFI_NOT_STARTED;
break;
}
//
// Free the buffer if necessary
//
if ( NULL != pIpConfigData ) {
FreePool ( pIpConfigData );
}
//
// Return the IP address status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/** /**
Interface between the socket layer and the network specific Interface between the socket layer and the network specific
code that supports SOCK_DGRAM sockets over UDPv4. code that supports SOCK_DGRAM sockets over UDPv4.
@ -1094,5 +1374,6 @@ CONST ESL_PROTOCOL_API cEslUdp6Api = {
NULL, // RxStart NULL, // RxStart
EslUdp6TxBuffer, EslUdp6TxBuffer,
EslUdp6TxComplete, EslUdp6TxComplete,
NULL // TxOobComplete NULL, // TxOobComplete
EslUdp6VerifyLocalIpAddress
}; };

View File

@ -24,6 +24,8 @@
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
#include <Protocol/EfiSocket.h> #include <Protocol/EfiSocket.h>
#include <Protocol/Ip4Config.h>
#include <Protocol/Ip6Config.h>
#include <Protocol/ServiceBinding.h> #include <Protocol/ServiceBinding.h>
#include <Protocol/Tcp4.h> #include <Protocol/Tcp4.h>
#include <Protocol/Tcp6.h> #include <Protocol/Tcp6.h>