]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
MdeModulePkg: Removing ipf which is no longer supported from edk2.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Rrq.c
index 524db8ff635cdfff8c97756007ce07910257f108..63115ba5195866f0220c3a869d2984ac79190548 100644 (file)
@@ -1,8 +1,9 @@
 /** @file\r
   Routines to process Rrq (download).\r
-  \r
-Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+\r
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+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<BR>\r
@@ -26,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 VOID\r
+EFIAPI\r
 Mtftp4RrqInput (\r
   IN NET_BUF                *UdpPacket,\r
   IN UDP_END_POINT          *EndPoint,\r
@@ -35,9 +37,9 @@ Mtftp4RrqInput (
 \r
 \r
 /**\r
-  Start the MTFTP session to download. \r
-  \r
-  It will first initialize some of the internal states then build and send a RRQ \r
+  Start the MTFTP session to download.\r
+\r
+  It will first initialize some of the internal states then build and send a RRQ\r
   reqeuest packet, at last, it will start receive for the downloading.\r
 \r
   @param  Instance              The Mtftp session\r
@@ -144,15 +146,19 @@ Mtftp4RrqSaveBlock (
   UINT16                    Block;\r
   UINT64                    Start;\r
   UINT32                    DataLen;\r
+  UINT64                    TotalBlock;\r
+  BOOLEAN                   Completed;\r
 \r
-  Token   = Instance->Token;\r
-  Block   = NTOHS (Packet->Data.Block);\r
-  DataLen = Len - MTFTP4_DATA_HEAD_LEN;\r
+  Completed = FALSE;\r
+  Token     = Instance->Token;\r
+  Block     = NTOHS (Packet->Data.Block);\r
+  DataLen   = Len - MTFTP4_DATA_HEAD_LEN;\r
 \r
   //\r
   // This is the last block, save the block no\r
   //\r
   if (DataLen < Instance->BlkSize) {\r
+  Completed = TRUE;\r
     Instance->LastBlock = Block;\r
     Mtftp4SetLastBlockNum (&Instance->Blocks, Block);\r
   }\r
@@ -160,8 +166,11 @@ Mtftp4RrqSaveBlock (
   //\r
   // Remove this block number from the file hole. If Mtftp4RemoveBlockNum\r
   // returns EFI_NOT_FOUND, the block has been saved, don't save it again.\r
+  // Note that : For bigger files, allowing the block counter to roll over\r
+  // to accept transfers of unlimited size. So TotalBlock is memorised as\r
+  // continuous block counter.\r
   //\r
-  Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block);\r
+  Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block, Completed, &TotalBlock);\r
 \r
   if (Status == EFI_NOT_FOUND) {\r
     return EFI_SUCCESS;\r
@@ -184,7 +193,7 @@ Mtftp4RrqSaveBlock (
   }\r
 \r
   if (Token->Buffer != NULL) {\r
-    Start = MultU64x32 (Block - 1, Instance->BlkSize);\r
+     Start = MultU64x32 (TotalBlock - 1, Instance->BlkSize);\r
 \r
     if (Start + DataLen <= Token->BufferSize) {\r
       CopyMem ((UINT8 *) Token->Buffer + Start, Packet->Data.Data, DataLen);\r
@@ -192,7 +201,7 @@ Mtftp4RrqSaveBlock (
       //\r
       // Update the file size when received the last block\r
       //\r
-      if (Instance->LastBlock == Block) {\r
+      if ((Instance->LastBlock == Block) && Completed) {\r
         Token->BufferSize = Start + DataLen;\r
       }\r
 \r
@@ -219,8 +228,8 @@ Mtftp4RrqSaveBlock (
 \r
 \r
 /**\r
-  Function to process the received data packets. \r
-  \r
+  Function to process the received data packets.\r
+\r
   It will save the block then send back an ACK if it is active.\r
 \r
   @param  Instance              The downloading MTFTP session\r
@@ -309,7 +318,7 @@ Mtftp4RrqHandleData (
 \r
 /**\r
   Validate whether the options received in the server's OACK packet is valid.\r
-  \r
+\r
   The options are valid only if:\r
   1. The server doesn't include options not requested by us\r
   2. The server can only use smaller blksize than that is requested\r
@@ -379,6 +388,7 @@ Mtftp4RrqOackValid (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 Mtftp4RrqConfigMcastPort (\r
   IN UDP_IO                 *McastIo,\r
   IN VOID                   *Context\r
@@ -404,13 +414,13 @@ Mtftp4RrqConfigMcastPort (
   UdpConfig.ReceiveTimeout     = 0;\r
   UdpConfig.TransmitTimeout    = 0;\r
   UdpConfig.UseDefaultAddress  = Config->UseDefaultSetting;\r
-  UdpConfig.StationAddress     = Config->StationIp;\r
-  UdpConfig.SubnetMask         = Config->SubnetMask;\r
+  IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);\r
+  IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);\r
   UdpConfig.StationPort        = Instance->McastPort;\r
   UdpConfig.RemotePort         = 0;\r
 \r
   Ip = HTONL (Instance->ServerIp);\r
-  CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+  IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);\r
 \r
   Status = McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig);\r
 \r
@@ -418,20 +428,20 @@ Mtftp4RrqConfigMcastPort (
     return Status;\r
   }\r
 \r
-  if (!Config->UseDefaultSetting && \r
+  if (!Config->UseDefaultSetting &&\r
       !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {\r
     //\r
     // The station IP address is manually configured and the Gateway IP is not 0.\r
     // Add the default route for this UDP instance.\r
     //\r
     Status = McastIo->Protocol.Udp4->Routes (\r
-                                       McastIo->Protocol.Udp4, \r
+                                       McastIo->Protocol.Udp4,\r
                                        FALSE,\r
                                        &mZeroIp4Addr,\r
                                        &mZeroIp4Addr,\r
                                        &Config->GatewayIp\r
                                        );\r
-                             \r
+\r
     if (EFI_ERROR (Status)) {\r
       McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, NULL);\r
       return Status;\r
@@ -442,15 +452,15 @@ Mtftp4RrqConfigMcastPort (
   // join the multicast group\r
   //\r
   Ip = HTONL (Instance->McastIp);\r
-  CopyMem (&Group, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+  IP4_COPY_ADDRESS (&Group, &Ip);\r
 \r
   return McastIo->Protocol.Udp4->Groups (McastIo->Protocol.Udp4, TRUE, &Group);\r
 }\r
 \r
 \r
 /**\r
-  Function to process the OACK. \r
-  \r
+  Function to process the OACK.\r
+\r
   It will first validate the OACK packet, then update the various negotiated parameters.\r
 \r
   @param  Instance              The download MTFTP session\r
@@ -477,6 +487,7 @@ Mtftp4RrqHandleOack (
   MTFTP4_OPTION             Reply;\r
   EFI_STATUS                Status;\r
   INTN                      Expected;\r
+  EFI_UDP4_PROTOCOL         *Udp4;\r
 \r
   *Completed = FALSE;\r
 \r
@@ -539,13 +550,31 @@ Mtftp4RrqHandleOack (
       //\r
       Instance->McastIp      = Reply.McastIp;\r
       Instance->McastPort    = Reply.McastPort;\r
-      Instance->McastUdpPort = UdpIoCreateIo (\r
-                                 Instance->Service->Controller,\r
-                                 Instance->Service->Image,\r
-                                 Mtftp4RrqConfigMcastPort,\r
-                                 UDP_IO_UDP4_VERSION,\r
-                                 Instance\r
-                                 );\r
+      if (Instance->McastUdpPort == NULL) {\r
+        Instance->McastUdpPort = UdpIoCreateIo (\r
+                                   Instance->Service->Controller,\r
+                                   Instance->Service->Image,\r
+                                   Mtftp4RrqConfigMcastPort,\r
+                                   UDP_IO_UDP4_VERSION,\r
+                                   Instance\r
+                                   );\r
+        if (Instance->McastUdpPort != NULL) {\r
+          Status = gBS->OpenProtocol (\r
+                          Instance->McastUdpPort->UdpHandle,\r
+                          &gEfiUdp4ProtocolGuid,\r
+                          (VOID **) &Udp4,\r
+                          Instance->Service->Image,\r
+                          Instance->Handle,\r
+                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                          );\r
+          if (EFI_ERROR (Status)) {\r
+            UdpIoFreeIo (Instance->McastUdpPort);\r
+            Instance->McastUdpPort = NULL;\r
+            return EFI_DEVICE_ERROR;\r
+          }\r
+        }\r
+      }\r
+\r
 \r
       if (Instance->McastUdpPort == NULL) {\r
         return EFI_DEVICE_ERROR;\r
@@ -562,22 +591,22 @@ Mtftp4RrqHandleOack (
 \r
         return Status;\r
       }\r
-    \r
+\r
       //\r
       // Update the parameters used.\r
       //\r
       if (Reply.BlkSize != 0) {\r
         Instance->BlkSize = Reply.BlkSize;\r
       }\r
-      \r
+\r
       if (Reply.Timeout != 0) {\r
         Instance->Timeout = Reply.Timeout;\r
-      }  \r
-    }    \r
-    \r
+      }\r
+    }\r
+\r
   } else {\r
     Instance->Master = TRUE;\r
-    \r
+\r
     if (Reply.BlkSize != 0) {\r
       Instance->BlkSize = Reply.BlkSize;\r
     }\r
@@ -586,7 +615,7 @@ Mtftp4RrqHandleOack (
       Instance->Timeout = Reply.Timeout;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Send an ACK to (Expected - 1) which is 0 for unicast download,\r
   // or tell the server we want to receive the Expected block.\r
@@ -605,6 +634,7 @@ Mtftp4RrqHandleOack (
 \r
 **/\r
 VOID\r
+EFIAPI\r
 Mtftp4RrqInput (\r
   IN NET_BUF                *UdpPacket,\r
   IN UDP_END_POINT          *EndPoint,\r
@@ -675,6 +705,7 @@ Mtftp4RrqInput (
 \r
   } else {\r
     Packet = (EFI_MTFTP4_PACKET *) NetbufGetByte (UdpPacket, 0, NULL);\r
+    ASSERT (Packet != NULL);\r
   }\r
 \r
   Opcode = NTOHS (Packet->OpCode);\r
@@ -731,7 +762,7 @@ Mtftp4RrqInput (
   case EFI_MTFTP4_OPCODE_ERROR:\r
     Status = EFI_TFTP_ERROR;\r
     break;\r
-    \r
+\r
   default:\r
     break;\r
   }\r
@@ -743,7 +774,7 @@ ON_EXIT:
   // receive, otherwise end the session.\r
   //\r
   if ((Packet != NULL) && (UdpPacket->BlockOpNum > 1)) {\r
-    gBS->FreePool (Packet);\r
+    FreePool (Packet);\r
   }\r
 \r
   if (UdpPacket != NULL) {\r