From 2dc09dd50fe30496efe9922ee6177ed7bdef6bc2 Mon Sep 17 00:00:00 2001 From: Lee Leahy Date: Wed, 20 Nov 2013 18:31:01 +0000 Subject: 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 Reviewed-by: Ankit Singh3 git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14875 6f19259b-4bc3-4df7-8a09-765794883524 --- StdLib/EfiSocketLib/Tcp6.c | 259 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 258 insertions(+), 1 deletion(-) (limited to 'StdLib/EfiSocketLib/Tcp6.c') diff --git a/StdLib/EfiSocketLib/Tcp6.c b/StdLib/EfiSocketLib/Tcp6.c index df70a94f4c..d68cb76cb8 100644 --- a/StdLib/EfiSocketLib/Tcp6.c +++ b/StdLib/EfiSocketLib/Tcp6.c @@ -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 code that supports SOCK_STREAM and SOCK_SEQPACKET sockets @@ -2333,5 +2589,6 @@ CONST ESL_PROTOCOL_API cEslTcp6Api = { EslTcp6RxStart, EslTcp6TxBuffer, EslTcp6TxComplete, - EslTcp6TxOobComplete + EslTcp6TxOobComplete, + EslTcp6VerifyLocalIpAddress }; -- cgit v1.2.3