]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Tcp6.c
StdLib: Remove EfiSocketLib and Ip4Config Protocol dependency.
[mirror_edk2.git] / StdLib / EfiSocketLib / Tcp6.c
index df70a94f4c380a1ba4ae49274fb15b886eb04f51..0f6d2d6ac93c24f85fa91dc99979a20590ea13f5 100644 (file)
@@ -1,18 +1,18 @@
 /** @file\r
   Implement the TCP6 driver support for the socket layer.\r
 \r
 /** @file\r
   Implement the TCP6 driver support for the socket layer.\r
 \r
-  Copyright (c) 2011, Intel Corporation\r
-  All rights reserved. This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
+  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials are licensed and made available\r
+  under the terms and conditions of the BSD License which accompanies this\r
+  distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
 \r
   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 \r
   \section ConnectionManagement Connection Management\r
 \r
   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 \r
   \section ConnectionManagement Connection Management\r
-  \r
+\r
   The ::EslTcp6Listen routine initially places the SOCK_STREAM or\r
   SOCK_SEQPACKET socket into a listen state.   When a remote machine\r
   makes a connection to the socket, the TCPv6 network layer calls\r
   The ::EslTcp6Listen routine initially places the SOCK_STREAM or\r
   SOCK_SEQPACKET socket into a listen state.   When a remote machine\r
   makes a connection to the socket, the TCPv6 network layer calls\r
@@ -238,6 +238,13 @@ EslTcp6ConnectComplete (
               pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],\r
               pTcp6->ConfigData.AccessPoint.RemotePort ));\r
 \r
               pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],\r
               pTcp6->ConfigData.AccessPoint.RemotePort ));\r
 \r
+    //\r
+    //  Start the receive operations\r
+    //\r
+    pSocket->bConfigured = TRUE;\r
+    pSocket->State = SOCKET_STATE_CONNECTED;\r
+    EslSocketRxStart ( pPort );\r
+\r
     //\r
     //  Remove the rest of the ports\r
     //\r
     //\r
     //  Remove the rest of the ports\r
     //\r
@@ -391,56 +398,55 @@ EslTcp6ConnectPoll (
       case EFI_DEVICE_ERROR:\r
         pSocket->errno = EIO;\r
         break;\r
       case EFI_DEVICE_ERROR:\r
         pSocket->errno = EIO;\r
         break;\r
-      \r
+\r
       case EFI_ABORTED:\r
         pSocket->errno = ECONNABORTED;\r
         break;\r
       case EFI_ABORTED:\r
         pSocket->errno = ECONNABORTED;\r
         break;\r
-      \r
+\r
       case EFI_ACCESS_DENIED:\r
         pSocket->errno = EACCES;\r
         break;\r
       case EFI_ACCESS_DENIED:\r
         pSocket->errno = EACCES;\r
         break;\r
-      \r
+\r
       case EFI_CONNECTION_RESET:\r
         pSocket->errno = ECONNRESET;\r
         break;\r
       case EFI_CONNECTION_RESET:\r
         pSocket->errno = ECONNRESET;\r
         break;\r
-      \r
+\r
       case EFI_INVALID_PARAMETER:\r
         pSocket->errno = EADDRNOTAVAIL;\r
         break;\r
       case EFI_INVALID_PARAMETER:\r
         pSocket->errno = EADDRNOTAVAIL;\r
         break;\r
-      \r
+\r
       case EFI_HOST_UNREACHABLE:\r
       case EFI_NO_RESPONSE:\r
         pSocket->errno = EHOSTUNREACH;\r
         break;\r
       case EFI_HOST_UNREACHABLE:\r
       case EFI_NO_RESPONSE:\r
         pSocket->errno = EHOSTUNREACH;\r
         break;\r
-      \r
+\r
       case EFI_NO_MAPPING:\r
         pSocket->errno = EAFNOSUPPORT;\r
         break;\r
       case EFI_NO_MAPPING:\r
         pSocket->errno = EAFNOSUPPORT;\r
         break;\r
-      \r
+\r
       case EFI_NO_MEDIA:\r
       case EFI_NETWORK_UNREACHABLE:\r
         pSocket->errno = ENETDOWN;\r
         break;\r
       case EFI_NO_MEDIA:\r
       case EFI_NETWORK_UNREACHABLE:\r
         pSocket->errno = ENETDOWN;\r
         break;\r
-      \r
+\r
       case EFI_OUT_OF_RESOURCES:\r
         pSocket->errno = ENOBUFS;\r
         break;\r
       case EFI_OUT_OF_RESOURCES:\r
         pSocket->errno = ENOBUFS;\r
         break;\r
-      \r
+\r
       case EFI_PORT_UNREACHABLE:\r
       case EFI_PROTOCOL_UNREACHABLE:\r
       case EFI_CONNECTION_REFUSED:\r
         pSocket->errno = ECONNREFUSED;\r
         break;\r
       case EFI_PORT_UNREACHABLE:\r
       case EFI_PROTOCOL_UNREACHABLE:\r
       case EFI_CONNECTION_REFUSED:\r
         pSocket->errno = ECONNREFUSED;\r
         break;\r
-      \r
+\r
       case EFI_SUCCESS:\r
         pSocket->errno = 0;\r
       case EFI_SUCCESS:\r
         pSocket->errno = 0;\r
-        pSocket->bConfigured = TRUE;\r
         break;\r
         break;\r
-      \r
+\r
       case EFI_TIMEOUT:\r
         pSocket->errno = ETIMEDOUT;\r
         break;\r
       case EFI_TIMEOUT:\r
         pSocket->errno = ETIMEDOUT;\r
         break;\r
-      \r
+\r
       case EFI_UNSUPPORTED:\r
         pSocket->errno = EOPNOTSUPP;\r
         break;\r
       case EFI_UNSUPPORTED:\r
         pSocket->errno = EOPNOTSUPP;\r
         break;\r
@@ -499,7 +505,7 @@ EslTcp6ConnectStart (
   EFI_STATUS Status;\r
 \r
   DBG_ENTER ( );\r
   EFI_STATUS Status;\r
 \r
   DBG_ENTER ( );\r
-  \r
+\r
   //\r
   //  Determine if any more local adapters are available\r
   //\r
   //\r
   //  Determine if any more local adapters are available\r
   //\r
@@ -595,7 +601,7 @@ EslTcp6ConnectStart (
       //  Status to errno translation gets done in EslTcp4ConnectPoll\r
       //\r
       pTcp6->ConnectToken.CompletionToken.Status = Status;\r
       //  Status to errno translation gets done in EslTcp4ConnectPoll\r
       //\r
       pTcp6->ConnectToken.CompletionToken.Status = Status;\r
-      \r
+\r
       //\r
       //  Continue with the next port\r
       //\r
       //\r
       //  Continue with the next port\r
       //\r
@@ -801,7 +807,7 @@ EslTcp6Listen (
       //\r
       pPort = pNextPort;\r
     }\r
       //\r
       pPort = pNextPort;\r
     }\r
-    \r
+\r
     //\r
     //  Determine if any ports are in the listen state\r
     //\r
     //\r
     //  Determine if any ports are in the listen state\r
     //\r
@@ -865,7 +871,6 @@ EslTcp6ListenComplete (
   EFI_HANDLE ChildHandle;\r
   struct sockaddr_in6 LocalAddress;\r
   EFI_TCP6_CONFIG_DATA * pConfigData;\r
   EFI_HANDLE ChildHandle;\r
   struct sockaddr_in6 LocalAddress;\r
   EFI_TCP6_CONFIG_DATA * pConfigData;\r
-  ESL_LAYER * pLayer;\r
   ESL_PORT * pNewPort;\r
   ESL_SOCKET * pNewSocket;\r
   ESL_SOCKET * pSocket;\r
   ESL_PORT * pNewPort;\r
   ESL_SOCKET * pNewSocket;\r
   ESL_SOCKET * pSocket;\r
@@ -894,7 +899,6 @@ EslTcp6ListenComplete (
     //  Allocate a socket for this connection\r
     //\r
     ChildHandle = NULL;\r
     //  Allocate a socket for this connection\r
     //\r
     ChildHandle = NULL;\r
-    pLayer = &mEslLayer;\r
     Status = EslSocketAllocate ( &ChildHandle,\r
                                  DEBUG_CONNECTION,\r
                                  &pNewSocket );\r
     Status = EslSocketAllocate ( &ChildHandle,\r
                                  DEBUG_CONNECTION,\r
                                  &pNewSocket );\r
@@ -1092,7 +1096,7 @@ EslTcp6ListenComplete (
     //  Process:\r
     //    Call close\r
     //    Release the resources\r
     //  Process:\r
     //    Call close\r
     //    Release the resources\r
-    \r
+\r
   }\r
 \r
   DBG_EXIT ( );\r
   }\r
 \r
   DBG_EXIT ( );\r
@@ -1391,7 +1395,7 @@ EslTcp6PortAllocate (
 \r
   This routine is called by ::EslSocketPortClose.\r
   See the \ref PortCloseStateMachine section.\r
 \r
   This routine is called by ::EslSocketPortClose.\r
   See the \ref PortCloseStateMachine section.\r
-  \r
+\r
   @param [in] pPort       Address of an ::ESL_PORT structure.\r
 \r
   @retval EFI_SUCCESS     The port is closed\r
   @param [in] pPort       Address of an ::ESL_PORT structure.\r
 \r
   @retval EFI_SUCCESS     The port is closed\r
@@ -1406,7 +1410,7 @@ EslTcp6PortClose (
   UINTN DebugFlags;\r
   ESL_TCP6_CONTEXT * pTcp6;\r
   EFI_STATUS Status;\r
   UINTN DebugFlags;\r
   ESL_TCP6_CONTEXT * pTcp6;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
 \r
   //\r
   DBG_ENTER ( );\r
 \r
   //\r
@@ -1550,13 +1554,13 @@ EslTcp6PortCloseOp (
   @param [in] pPort           Address of an ::ESL_PORT structure.\r
 \r
   @param [in] pPacket         Address of an ::ESL_PACKET structure.\r
   @param [in] pPort           Address of an ::ESL_PORT structure.\r
 \r
   @param [in] pPacket         Address of an ::ESL_PACKET structure.\r
-  \r
+\r
   @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed\r
   @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed\r
-  \r
+\r
   @param [in] BufferLength    Length of the the buffer\r
   @param [in] BufferLength    Length of the the buffer\r
-  \r
+\r
   @param [in] pBuffer         Address of a buffer to receive the data.\r
   @param [in] pBuffer         Address of a buffer to receive the data.\r
-  \r
+\r
   @param [in] pDataLength     Number of received data bytes in the buffer.\r
 \r
   @param [out] pAddress       Network address to receive the remote system address\r
   @param [in] pDataLength     Number of received data bytes in the buffer.\r
 \r
   @param [out] pAddress       Network address to receive the remote system address\r
@@ -1951,13 +1955,13 @@ EslTcp6RxStart (
   during the current transmission attempt.\r
 \r
   @param [in] pSocket         Address of an ::ESL_SOCKET structure\r
   during the current transmission attempt.\r
 \r
   @param [in] pSocket         Address of an ::ESL_SOCKET structure\r
-  \r
+\r
   @param [in] Flags           Message control flags\r
   @param [in] Flags           Message control flags\r
-  \r
+\r
   @param [in] BufferLength    Length of the the buffer\r
   @param [in] BufferLength    Length of the the buffer\r
-  \r
+\r
   @param [in] pBuffer         Address of a buffer to receive the data.\r
   @param [in] pBuffer         Address of a buffer to receive the data.\r
-  \r
+\r
   @param [in] pDataLength     Number of received data bytes in the buffer.\r
 \r
   @param [in] pAddress        Network address of the remote system address\r
   @param [in] pDataLength     Number of received data bytes in the buffer.\r
 \r
   @param [in] pAddress        Network address of the remote system address\r
@@ -1987,7 +1991,6 @@ EslTcp6TxBuffer (
   ESL_PACKET ** ppQueueHead;\r
   ESL_PACKET ** ppQueueTail;\r
   ESL_PACKET * pPreviousPacket;\r
   ESL_PACKET ** ppQueueHead;\r
   ESL_PACKET ** ppQueueTail;\r
   ESL_PACKET * pPreviousPacket;\r
-  ESL_TCP6_CONTEXT * pTcp6;\r
   size_t * pTxBytes;\r
   EFI_TCP6_TRANSMIT_DATA * pTxData;\r
   EFI_STATUS Status;\r
   size_t * pTxBytes;\r
   EFI_TCP6_TRANSMIT_DATA * pTxData;\r
   EFI_STATUS Status;\r
@@ -2014,7 +2017,6 @@ EslTcp6TxBuffer (
       //\r
       //  Determine the queue head\r
       //\r
       //\r
       //  Determine the queue head\r
       //\r
-      pTcp6 = &pPort->Context.Tcp6;\r
       bUrgent = (BOOLEAN)( 0 != ( Flags & MSG_OOB ));\r
       bUrgentQueue = bUrgent\r
                     && ( !pSocket->bOobInLine )\r
       bUrgent = (BOOLEAN)( 0 != ( Flags & MSG_OOB ));\r
       bUrgentQueue = bUrgent\r
                     && ( !pSocket->bOobInLine )\r
@@ -2205,7 +2207,7 @@ EslTcp6TxComplete (
   ESL_PORT * pPort;\r
   ESL_SOCKET * pSocket;\r
   EFI_STATUS Status;\r
   ESL_PORT * pPort;\r
   ESL_SOCKET * pSocket;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
 \r
   //\r
   DBG_ENTER ( );\r
 \r
   //\r
@@ -2294,6 +2296,262 @@ EslTcp6TxOobComplete (
 }\r
 \r
 \r
 }\r
 \r
 \r
+/**\r
+  Verify the adapter's IP address\r
+\r
+  This support routine is called by EslSocketBindTest.\r
+\r
+  @param [in] pPort       Address of an ::ESL_PORT structure.\r
+  @param [in] pConfigData Address of the configuration data\r
+\r
+  @retval EFI_SUCCESS - The IP address is valid\r
+  @retval EFI_NOT_STARTED - The IP address is invalid\r
+\r
+ **/\r
+EFI_STATUS\r
+EslTcp6VerifyLocalIpAddress (\r
+  IN ESL_PORT * pPort,\r
+  IN EFI_TCP6_CONFIG_DATA * pConfigData\r
+  )\r
+{\r
+  UINTN AddressCount;\r
+  EFI_IP6_ADDRESS_INFO * pAddressInfo;\r
+  UINTN DataSize;\r
+  EFI_TCP6_ACCESS_POINT * pAccess;\r
+  EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;\r
+  EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;\r
+  ESL_SERVICE * pService;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Use break instead of goto\r
+  //\r
+  pIpConfigData = NULL;\r
+  for ( ; ; ) {\r
+    //\r
+    //  Determine if the IP address is specified\r
+    //\r
+    pAccess = &pConfigData->AccessPoint;\r
+    DEBUG (( DEBUG_BIND,\r
+              "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+              pAccess->StationAddress.Addr[0],\r
+              pAccess->StationAddress.Addr[1],\r
+              pAccess->StationAddress.Addr[2],\r
+              pAccess->StationAddress.Addr[3],\r
+              pAccess->StationAddress.Addr[4],\r
+              pAccess->StationAddress.Addr[5],\r
+              pAccess->StationAddress.Addr[6],\r
+              pAccess->StationAddress.Addr[7],\r
+              pAccess->StationAddress.Addr[8],\r
+              pAccess->StationAddress.Addr[9],\r
+              pAccess->StationAddress.Addr[10],\r
+              pAccess->StationAddress.Addr[11],\r
+              pAccess->StationAddress.Addr[12],\r
+              pAccess->StationAddress.Addr[13],\r
+              pAccess->StationAddress.Addr[14],\r
+              pAccess->StationAddress.Addr[15]));\r
+    if (( 0 == pAccess->StationAddress.Addr [ 0 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 1 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 2 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 3 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 4 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 5 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 6 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 7 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 8 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 9 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 10 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 11 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 12 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 13 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 14 ])\r
+      && ( 0 == pAccess->StationAddress.Addr [ 15 ]))\r
+    {\r
+      Status = EFI_SUCCESS;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Open the configuration protocol\r
+    //\r
+    pService = pPort->pService;\r
+    Status = gBS->OpenProtocol ( pService->Controller,\r
+                                 &gEfiIp6ConfigProtocolGuid,\r
+                                 (VOID **)&pIpConfigProtocol,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 EFI_OPEN_PROTOCOL_GET_PROTOCOL );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - IP Configuration Protocol not available, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Get the IP configuration data size\r
+    //\r
+    DataSize = 0;\r
+    Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+                                          Ip6ConfigDataTypeInterfaceInfo,\r
+                                          &DataSize,\r
+                                          NULL );\r
+    if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Allocate the configuration data buffer\r
+    //\r
+    pIpConfigData = AllocatePool ( DataSize );\r
+    if ( NULL == pIpConfigData ) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Get the IP configuration\r
+    //\r
+    Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,\r
+                                          Ip6ConfigDataTypeInterfaceInfo,\r
+                                          &DataSize,\r
+                                          pIpConfigData );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to return IP Configuration data, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Display the current configuration\r
+    //\r
+    DEBUG (( DEBUG_BIND,\r
+              "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+              pIpConfigData->HwAddress.Addr [ 0 ],\r
+              pIpConfigData->HwAddress.Addr [ 1 ],\r
+              pIpConfigData->HwAddress.Addr [ 2 ],\r
+              pIpConfigData->HwAddress.Addr [ 3 ],\r
+              pIpConfigData->HwAddress.Addr [ 4 ],\r
+              pIpConfigData->HwAddress.Addr [ 5 ],\r
+              pIpConfigData->HwAddress.Addr [ 6 ],\r
+              pIpConfigData->HwAddress.Addr [ 7 ],\r
+              pIpConfigData->HwAddress.Addr [ 8 ],\r
+              pIpConfigData->HwAddress.Addr [ 9 ],\r
+              pIpConfigData->HwAddress.Addr [ 10 ],\r
+              pIpConfigData->HwAddress.Addr [ 11 ],\r
+              pIpConfigData->HwAddress.Addr [ 12 ],\r
+              pIpConfigData->HwAddress.Addr [ 13 ],\r
+              pIpConfigData->HwAddress.Addr [ 14 ],\r
+              pIpConfigData->HwAddress.Addr [ 15 ]));\r
+\r
+    //\r
+    //  Validate the hardware address\r
+    //\r
+    Status = EFI_SUCCESS;\r
+    if (( 16 == pIpConfigData->HwAddressSize )\r
+      && ( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])\r
+      && ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])\r
+      && ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])\r
+      && ( pAccess->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])\r
+      && ( pAccess->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])\r
+      && ( pAccess->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])\r
+      && ( pAccess->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])\r
+      && ( pAccess->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])\r
+      && ( pAccess->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])\r
+      && ( pAccess->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])\r
+      && ( pAccess->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])\r
+      && ( pAccess->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])\r
+      && ( pAccess->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])\r
+      && ( pAccess->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])\r
+      && ( pAccess->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])\r
+      && ( pAccess->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Walk the list of other IP addresses assigned to this adapter\r
+    //\r
+    for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {\r
+      pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];\r
+\r
+      //\r
+      //  Display the IP address\r
+      //\r
+      DEBUG (( DEBUG_BIND,\r
+                "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",\r
+                pAddressInfo->Address.Addr [ 0 ],\r
+                pAddressInfo->Address.Addr [ 1 ],\r
+                pAddressInfo->Address.Addr [ 2 ],\r
+                pAddressInfo->Address.Addr [ 3 ],\r
+                pAddressInfo->Address.Addr [ 4 ],\r
+                pAddressInfo->Address.Addr [ 5 ],\r
+                pAddressInfo->Address.Addr [ 6 ],\r
+                pAddressInfo->Address.Addr [ 7 ],\r
+                pAddressInfo->Address.Addr [ 8 ],\r
+                pAddressInfo->Address.Addr [ 9 ],\r
+                pAddressInfo->Address.Addr [ 10 ],\r
+                pAddressInfo->Address.Addr [ 11 ],\r
+                pAddressInfo->Address.Addr [ 12 ],\r
+                pAddressInfo->Address.Addr [ 13 ],\r
+                pAddressInfo->Address.Addr [ 14 ],\r
+                pAddressInfo->Address.Addr [ 15 ]));\r
+\r
+      //\r
+      //  Validate the IP address\r
+      //\r
+      if (( pAccess->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])\r
+        && ( pAccess->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])\r
+        && ( pAccess->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])\r
+        && ( pAccess->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])\r
+        && ( pAccess->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])\r
+        && ( pAccess->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])\r
+        && ( pAccess->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])\r
+        && ( pAccess->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])\r
+        && ( pAccess->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])\r
+        && ( pAccess->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])\r
+        && ( pAccess->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])\r
+        && ( pAccess->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])\r
+        && ( pAccess->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])\r
+        && ( pAccess->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])\r
+        && ( pAccess->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])\r
+        && ( pAccess->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {\r
+        break;\r
+      }\r
+    }\r
+    if ( pIpConfigData->AddressInfoCount > AddressCount ) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  The IP address did not match\r
+    //\r
+    Status = EFI_NOT_STARTED;\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Free the buffer if necessary\r
+  //\r
+  if ( NULL != pIpConfigData ) {\r
+    FreePool ( pIpConfigData );\r
+  }\r
+\r
+  //\r
+  //  Return the IP address status\r
+  //\r
+  DBG_EXIT_STATUS ( Status );\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Interface between the socket layer and the network specific\r
   code that supports SOCK_STREAM and SOCK_SEQPACKET sockets\r
 /**\r
   Interface between the socket layer and the network specific\r
   code that supports SOCK_STREAM and SOCK_SEQPACKET sockets\r
@@ -2333,5 +2591,6 @@ CONST ESL_PROTOCOL_API cEslTcp6Api = {
   EslTcp6RxStart,\r
   EslTcp6TxBuffer,\r
   EslTcp6TxComplete,\r
   EslTcp6RxStart,\r
   EslTcp6TxBuffer,\r
   EslTcp6TxComplete,\r
-  EslTcp6TxOobComplete\r
+  EslTcp6TxOobComplete,\r
+  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslTcp6VerifyLocalIpAddress\r
 };\r
 };\r