]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Ip4.c
StdLib: Remove EfiSocketLib and Ip4Config Protocol dependency.
[mirror_edk2.git] / StdLib / EfiSocketLib / Ip4.c
index a245e6847e25a0fba58445f7b99f2b278bde2c19..d3531b89288d8786c570068e784da0369ef9f236 100644 (file)
@@ -1,22 +1,19 @@
 /** @file\r
   Implement the IP4 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 - 2015, 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
-\r
 #include "Socket.h"\r
 \r
 \r
-/**\r
-  Get the local socket address\r
+/** Get the local socket address.\r
 \r
   This routine returns the IPv4 address associated with the local\r
   socket.\r
@@ -25,9 +22,7 @@
   network address for the SOCK_RAW socket.\r
 \r
   @param [in] pPort       Address of an ::ESL_PORT structure.\r
-\r
   @param [out] pAddress   Network address to receive the local system address\r
-\r
 **/\r
 VOID\r
 EslIp4LocalAddressGet (\r
@@ -40,9 +35,7 @@ EslIp4LocalAddressGet (
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Return the local address\r
-  //\r
   pIp4 = &pPort->Context.Ip4;\r
   pLocalAddress = (struct sockaddr_in *)pAddress;\r
   pLocalAddress->sin_family = AF_INET;\r
@@ -54,8 +47,7 @@ EslIp4LocalAddressGet (
 }\r
 \r
 \r
-/**\r
-  Set the local port address.\r
+/** Set the local port address.\r
 \r
   This routine sets the local port address.\r
 \r
@@ -75,7 +67,6 @@ EslIp4LocalAddressGet (
   @param [in] bBindTest   TRUE = run bind testing\r
 \r
   @retval EFI_SUCCESS     The operation was successful\r
-\r
  **/\r
 EFI_STATUS\r
 EslIp4LocalAddressSet (\r
@@ -91,23 +82,17 @@ EslIp4LocalAddressSet (
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Validate the address\r
-  //\r
   pIpAddress = (struct sockaddr_in *)pSockAddr;\r
   if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {\r
-    //\r
     //  The local address must not be the broadcast address\r
-    //\r
     Status = EFI_INVALID_PARAMETER;\r
     pPort->pSocket->errno = EADDRNOTAVAIL;\r
   }\r
   else {\r
     Status = EFI_SUCCESS;\r
 \r
-    //\r
     //  Set the local address\r
-    //\r
     pIpAddress = (struct sockaddr_in *)pSockAddr;\r
     pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;\r
     pConfig = &pPort->Context.Ip4.ModeData.ConfigData;\r
@@ -116,14 +101,10 @@ EslIp4LocalAddressSet (
     pConfig->StationAddress.Addr[2] = pIpv4Address[2];\r
     pConfig->StationAddress.Addr[3] = pIpv4Address[3];\r
 \r
-    //\r
     //  Determine if the default address is used\r
-    //\r
     pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );\r
 \r
-    //\r
     //  Display the local address\r
-    //\r
     DEBUG (( DEBUG_BIND,\r
               "0x%08x: Port, Local IP4 Address: %d.%d.%d.%d\r\n",\r
               pPort,\r
@@ -132,9 +113,7 @@ EslIp4LocalAddressSet (
               pConfig->StationAddress.Addr[2],\r
               pConfig->StationAddress.Addr[3]));\r
 \r
-    //\r
     //  Set the subnet mask\r
-    //\r
     if ( pConfig->UseDefaultAddress ) {\r
       pConfig->SubnetMask.Addr[0] = 0;\r
       pConfig->SubnetMask.Addr[1] = 0;\r
@@ -148,17 +127,13 @@ EslIp4LocalAddressSet (
       pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;\r
     }\r
   }\r
-\r
-  //\r
   //  Return the operation status\r
-  //\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
 \r
 \r
-/**\r
-  Get the option value\r
+/** Get the option value.\r
 \r
   This routine handles the IPv4 level options.\r
 \r
@@ -171,7 +146,6 @@ EslIp4LocalAddressSet (
   @param [out] pOptionLength    Buffer to receive the option length\r
 \r
   @retval EFI_SUCCESS - Socket data successfully received\r
-\r
  **/\r
 EFI_STATUS\r
 EslIp4OptionGet (\r
@@ -185,20 +159,14 @@ EslIp4OptionGet (
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Assume success\r
-  //\r
   pSocket->errno = 0;\r
   Status = EFI_SUCCESS;\r
 \r
-  //\r
   //  Attempt to get the option\r
-  //\r
   switch ( OptionName ) {\r
   default:\r
-    //\r
     //  Option not supported\r
-    //\r
     pSocket->errno = ENOPROTOOPT;\r
     Status = EFI_INVALID_PARAMETER;\r
     break;\r
@@ -208,17 +176,13 @@ EslIp4OptionGet (
     *pOptionLength = sizeof ( pSocket->bIncludeHeader );\r
     break;\r
   }\r
-\r
-  //\r
   //  Return the operation status\r
-  //\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
 \r
 \r
-/**\r
-  Set the option value\r
+/** Set the option value.\r
 \r
   This routine handles the IPv4 level options.\r
 \r
@@ -231,7 +195,6 @@ EslIp4OptionGet (
   @param [in] OptionLength    Length of the buffer in bytes\r
 \r
   @retval EFI_SUCCESS - Option successfully set\r
-\r
  **/\r
 EFI_STATUS\r
 EslIp4OptionSet (\r
@@ -242,28 +205,22 @@ EslIp4OptionSet (
   )\r
 {\r
   BOOLEAN bTrueFalse;\r
-  socklen_t LengthInBytes;\r
-  UINT8 * pOptionData;\r
+  //socklen_t LengthInBytes;\r
+  //UINT8 * pOptionData;\r
   EFI_STATUS Status;\r
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Assume success\r
-  //\r
   pSocket->errno = 0;\r
   Status = EFI_SUCCESS;\r
 \r
-  //\r
   //  Determine if the option protocol matches\r
-  //\r
-  LengthInBytes = 0;\r
-  pOptionData = NULL;\r
+  //LengthInBytes = 0;\r
+  //pOptionData = NULL;\r
   switch ( OptionName ) {\r
   default:\r
-    //\r
     //  Protocol level not supported\r
-    //\r
     DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid protocol option\r\n" ));\r
     pSocket->errno = ENOTSUP;\r
     Status = EFI_UNSUPPORTED;\r
@@ -271,31 +228,22 @@ EslIp4OptionSet (
 \r
   case IP_HDRINCL:\r
 \r
-    //\r
     //  Validate the option length\r
-    //\r
     if ( sizeof ( UINT32 ) == OptionLength ) {\r
-      //\r
       //  Restrict the input to TRUE or FALSE\r
-      //\r
       bTrueFalse = TRUE;\r
       if ( 0 == *(UINT32 *)pOptionValue ) {\r
         bTrueFalse = FALSE;\r
       }\r
       pOptionValue = &bTrueFalse;\r
 \r
-      //\r
       //  Set the option value\r
-      //\r
-      pOptionData = (UINT8 *)&pSocket->bIncludeHeader;\r
-      LengthInBytes = sizeof ( pSocket->bIncludeHeader );\r
+      //pOptionData = (UINT8 *)&pSocket->bIncludeHeader;\r
+      //LengthInBytes = sizeof ( pSocket->bIncludeHeader );\r
     }\r
     break;\r
   }\r
-\r
-  //\r
   //  Return the operation status\r
-  //\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
@@ -430,13 +378,13 @@ EslIp4PortAllocate (
   @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
@@ -653,17 +601,15 @@ EslIp4RxComplete (
   )\r
 {\r
   size_t LengthInBytes;\r
-  ESL_PORT * pPort;\r
   ESL_PACKET * pPacket;\r
   EFI_IP4_RECEIVE_DATA * pRxData;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
-  \r
+\r
   //\r
   //  Get the operation status.\r
   //\r
-  pPort = pIo->pPort;\r
   Status = pIo->Token.Ip4Rx.Status;\r
 \r
   //\r
@@ -672,7 +618,7 @@ EslIp4RxComplete (
   pRxData = pIo->Token.Ip4Rx.Packet.RxData;\r
   LengthInBytes = pRxData->HeaderLength + pRxData->DataLength;\r
 \r
-  //\r
+  //{{\r
   //      +--------------------+   +----------------------+\r
   //      | ESL_IO_MGMT        |   |      Data Buffer     |\r
   //      |                    |   |     (Driver owned)   |\r
@@ -692,7 +638,7 @@ EslIp4RxComplete (
   //\r
   //\r
   //  Save the data in the packet\r
-  //\r
+  //}}\r
   pPacket = pIo->pPacket;\r
   pPacket->Op.Ip4Rx.pRxData = pRxData;\r
 \r
@@ -717,7 +663,7 @@ EslIp4RxComplete (
   that the socket is configured.\r
 \r
   @param [in] pSocket         Address of an ::ESL_SOCKET structure\r
-  \r
+\r
   @retval EFI_SUCCESS - The port is connected\r
   @retval EFI_NOT_STARTED - The port is not connected\r
 \r
@@ -904,7 +850,7 @@ EslIp4RxComplete (
   //  Determine the socket configuration status\r
   //\r
   Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
-  \r
+\r
   //\r
   //  Return the port connected state.\r
   //\r
@@ -985,21 +931,21 @@ EslIp4TxBuffer (
   //\r
   if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
     //\r
-    //  Locate the port\r
+    //  Verify that there is enough room to buffer another\r
+    //  transmit operation\r
     //\r
-    pPort = pSocket->pPortList;\r
-    if ( NULL != pPort ) {\r
+    pTxBytes = &pSocket->TxBytes;\r
+    if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
       //\r
-      //  Determine the queue head\r
+      //  Locate the port\r
       //\r
-      pIp4 = &pPort->Context.Ip4;\r
-      pTxBytes = &pSocket->TxBytes;\r
+      pPort = pSocket->pPortList;\r
+      while ( NULL != pPort ) {\r
+        //\r
+        //  Determine the queue head\r
+        //\r
+        pIp4 = &pPort->Context.Ip4;\r
 \r
-      //\r
-      //  Verify that there is enough room to buffer another\r
-      //  transmit operation\r
-      //\r
-      if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
         //\r
         //  Attempt to allocate the packet\r
         //\r
@@ -1067,70 +1013,64 @@ EslIp4TxBuffer (
           RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
 \r
           //\r
-          //  Stop transmission after an error\r
+          //  Display the request\r
           //\r
-          if ( !EFI_ERROR ( pSocket->TxError )) {\r
-            //\r
-            //  Display the request\r
-            //\r
-            DEBUG (( DEBUG_TX,\r
-                      "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",\r
-                      BufferLength,\r
-                      pBuffer,\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
-                      pTxData->TxData.DestinationAddress.Addr[0],\r
-                      pTxData->TxData.DestinationAddress.Addr[1],\r
-                      pTxData->TxData.DestinationAddress.Addr[2],\r
-                      pTxData->TxData.DestinationAddress.Addr[3]));\r
-\r
-            //\r
-            //  Queue the data for transmission\r
-            //\r
-            pPacket->pNext = NULL;\r
-            pPreviousPacket = pSocket->pTxPacketListTail;\r
-            if ( NULL == pPreviousPacket ) {\r
-              pSocket->pTxPacketListHead = pPacket;\r
-            }\r
-            else {\r
-              pPreviousPacket->pNext = pPacket;\r
-            }\r
-            pSocket->pTxPacketListTail = pPacket;\r
-            DEBUG (( DEBUG_TX,\r
-                      "0x%08x: Packet on transmit list\r\n",\r
-                      pPacket ));\r
-\r
-            //\r
-            //  Account for the buffered data\r
-            //\r
-            *pTxBytes += BufferLength;\r
-            *pDataLength = BufferLength;\r
+          DEBUG (( DEBUG_TX,\r
+                    "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",\r
+                    BufferLength,\r
+                    pBuffer,\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
+                    pTxData->TxData.DestinationAddress.Addr[0],\r
+                    pTxData->TxData.DestinationAddress.Addr[1],\r
+                    pTxData->TxData.DestinationAddress.Addr[2],\r
+                    pTxData->TxData.DestinationAddress.Addr[3]));\r
 \r
-            //\r
-            //  Start the transmit engine if it is idle\r
-            //\r
-            if ( NULL != pPort->pTxFree ) {\r
-              EslSocketTxStart ( pPort,\r
-                                 &pSocket->pTxPacketListHead,\r
-                                 &pSocket->pTxPacketListTail,\r
-                                 &pPort->pTxActive,\r
-                                 &pPort->pTxFree );\r
-            }\r
+          //\r
+          //  Queue the data for transmission\r
+          //\r
+          pPacket->pNext = NULL;\r
+          pPreviousPacket = pSocket->pTxPacketListTail;\r
+          if ( NULL == pPreviousPacket ) {\r
+            pSocket->pTxPacketListHead = pPacket;\r
           }\r
           else {\r
-            //\r
-            //  Previous transmit error\r
-            //  Stop transmission\r
-            //\r
-            Status = pSocket->TxError;\r
-            pSocket->errno = EIO;\r
+            pPreviousPacket->pNext = pPacket;\r
+          }\r
+          pSocket->pTxPacketListTail = pPacket;\r
+          DEBUG (( DEBUG_TX,\r
+                    "0x%08x: Packet on transmit list\r\n",\r
+                    pPacket ));\r
+\r
+          //\r
+          //  Account for the buffered data\r
+          //\r
+          *pTxBytes += BufferLength;\r
+          *pDataLength = BufferLength;\r
+\r
+          //\r
+          //  Start the transmit engine if it is idle\r
+          //\r
+          if ( NULL != pPort->pTxFree ) {\r
+            EslSocketTxStart ( pPort,\r
+                               &pSocket->pTxPacketListHead,\r
+                               &pSocket->pTxPacketListTail,\r
+                               &pPort->pTxActive,\r
+                               &pPort->pTxFree );\r
 \r
             //\r
-            //  Free the packet\r
+            //  Ignore any transmit error\r
             //\r
-            EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+            if ( EFI_ERROR ( pSocket->TxError )) {\r
+              DEBUG (( DEBUG_TX,\r
+                       "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",\r
+                       pPort,\r
+                       pPacket,\r
+                       pSocket->TxError ));\r
+            }\r
+            pSocket->TxError = EFI_SUCCESS;\r
           }\r
 \r
           //\r
@@ -1143,16 +1083,22 @@ EslIp4TxBuffer (
           //  Packet allocation failed\r
           //\r
           pSocket->errno = ENOMEM;\r
+          break;\r
         }\r
-      }\r
-      else {\r
+\r
         //\r
-        //  Not enough buffer space available\r
+        //  Set the next port\r
         //\r
-        pSocket->errno = EAGAIN;\r
-        Status = EFI_NOT_READY;\r
+        pPort = pPort->pLinkSocket;\r
       }\r
     }\r
+    else {\r
+      //\r
+      //  Not enough buffer space available\r
+      //\r
+      pSocket->errno = EAGAIN;\r
+      Status = EFI_NOT_READY;\r
+    }\r
   }\r
 \r
   //\r
@@ -1188,9 +1134,9 @@ EslIp4TxComplete (
   ESL_PACKET * pPacket;\r
   ESL_SOCKET * pSocket;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
-  \r
+\r
   //\r
   //  Locate the active transmit packet\r
   //\r
@@ -1205,6 +1151,18 @@ EslIp4TxComplete (
   pSocket->TxBytes -= LengthInBytes;\r
   Status = pIo->Token.Ip4Tx.Status;\r
 \r
+  //\r
+  //  Ignore the transmit error\r
+  //\r
+  if ( EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_TX,\r
+             "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",\r
+             pPort,\r
+             pPacket,\r
+             Status ));\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   //  Complete the transmit operation\r
   //\r
@@ -1220,6 +1178,165 @@ EslIp4TxComplete (
 }\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
+EslIp4VerifyLocalIpAddress (\r
+  IN ESL_PORT * pPort,\r
+  IN EFI_IP4_CONFIG_DATA * pConfigData\r
+  )\r
+{\r
+  UINTN DataSize;\r
+  EFI_IP4_CONFIG2_INTERFACE_INFO * pIfInfo;\r
+  EFI_IP4_CONFIG2_PROTOCOL * pIpConfig2Protocol;\r
+  ESL_SERVICE * pService;\r
+  EFI_STATUS Status;\r
+\r
+  DBG_ENTER ( );\r
+\r
+  //\r
+  //  Use break instead of goto\r
+  //\r
+  pIfInfo = NULL;\r
+  for ( ; ; ) {\r
+    //\r
+    //  Determine if the IP address is specified\r
+    //\r
+    DEBUG (( DEBUG_BIND,\r
+              "UseDefaultAddress: %s\r\n",\r
+              pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));\r
+    DEBUG (( DEBUG_BIND,\r
+              "Requested IP address: %d.%d.%d.%d\r\n",\r
+              pConfigData->StationAddress.Addr [ 0 ],\r
+              pConfigData->StationAddress.Addr [ 1 ],\r
+              pConfigData->StationAddress.Addr [ 2 ],\r
+              pConfigData->StationAddress.Addr [ 3 ]));\r
+    if ( pConfigData->UseDefaultAddress\r
+      || (( 0 == pConfigData->StationAddress.Addr [ 0 ])\r
+      && ( 0 == pConfigData->StationAddress.Addr [ 1 ])\r
+      && ( 0 == pConfigData->StationAddress.Addr [ 2 ])\r
+      && ( 0 == pConfigData->StationAddress.Addr [ 3 ])))\r
+    {\r
+      Status = EFI_SUCCESS;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Open the configuration protocol\r
+    //\r
+    pService = pPort->pService;\r
+    Status = gBS->OpenProtocol ( \r
+                    pService->Controller,\r
+                    &gEfiIp4Config2ProtocolGuid,\r
+                    (VOID **)&pIpConfig2Protocol,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL \r
+                    );\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 interface information size.\r
+    //\r
+    DataSize = 0;\r
+    Status = pIpConfig2Protocol->GetData ( \r
+                                   pIpConfig2Protocol,\r
+                                   Ip4Config2DataTypeInterfaceInfo,\r
+                                   &DataSize,\r
+                                   NULL\r
+                                   );\r
+    if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to get the interface information size, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Allocate the interface information buffer\r
+    //\r
+    pIfInfo = AllocatePool ( DataSize );\r
+    if ( NULL == pIfInfo ) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Not enough memory to allocate the interface information buffer!\r\n" ));\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Get the interface info.\r
+    //\r
+    Status = pIpConfig2Protocol->GetData ( \r
+                                  pIpConfig2Protocol,\r
+                                  Ip4Config2DataTypeInterfaceInfo,\r
+                                  &DataSize,\r
+                                  pIfInfo\r
+                                  );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to return the interface info, 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: %d.%d.%d.%d\r\n",\r
+              pIfInfo->StationAddress.Addr [ 0 ],\r
+              pIfInfo->StationAddress.Addr [ 1 ],\r
+              pIfInfo->StationAddress.Addr [ 2 ],\r
+              pIfInfo->StationAddress.Addr [ 3 ]));\r
+\r
+    //\r
+    //  Assume the port is not configured\r
+    //\r
+    Status = EFI_SUCCESS;\r
+    if (( pConfigData->StationAddress.Addr [ 0 ] == pIfInfo->StationAddress.Addr [ 0 ])\r
+      && ( pConfigData->StationAddress.Addr [ 1 ] == pIfInfo->StationAddress.Addr [ 1 ])\r
+      && ( pConfigData->StationAddress.Addr [ 2 ] == pIfInfo->StationAddress.Addr [ 2 ])\r
+      && ( pConfigData->StationAddress.Addr [ 3 ] == pIfInfo->StationAddress.Addr [ 3 ])) {\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 != pIfInfo ) {\r
+    FreePool ( pIfInfo );\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_RAW sockets over IPv4.\r
@@ -1258,5 +1375,6 @@ CONST ESL_PROTOCOL_API cEslIp4Api = {
   NULL,   //  RxStart\r
   EslIp4TxBuffer,\r
   EslIp4TxComplete,\r
-  NULL    //  TxOobComplete\r
+  NULL,   //  TxOobComplete\r
+  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslIp4VerifyLocalIpAddress\r
 };\r