]> 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 dd0f0864877817b8592b51945b2154be72f645dd..0f6d2d6ac93c24f85fa91dc99979a20590ea13f5 100644 (file)
@@ -1,18 +1,18 @@
 /** @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
+\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
+    //\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
@@ -247,27 +254,29 @@ EslTcp6ConnectComplete (
     //\r
     //  The connection failed\r
     //\r
-    DEBUG (( DEBUG_CONNECT,\r
-              "0x%08x: Port connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d failed, Status: %r\r\n",\r
-              pPort,\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],\r
-              pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],\r
-              pTcp6->ConfigData.AccessPoint.RemotePort,\r
-              Status ));\r
+    if ( pPort->bConfigured ) {\r
+      DEBUG (( DEBUG_CONNECT,\r
+                "0x%08x: Port connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d failed, Status: %r\r\n",\r
+                pPort,\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],\r
+                pTcp6->ConfigData.AccessPoint.RemotePort,\r
+                Status ));\r
+    }\r
 \r
     //\r
     //  Close the current port\r
@@ -290,7 +299,6 @@ EslTcp6ConnectComplete (
     //\r
     Status = EslTcp6ConnectStart ( pSocket );\r
     if ( EFI_NOT_READY != Status ) {\r
-      pSocket->ConnectStatus = Status;\r
       bRemoveFirstPort = TRUE;\r
     }\r
   }\r
@@ -386,49 +394,71 @@ EslTcp6ConnectPoll (
     //\r
     Status = pSocket->ConnectStatus;\r
     switch ( Status ) {\r
-    default:\r
-    case EFI_DEVICE_ERROR:\r
-      pSocket->errno = EIO;\r
-      break;\r
+      default:\r
+      case EFI_DEVICE_ERROR:\r
+        pSocket->errno = EIO;\r
+        break;\r
 \r
-    case EFI_ABORTED:\r
-      pSocket->errno = ECONNREFUSED;\r
-      break;\r
+      case EFI_ABORTED:\r
+        pSocket->errno = ECONNABORTED;\r
+        break;\r
 \r
-    case EFI_INVALID_PARAMETER:\r
-      pSocket->errno = EINVAL;\r
-      break;\r
+      case EFI_ACCESS_DENIED:\r
+        pSocket->errno = EACCES;\r
+        break;\r
 \r
-    case EFI_NO_MAPPING:\r
-    case EFI_NO_RESPONSE:\r
-      pSocket->errno = EHOSTUNREACH;\r
-      break;\r
+      case EFI_CONNECTION_RESET:\r
+        pSocket->errno = ECONNRESET;\r
+        break;\r
 \r
-    case EFI_NO_MEDIA:\r
-      pSocket->errno = ENETDOWN;\r
-      break;\r
+      case EFI_INVALID_PARAMETER:\r
+        pSocket->errno = EADDRNOTAVAIL;\r
+        break;\r
 \r
-    case EFI_OUT_OF_RESOURCES:\r
-      pSocket->errno = ENOMEM;\r
-      break;\r
+      case EFI_HOST_UNREACHABLE:\r
+      case EFI_NO_RESPONSE:\r
+        pSocket->errno = EHOSTUNREACH;\r
+        break;\r
 \r
-    case EFI_SUCCESS:\r
-      pSocket->errno = 0;\r
-      pSocket->bConfigured = TRUE;\r
-      break;\r
+      case EFI_NO_MAPPING:\r
+        pSocket->errno = EAFNOSUPPORT;\r
+        break;\r
 \r
-    case EFI_TIMEOUT:\r
-      pSocket->errno = ETIMEDOUT;\r
-      break;\r
+      case EFI_NO_MEDIA:\r
+      case EFI_NETWORK_UNREACHABLE:\r
+        pSocket->errno = ENETDOWN;\r
+        break;\r
 \r
-    case EFI_UNSUPPORTED:\r
-      pSocket->errno = ENOTSUP;\r
-      break;\r
+      case EFI_OUT_OF_RESOURCES:\r
+        pSocket->errno = ENOBUFS;\r
+        break;\r
 \r
-    case 0x80000069:\r
-      pSocket->errno = ECONNRESET;\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
+      case EFI_SUCCESS:\r
+        pSocket->errno = 0;\r
+        break;\r
+\r
+      case EFI_TIMEOUT:\r
+        pSocket->errno = ETIMEDOUT;\r
+        break;\r
+\r
+      case EFI_UNSUPPORTED:\r
+        pSocket->errno = EOPNOTSUPP;\r
+        break;\r
     }\r
+\r
+    //\r
+    //  Display the translation\r
+    //\r
+    DEBUG (( DEBUG_CONNECT,\r
+              "ERROR - errno: %d, Status: %r\r\n",\r
+              pSocket->errno,\r
+              Status ));\r
   }\r
 \r
   //\r
@@ -475,7 +505,7 @@ EslTcp6ConnectStart (
   EFI_STATUS Status;\r
 \r
   DBG_ENTER ( );\r
-  \r
+\r
   //\r
   //  Determine if any more local adapters are available\r
   //\r
@@ -495,32 +525,6 @@ EslTcp6ConnectStart (
       DEBUG (( DEBUG_CONNECT,\r
                 "ERROR - Failed to configure the Tcp6 port, Status: %r\r\n",\r
                 Status ));\r
-      switch ( Status ) {\r
-      case EFI_ACCESS_DENIED:\r
-        pSocket->errno = EACCES;\r
-        break;\r
-    \r
-      default:\r
-      case EFI_DEVICE_ERROR:\r
-        pSocket->errno = EIO;\r
-        break;\r
-    \r
-      case EFI_INVALID_PARAMETER:\r
-        pSocket->errno = EADDRNOTAVAIL;\r
-        break;\r
-    \r
-      case EFI_NO_MAPPING:\r
-        pSocket->errno = EAFNOSUPPORT;\r
-        break;\r
-    \r
-      case EFI_OUT_OF_RESOURCES:\r
-        pSocket->errno = ENOBUFS;\r
-        break;\r
-    \r
-      case EFI_UNSUPPORTED:\r
-        pSocket->errno = EOPNOTSUPP;\r
-        break;\r
-      }\r
     }\r
     else {\r
       DEBUG (( DEBUG_CONNECT,\r
@@ -543,18 +547,7 @@ EslTcp6ConnectStart (
           //\r
           //  Port is not connected to the network\r
           //\r
-          pTcp6->ConnectToken.CompletionToken.Status = EFI_NO_MEDIA;\r
-\r
-          //\r
-          //  Continue with the next port\r
-          //\r
-          gBS->CheckEvent ( pTcp6->ConnectToken.CompletionToken.Event );\r
-          gBS->SignalEvent ( pTcp6->ConnectToken.CompletionToken.Event );\r
-\r
-          //\r
-          //  Connection in progress\r
-          //\r
-          Status = EFI_SUCCESS;\r
+          Status = EFI_NO_MEDIA;\r
         }\r
         else {\r
           //\r
@@ -564,34 +557,7 @@ EslTcp6ConnectStart (
                                             &pTcp6->ConnectToken );\r
         }\r
       }\r
-      if ( !EFI_ERROR ( Status )) {\r
-        //\r
-        //  Connection in progress\r
-        //\r
-        pSocket->errno = EINPROGRESS;\r
-        Status = EFI_NOT_READY;\r
-        DEBUG (( DEBUG_CONNECT,\r
-                  "0x%08x: Port attempting connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
-                  pPort,\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],\r
-                  pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],\r
-                  pTcp6->ConfigData.AccessPoint.RemotePort ));\r
-      }\r
-      else {\r
+      if ( EFI_ERROR ( Status )) {\r
         //\r
         //  Connection error\r
         //\r
@@ -599,43 +565,50 @@ EslTcp6ConnectStart (
                   "ERROR - Port 0x%08x not connected, Status: %r\r\n",\r
                   pPort,\r
                   Status ));\r
-        //\r
-        //  Determine the errno value\r
-        //\r
-        switch ( Status ) {\r
-        default:\r
-          pSocket->errno = EIO;\r
-          break;\r
-\r
-        case EFI_OUT_OF_RESOURCES:\r
-          pSocket->errno = ENOBUFS;\r
-          break;\r
-\r
-        case EFI_TIMEOUT:\r
-          pSocket->errno = ETIMEDOUT;\r
-          break;\r
-\r
-        case EFI_NO_MEDIA:\r
-        case EFI_NETWORK_UNREACHABLE:\r
-          pSocket->errno = ENETDOWN;\r
-          break;\r
-\r
-        case EFI_HOST_UNREACHABLE:\r
-          pSocket->errno = EHOSTUNREACH;\r
-          break;\r
-\r
-        case EFI_PORT_UNREACHABLE:\r
-        case EFI_PROTOCOL_UNREACHABLE:\r
-        case EFI_CONNECTION_REFUSED:\r
-          pSocket->errno = ECONNREFUSED;\r
-          break;\r
-\r
-        case EFI_CONNECTION_RESET:\r
-          pSocket->errno = ECONNRESET;\r
-          break;\r
-        }\r
       }\r
     }\r
+    if ( !EFI_ERROR ( Status )) {\r
+      //\r
+      //  Connection in progress\r
+      //\r
+      pSocket->errno = EINPROGRESS;\r
+      DEBUG (( DEBUG_CONNECT,\r
+                "0x%08x: Port attempting connection to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
+                pPort,\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[4],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[5],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[6],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[7],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[8],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[9],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[10],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[11],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[12],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[13],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[14],\r
+                pTcp6->ConfigData.AccessPoint.RemoteAddress.Addr[15],\r
+                pTcp6->ConfigData.AccessPoint.RemotePort ));\r
+    }\r
+    else {\r
+      //\r
+      //  Error return path is through EslTcp6ConnectComplete to\r
+      //  enable retry on other ports\r
+      //\r
+      //  Status to errno translation gets done in EslTcp4ConnectPoll\r
+      //\r
+      pTcp6->ConnectToken.CompletionToken.Status = Status;\r
+\r
+      //\r
+      //  Continue with the next port\r
+      //\r
+      gBS->CheckEvent ( pTcp6->ConnectToken.CompletionToken.Event );\r
+      gBS->SignalEvent ( pTcp6->ConnectToken.CompletionToken.Event );\r
+    }\r
+    Status = EFI_NOT_READY;\r
   }\r
   else {\r
     //\r
@@ -834,7 +807,7 @@ EslTcp6Listen (
       //\r
       pPort = pNextPort;\r
     }\r
-    \r
+\r
     //\r
     //  Determine if any ports are in the listen state\r
     //\r
@@ -854,6 +827,8 @@ EslTcp6Listen (
     //  Mark the socket as configured\r
     //\r
     pSocket->bConfigured = TRUE;\r
+    Status = EFI_SUCCESS;\r
+    pSocket->errno = 0;\r
 \r
     //\r
     //  All done\r
@@ -896,7 +871,6 @@ EslTcp6ListenComplete (
   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
@@ -925,7 +899,6 @@ EslTcp6ListenComplete (
     //  Allocate a socket for this connection\r
     //\r
     ChildHandle = NULL;\r
-    pLayer = &mEslLayer;\r
     Status = EslSocketAllocate ( &ChildHandle,\r
                                  DEBUG_CONNECTION,\r
                                  &pNewSocket );\r
@@ -1123,7 +1096,7 @@ EslTcp6ListenComplete (
     //  Process:\r
     //    Call close\r
     //    Release the resources\r
-    \r
+\r
   }\r
 \r
   DBG_EXIT ( );\r
@@ -1422,7 +1395,7 @@ EslTcp6PortAllocate (
 \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
@@ -1437,7 +1410,7 @@ EslTcp6PortClose (
   UINTN DebugFlags;\r
   ESL_TCP6_CONTEXT * pTcp6;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
 \r
   //\r
@@ -1581,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
-  \r
+\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
-  \r
+\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
@@ -1982,13 +1955,13 @@ EslTcp6RxStart (
   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
-  \r
+\r
   @param [in] BufferLength    Length of the the buffer\r
-  \r
+\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
@@ -2018,7 +1991,6 @@ EslTcp6TxBuffer (
   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
@@ -2045,7 +2017,6 @@ EslTcp6TxBuffer (
       //\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
@@ -2236,7 +2207,7 @@ EslTcp6TxComplete (
   ESL_PORT * pPort;\r
   ESL_SOCKET * pSocket;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
 \r
   //\r
@@ -2325,6 +2296,262 @@ EslTcp6TxOobComplete (
 }\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
@@ -2364,5 +2591,6 @@ CONST ESL_PROTOCOL_API cEslTcp6Api = {
   EslTcp6RxStart,\r
   EslTcp6TxBuffer,\r
   EslTcp6TxComplete,\r
-  EslTcp6TxOobComplete\r
+  EslTcp6TxOobComplete,\r
+  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslTcp6VerifyLocalIpAddress\r
 };\r