]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Udp4.c
StdLib: Remove EfiSocketLib and Ip4Config Protocol dependency.
[mirror_edk2.git] / StdLib / EfiSocketLib / Udp4.c
index 414e3fe321a4c076c9f0d64d4f252b9a65f093ff..ef2f9e321b2d50f856009233e21ffcd733b6a1e6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implement the UDP4 driver support for the socket layer.\r
 \r
-  Copyright (c) 2011, Intel Corporation\r
+  Copyright (c) 2011 - 2015, 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
@@ -266,7 +266,7 @@ EslUdp4PortAllocate (
   pConfig->AcceptBroadcast = FALSE;\r
   pConfig->AcceptPromiscuous = FALSE;\r
   pConfig->AllowDuplicatePort = TRUE;\r
-  pConfig->DoNotFragment = TRUE;\r
+  pConfig->DoNotFragment = FALSE;\r
   Status = EFI_SUCCESS;\r
 \r
   //\r
@@ -867,63 +867,62 @@ EslUdp4TxBuffer (
           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 %s bytes from 0x%08x\r\n",\r
-                      BufferLength,\r
-                      pBuffer ));\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 to %d.%d.%d.%d:%d\r\n",\r
+                    BufferLength,\r
+                    pBuffer,\r
+                    pTxData->Session.DestinationAddress.Addr[0],\r
+                    pTxData->Session.DestinationAddress.Addr[1],\r
+                    pTxData->Session.DestinationAddress.Addr[2],\r
+                    pTxData->Session.DestinationAddress.Addr[3],\r
+                    pTxData->Session.DestinationPort ));\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
+            pPacket = pSocket->pTxPacketListHead;\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
-            break;\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
@@ -1004,6 +1003,18 @@ EslUdp4TxComplete (
   pSocket->TxBytes -= LengthInBytes;\r
   Status = pIo->Token.Udp4Tx.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
@@ -1019,6 +1030,165 @@ EslUdp4TxComplete (
 }\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
+EslUdp4VerifyLocalIpAddress (\r
+  IN ESL_PORT * pPort,\r
+  IN EFI_UDP4_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_DGRAM sockets over UDPv4.\r
@@ -1057,5 +1227,6 @@ CONST ESL_PROTOCOL_API cEslUdp4Api = {
   NULL,   //  RxStart\r
   EslUdp4TxBuffer,\r
   EslUdp4TxComplete,\r
-  NULL    //  TxOobComplete\r
+  NULL,   //  TxOobComplete\r
+  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslUdp4VerifyLocalIpAddress\r
 };\r