]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Udp4.c
NetworkPkg: Remove IpSecDxe and Ip4Config Protocol dependency.
[mirror_edk2.git] / StdLib / EfiSocketLib / Udp4.c
index 026f850377278e186c4b74eac1547d23fdb4a1b3..7fece750958e0048075a2179b1f639c2a9a08d6c 100644 (file)
@@ -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
@@ -591,6 +591,7 @@ EslUdp4RxComplete (
     //\r
     //  Fill in the port list if necessary\r
     //\r
+    pSocket->errno = ENETDOWN;\r
     if ( NULL == pSocket->pPortList ) {\r
       LocalAddress.sin_len = sizeof ( LocalAddress );\r
       LocalAddress.sin_family = AF_INET;\r
@@ -640,34 +641,36 @@ EslUdp4RxComplete (
                                               NULL );\r
       }\r
       if ( EFI_ERROR ( Status )) {\r
-        DEBUG (( DEBUG_LISTEN,\r
-                  "ERROR - Failed to configure the Udp4 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
+        if ( !pSocket->bConfigured ) {\r
+          DEBUG (( DEBUG_LISTEN,\r
+                    "ERROR - Failed to configure the Udp4 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
+          case EFI_INVALID_PARAMETER:\r
+            pSocket->errno = EADDRNOTAVAIL;\r
+            break;\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
-        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
-        case EFI_UNSUPPORTED:\r
-          pSocket->errno = EOPNOTSUPP;\r
-          break;\r
+          case EFI_UNSUPPORTED:\r
+            pSocket->errno = EOPNOTSUPP;\r
+            break;\r
+          }\r
         }\r
       }\r
       else {\r
@@ -685,6 +688,7 @@ EslUdp4RxComplete (
                   pConfigData->RemoteAddress.Addr[3],\r
                   pConfigData->RemotePort ));\r
         pPort->bConfigured = TRUE;\r
+        pSocket->bConfigured = TRUE;\r
 \r
         //\r
         //  Start the first read on the port\r
@@ -695,6 +699,7 @@ EslUdp4RxComplete (
         //  The socket is connected\r
         //\r
         pSocket->State = SOCKET_STATE_CONNECTED;\r
+        pSocket->errno = 0;\r
       }\r
 \r
       //\r
@@ -702,21 +707,12 @@ EslUdp4RxComplete (
       //\r
       pPort = pNextPort;\r
     }\r
-\r
-    //\r
-    //  Determine the configuration status\r
-    //\r
-    if ( NULL != pSocket->pPortList ) {\r
-      pSocket->bConfigured = TRUE;\r
-    }\r
   }\r
 \r
   //\r
   //  Determine the socket configuration status\r
   //\r
-  if ( !EFI_ERROR ( Status )) {\r
-    Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
-  }\r
+  Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
   \r
   //\r
   //  Return the port connected state.\r
@@ -798,21 +794,21 @@ EslUdp4TxBuffer (
   //\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
-      pUdp4 = &pPort->Context.Udp4;\r
-      pTxBytes = &pSocket->TxBytes;\r
+      pPort = pSocket->pPortList;\r
+      while ( NULL != pPort ) {\r
+        //\r
+        //  Determine the queue head\r
+        //\r
+        pUdp4 = &pPort->Context.Udp4;\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
@@ -871,62 +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
+            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
@@ -939,16 +935,22 @@ EslUdp4TxBuffer (
           //  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
@@ -1001,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
@@ -1016,6 +1030,157 @@ 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_IPCONFIG_DATA * pIpConfigData;\r
+  EFI_IP4_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
+    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 ( pService->Controller,\r
+                                 &gEfiIp4ConfigProtocolGuid,\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
+                                          &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
+                                          &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: %d.%d.%d.%d\r\n",\r
+              pIpConfigData->StationAddress.Addr [ 0 ],\r
+              pIpConfigData->StationAddress.Addr [ 1 ],\r
+              pIpConfigData->StationAddress.Addr [ 2 ],\r
+              pIpConfigData->StationAddress.Addr [ 3 ]));\r
+\r
+    //\r
+    //  Assume the port is not configured\r
+    //\r
+    Status = EFI_SUCCESS;\r
+    if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])\r
+      && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])\r
+      && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])\r
+      && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->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 != 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_DGRAM sockets over UDPv4.\r
@@ -1054,5 +1219,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