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
diff --git a/StdLib/EfiSocketLib/EfiSocketLib.inf b/StdLib/EfiSocketLib/EfiSocketLib.inf
index 5e6ff59..a68e241 100644
--- a/StdLib/EfiSocketLib/EfiSocketLib.inf
+++ b/StdLib/EfiSocketLib/EfiSocketLib.inf
@@ -52,6 +52,8 @@
UefiLib
[Protocols]
+ gEfiIp4ConfigProtocolGuid
+ gEfiIp6ConfigProtocolGuid
gEfiIp4ProtocolGuid
gEfiIp4ServiceBindingProtocolGuid
gEfiIp6ProtocolGuid
diff --git a/StdLib/EfiSocketLib/Ip4.c b/StdLib/EfiSocketLib/Ip4.c
index 2e832c7..1f7096e 100644
--- a/StdLib/EfiSocketLib/Ip4.c
+++ b/StdLib/EfiSocketLib/Ip4.c
@@ -1067,71 +1067,64 @@
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
- // Stop transmission after an error
+ // Display the request
//
- if ( !EFI_ERROR ( pSocket->TxError )) {
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
- BufferLength,
- pBuffer,
- pIp4->ModeData.ConfigData.StationAddress.Addr[0],
- pIp4->ModeData.ConfigData.StationAddress.Addr[1],
- pIp4->ModeData.ConfigData.StationAddress.Addr[2],
- pIp4->ModeData.ConfigData.StationAddress.Addr[3],
- pTxData->TxData.DestinationAddress.Addr[0],
- pTxData->TxData.DestinationAddress.Addr[1],
- pTxData->TxData.DestinationAddress.Addr[2],
- pTxData->TxData.DestinationAddress.Addr[3]));
+ DEBUG (( DEBUG_TX,
+ "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
+ BufferLength,
+ pBuffer,
+ pIp4->ModeData.ConfigData.StationAddress.Addr[0],
+ pIp4->ModeData.ConfigData.StationAddress.Addr[1],
+ pIp4->ModeData.ConfigData.StationAddress.Addr[2],
+ pIp4->ModeData.ConfigData.StationAddress.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
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
-
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- }
+ //
+ // Queue the data for transmission
+ //
+ pPacket->pNext = NULL;
+ pPreviousPacket = pSocket->pTxPacketListTail;
+ if ( NULL == pPreviousPacket ) {
+ pSocket->pTxPacketListHead = pPacket;
}
else {
- //
- // Previous transmit error
- // Stop transmission
- //
- Status = pSocket->TxError;
- pSocket->errno = EIO;
+ 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 );
//
- // Free the packet
+ // Ignore any transmit error
//
- EslSocketPacketFree ( pPacket, DEBUG_TX );
- break;
+ if ( EFI_ERROR ( pSocket->TxError )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ pSocket->TxError ));
+ }
+ pSocket->TxError = EFI_SUCCESS;
}
//
@@ -1213,6 +1206,18 @@
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
//
EslSocketTxComplete ( pIo,
@@ -1228,6 +1233,157 @@
/**
+ 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
code that supports SOCK_RAW sockets over IPv4.
**/
@@ -1265,5 +1421,6 @@
NULL, // RxStart
EslIp4TxBuffer,
EslIp4TxComplete,
- NULL // TxOobComplete
+ NULL, // TxOobComplete
+ EslIp4VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c
index a74dcd0..b801195 100644
--- a/StdLib/EfiSocketLib/Socket.c
+++ b/StdLib/EfiSocketLib/Socket.c
@@ -1336,27 +1336,40 @@
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 )) {
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,
Status ));
pPort->pSocket->errno = ErrnoValue;
}
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 )) {
- DEBUG (( DEBUG_ERROR | DEBUG_BIND,
- "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",
+ DEBUG (( DEBUG_WARN | DEBUG_BIND,
+ "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",
pPort,
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,11 +5937,25 @@
*ppActive = pIo;
}
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 ) {
pSocket->TxError = Status;
}
//
+ // Free the IO structure
+ //
+ pIo->pNext = *ppFree;
+ *ppFree = pIo;
+
+ //
// Discard the transmit buffer
//
EslSocketPacketFree ( pPacket, DEBUG_TX );
diff --git a/StdLib/EfiSocketLib/Socket.h b/StdLib/EfiSocketLib/Socket.h
index b38bec6..583be1f 100644
--- a/StdLib/EfiSocketLib/Socket.h
+++ b/StdLib/EfiSocketLib/Socket.h
@@ -921,6 +921,25 @@
);
/**
+ 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
This driver uses this structure to define the API for the socket type.
@@ -960,6 +979,7 @@
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 pfnTxOobComplete; ///< TX completion for urgent data
+ PFN_API_VERIFY_LOCAL_IP_ADDRESS pfnVerifyLocalIpAddress; ///< Verify the local IP address
} ESL_PROTOCOL_API;
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
index 34e60e2..1e1d62a 100644
--- a/StdLib/EfiSocketLib/Tcp4.c
+++ b/StdLib/EfiSocketLib/Tcp4.c
@@ -2226,6 +2226,159 @@
/**
+ 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
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets
over TCPv4.
@@ -2264,5 +2417,6 @@
EslTcp4RxStart,
EslTcp4TxBuffer,
EslTcp4TxComplete,
- EslTcp4TxOobComplete
+ EslTcp4TxOobComplete,
+ EslTcp4VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Tcp6.c b/StdLib/EfiSocketLib/Tcp6.c
index df70a94..d68cb76 100644
--- a/StdLib/EfiSocketLib/Tcp6.c
+++ b/StdLib/EfiSocketLib/Tcp6.c
@@ -2295,6 +2295,262 @@
/**
+ 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
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets
over TCPv6.
@@ -2333,5 +2589,6 @@
EslTcp6RxStart,
EslTcp6TxBuffer,
EslTcp6TxComplete,
- EslTcp6TxOobComplete
+ EslTcp6TxOobComplete,
+ EslTcp6VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
index 11b7db7..9ab96ac 100644
--- a/StdLib/EfiSocketLib/Udp4.c
+++ b/StdLib/EfiSocketLib/Udp4.c
@@ -867,63 +867,62 @@
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
- // Stop transmission after an error
+ // Display the request
//
- if ( !EFI_ERROR ( pSocket->TxError )) {
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d %s bytes from 0x%08x\r\n",
- BufferLength,
- pBuffer ));
+ DEBUG (( DEBUG_TX,
+ "Send %d bytes from 0x%08x to %d.%d.%d.%d:%d\r\n",
+ BufferLength,
+ pBuffer,
+ pTxData->Session.DestinationAddress.Addr[0],
+ pTxData->Session.DestinationAddress.Addr[1],
+ pTxData->Session.DestinationAddress.Addr[2],
+ pTxData->Session.DestinationAddress.Addr[3],
+ pTxData->Session.DestinationPort ));
- //
- // Queue the data for transmission
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
-
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- }
+ //
+ // Queue the data for transmission
+ //
+ pPacket->pNext = NULL;
+ pPreviousPacket = pSocket->pTxPacketListTail;
+ if ( NULL == pPreviousPacket ) {
+ pSocket->pTxPacketListHead = pPacket;
}
else {
- //
- // Previous transmit error
- // Stop transmission
- //
- Status = pSocket->TxError;
- pSocket->errno = EIO;
+ pPreviousPacket->pNext = pPacket;
+ }
+ pSocket->pTxPacketListTail = pPacket;
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Packet on transmit list\r\n",
+ pPacket ));
+
+ //
+ // Account for the buffered data
+ //
+ *pTxBytes += BufferLength;
+ *pDataLength = BufferLength;
+
+ //
+ // Start the transmit engine if it is idle
+ //
+ if ( NULL != pPort->pTxFree ) {
+ pPacket = pSocket->pTxPacketListHead;
+ EslSocketTxStart ( pPort,
+ &pSocket->pTxPacketListHead,
+ &pSocket->pTxPacketListTail,
+ &pPort->pTxActive,
+ &pPort->pTxFree );
//
- // Free the packet
+ // Ignore any transmit error
//
- EslSocketPacketFree ( pPacket, DEBUG_TX );
- break;
+ if ( EFI_ERROR ( pSocket->TxError )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ pSocket->TxError ));
+ }
+ pSocket->TxError = EFI_SUCCESS;
}
//
@@ -1005,6 +1004,18 @@
Status = pIo->Token.Udp4Tx.Status;
//
+ // Ignore the transmit error
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ Status ));
+ Status = EFI_SUCCESS;
+ }
+
+ //
// Complete the transmit operation
//
EslSocketTxComplete ( pIo,
@@ -1020,6 +1031,157 @@
/**
+ 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
code that supports SOCK_DGRAM sockets over UDPv4.
**/
@@ -1057,5 +1219,6 @@
NULL, // RxStart
EslUdp4TxBuffer,
EslUdp4TxComplete,
- NULL // TxOobComplete
+ NULL, // TxOobComplete
+ EslUdp4VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Udp6.c b/StdLib/EfiSocketLib/Udp6.c
index 7de5005..59b99f8 100644
--- a/StdLib/EfiSocketLib/Udp6.c
+++ b/StdLib/EfiSocketLib/Udp6.c
@@ -609,7 +609,7 @@
pUdp6Protocol = pPort->pProtocol.UDPv6;
pConfigData = &pUdp6->ConfigData;
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,
pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1],
@@ -627,7 +627,9 @@
pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14],
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[1],
pConfigData->RemoteAddress.Addr[2],
@@ -692,7 +694,7 @@
}
else {
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,
pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1],
@@ -710,7 +712,9 @@
pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14],
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[1],
pConfigData->RemoteAddress.Addr[2],
@@ -904,63 +908,73 @@
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
- // Stop transmission after an error
+ // Display the request
//
- if ( !EFI_ERROR ( pSocket->TxError )) {
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d %s bytes from 0x%08x\r\n",
- BufferLength,
- pBuffer ));
+ 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",
+ BufferLength,
+ pBuffer,
+ pTxData->Session.DestinationAddress.Addr[0],
+ pTxData->Session.DestinationAddress.Addr[1],
+ pTxData->Session.DestinationAddress.Addr[2],
+ 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
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
-
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- }
+ //
+ // Queue the data for transmission
+ //
+ pPacket->pNext = NULL;
+ pPreviousPacket = pSocket->pTxPacketListTail;
+ if ( NULL == pPreviousPacket ) {
+ pSocket->pTxPacketListHead = pPacket;
}
else {
- //
- // Previous transmit error
- // Stop transmission
- //
- Status = pSocket->TxError;
- pSocket->errno = EIO;
+ 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 );
//
- // Free the packet
+ // Ignore any transmit error
//
- EslSocketPacketFree ( pPacket, DEBUG_TX );
- break;
+ if ( EFI_ERROR ( pSocket->TxError )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ pSocket->TxError ));
+ }
+ pSocket->TxError = EFI_SUCCESS;
}
//
@@ -1042,6 +1056,18 @@
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
//
EslSocketTxComplete ( pIo,
@@ -1057,6 +1083,260 @@
/**
+ 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
code that supports SOCK_DGRAM sockets over UDPv4.
**/
@@ -1094,5 +1374,6 @@
NULL, // RxStart
EslUdp6TxBuffer,
EslUdp6TxComplete,
- NULL // TxOobComplete
+ NULL, // TxOobComplete
+ EslUdp6VerifyLocalIpAddress
};
diff --git a/StdLib/Include/Efi/EfiSocketLib.h b/StdLib/Include/Efi/EfiSocketLib.h
index d78e9f6..efd6a61 100644
--- a/StdLib/Include/Efi/EfiSocketLib.h
+++ b/StdLib/Include/Efi/EfiSocketLib.h
@@ -24,6 +24,8 @@
#include <Library/UefiLib.h>
#include <Protocol/EfiSocket.h>
+#include <Protocol/Ip4Config.h>
+#include <Protocol/Ip6Config.h>
#include <Protocol/ServiceBinding.h>
#include <Protocol/Tcp4.h>
#include <Protocol/Tcp6.h>