]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
MdeModulePkg: Update IP4 stack drivers for classless address unicast check.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Support.c
index e7f6291e035c99e34329c8dc16c688b8f30a472e..c625fda020e81034aca5fdf4baf07616bc3eb03e 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Support routines for Mtftp.\r
   \r
-Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2015, 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
@@ -32,7 +32,7 @@ Mtftp4AllocateRange (
 {\r
   MTFTP4_BLOCK_RANGE        *Range;\r
 \r
-  Range = AllocatePool (sizeof (MTFTP4_BLOCK_RANGE));\r
+  Range = AllocateZeroPool (sizeof (MTFTP4_BLOCK_RANGE));\r
 \r
   if (Range == NULL) {\r
     return NULL;\r
@@ -41,6 +41,7 @@ Mtftp4AllocateRange (
   InitializeListHead (&Range->Link);\r
   Range->Start  = Start;\r
   Range->End    = End;\r
+  Range->Bound  = End;\r
 \r
   return Range;\r
 }\r
@@ -157,6 +158,8 @@ Mtftp4SetLastBlockNum (
 \r
   @param  Head                  The block range list to remove from\r
   @param  Num                   The block number to remove\r
+  @param  Completed             Whether Num is the last block number\r
+  @param  TotalBlock            The continuous block number in all \r
 \r
   @retval EFI_NOT_FOUND         The block number isn't in the block range list\r
   @retval EFI_SUCCESS           The block number has been removed from the list\r
@@ -166,7 +169,9 @@ Mtftp4SetLastBlockNum (
 EFI_STATUS\r
 Mtftp4RemoveBlockNum (\r
   IN LIST_ENTRY             *Head,\r
-  IN UINT16                 Num\r
+  IN UINT16                 Num,\r
+  IN BOOLEAN                Completed,\r
+  OUT UINT64                *TotalBlock\r
   )\r
 {\r
   MTFTP4_BLOCK_RANGE        *Range;\r
@@ -207,7 +212,26 @@ Mtftp4RemoveBlockNum (
     } else if (Range->Start == Num) {\r
       Range->Start++;\r
 \r
-      if (Range->Start > Range->End) {\r
+      //\r
+      // Note that: RFC 1350 does not mention block counter roll-over, \r
+      // but several TFTP hosts implement the roll-over be able to accept \r
+      // transfers of unlimited size. There is no consensus, however, whether \r
+      // the counter should wrap around to zero or to one. Many implementations \r
+      // wrap to zero, because this is the simplest to implement. Here we choose \r
+      // this solution.\r
+      //\r
+         *TotalBlock  = Num;\r
+         \r
+      if (Range->Round > 0) {\r
+           *TotalBlock += Range->Bound +  MultU64x32 ((UINTN) (Range->Round -1), (UINT32) (Range->Bound + 1)) + 1;\r
+         }\r
+\r
+      if (Range->Start > Range->Bound) {\r
+                 Range->Start = 0;\r
+                 Range->Round ++;\r
+      }\r
+\r
+      if ((Range->Start > Range->End) || Completed) {\r
         RemoveEntryList (&Range->Link);\r
         FreePool (Range);\r
       }\r
@@ -254,13 +278,16 @@ Mtftp4SendRequest (
   EFI_MTFTP4_PACKET         *Packet;\r
   EFI_MTFTP4_OPTION         *Options;\r
   EFI_MTFTP4_TOKEN          *Token;\r
+  RETURN_STATUS             Status;\r
   NET_BUF                   *Nbuf;\r
   UINT8                     *Mode;\r
   UINT8                     *Cur;\r
-  UINT32                    Len;\r
   UINTN                     Index;\r
-  UINT32                    Len1;\r
-  UINT32                    Len2;\r
+  UINT32                    BufferLength;\r
+  UINTN                     FileNameLength;\r
+  UINTN                     ModeLength;\r
+  UINTN                     OptionStrLength;\r
+  UINTN                     ValueStrLength;\r
 \r
   Token   = Instance->Token;\r
   Options = Token->OptionList;\r
@@ -273,39 +300,52 @@ Mtftp4SendRequest (
   //\r
   // Compute the packet length\r
   //\r
-  Len1 = (UINT32) AsciiStrLen ((CHAR8 *) Token->Filename);\r
-  Len2 = (UINT32) AsciiStrLen ((CHAR8 *) Mode);\r
-  Len  = (Len1 + Len2 + 4);\r
+  FileNameLength = AsciiStrLen ((CHAR8 *) Token->Filename);\r
+  ModeLength     = AsciiStrLen ((CHAR8 *) Mode);\r
+  BufferLength   = (UINT32) FileNameLength + (UINT32) ModeLength + 4;\r
 \r
   for (Index = 0; Index < Token->OptionCount; Index++) {\r
-    Len1 = (UINT32) AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);\r
-    Len2 = (UINT32) AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);\r
-    Len += Len1 + Len2 + 2;\r
+    OptionStrLength = AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);\r
+    ValueStrLength  = AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);\r
+    BufferLength   += (UINT32) OptionStrLength + (UINT32) ValueStrLength + 2;\r
   }\r
-\r
   //\r
   // Allocate a packet then copy the data over\r
   //\r
-  if ((Nbuf = NetbufAlloc (Len)) == NULL) {\r
+  if ((Nbuf = NetbufAlloc (BufferLength)) == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Packet         = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (Nbuf, Len, FALSE);\r
+  Packet         = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (Nbuf, BufferLength, FALSE);\r
   ASSERT (Packet != NULL);\r
 \r
   Packet->OpCode = HTONS (Instance->Operation);\r
+  BufferLength  -= sizeof (Packet->OpCode);\r
+  \r
   Cur            = Packet->Rrq.Filename;\r
-  Cur            = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Token->Filename);\r
-  Cur           += AsciiStrLen ((CHAR8 *) Token->Filename) + 1;\r
-  Cur            = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Mode);\r
-  Cur           += AsciiStrLen ((CHAR8 *) Mode) + 1;\r
+  Status         = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Token->Filename);\r
+  ASSERT_EFI_ERROR (Status);\r
+  BufferLength  -= (UINT32) (FileNameLength + 1);\r
+  Cur           += FileNameLength + 1;\r
+  Status         = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Mode);\r
+  ASSERT_EFI_ERROR (Status);\r
+  BufferLength  -= (UINT32) (ModeLength + 1);\r
+  Cur           += ModeLength + 1;\r
 \r
   for (Index = 0; Index < Token->OptionCount; ++Index) {\r
-    Cur  = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Options[Index].OptionStr);\r
-    Cur += AsciiStrLen ((CHAR8 *) Options[Index].OptionStr) + 1;\r
-\r
-    Cur  = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Options[Index].ValueStr);\r
-    Cur += AsciiStrLen ((CHAR8 *) (CHAR8 *) Options[Index].ValueStr) + 1;\r
+    OptionStrLength = AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);\r
+    ValueStrLength  = AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);\r
+    \r
+    Status          = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Options[Index].OptionStr);\r
+    ASSERT_EFI_ERROR (Status);\r
+    BufferLength   -= (UINT32) (OptionStrLength + 1);\r
+    Cur            += OptionStrLength + 1;\r
+    \r
+    Status          = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Options[Index].ValueStr);\r
+    ASSERT_EFI_ERROR (Status);\r
+    BufferLength   -= (UINT32) (ValueStrLength + 1);\r
+    Cur            += ValueStrLength + 1;\r
+    \r
   }\r
 \r
   return Mtftp4SendPacket (Instance, Nbuf);\r
@@ -347,7 +387,7 @@ Mtftp4SendError (
   TftpError->OpCode = HTONS (EFI_MTFTP4_OPCODE_ERROR);\r
   TftpError->Error.ErrorCode = HTONS (ErrCode);\r
 \r
-  AsciiStrCpy ((CHAR8 *) TftpError->Error.ErrorMessage, (CHAR8 *) ErrInfo);\r
+  AsciiStrCpyS ((CHAR8 *) TftpError->Error.ErrorMessage, Len, (CHAR8 *) ErrInfo);\r
 \r
   return Mtftp4SendPacket (Instance, Packet);\r
 }\r
@@ -419,7 +459,7 @@ Mtftp4SendPacket (
   UDP_END_POINT             UdpPoint;\r
   EFI_STATUS                Status;\r
   UINT16                    OpCode;\r
-  UINT16                    Value;\r
+  UINT8                     *Buffer;\r
 \r
   //\r
   // Save the packet for retransmission\r
@@ -440,8 +480,9 @@ Mtftp4SendPacket (
   // Send the requests to the listening port, other packets\r
   // to the connected port\r
   //\r
-  Value = *((UINT16 *) NetbufGetByte (Packet, 0, NULL));\r
-  OpCode = NTOHS (Value);\r
+  Buffer = NetbufGetByte (Packet, 0, NULL);\r
+  ASSERT (Buffer != NULL);\r
+  OpCode = NTOHS (*(UINT16 *)Buffer);\r
 \r
   if ((OpCode == EFI_MTFTP4_OPCODE_RRQ) || \r
       (OpCode == EFI_MTFTP4_OPCODE_DIR) ||\r
@@ -487,7 +528,7 @@ Mtftp4Retransmit (
   UDP_END_POINT             UdpPoint;\r
   EFI_STATUS                Status;\r
   UINT16                    OpCode;\r
-  UINT16                    Value;\r
+  UINT8                     *Buffer;\r
 \r
   ASSERT (Instance->LastPacket != NULL);\r
 \r
@@ -497,8 +538,9 @@ Mtftp4Retransmit (
   //\r
   // Set the requests to the listening port, other packets to the connected port\r
   //\r
-  Value = *(UINT16 *) NetbufGetByte (Instance->LastPacket, 0, NULL);\r
-  OpCode = NTOHS (Value);\r
+  Buffer = NetbufGetByte (Instance->LastPacket, 0, NULL);\r
+  ASSERT (Buffer != NULL);\r
+  OpCode = NTOHS (*(UINT16 *) Buffer);\r
 \r
   if ((OpCode == EFI_MTFTP4_OPCODE_RRQ) || (OpCode == EFI_MTFTP4_OPCODE_DIR) ||\r
       (OpCode == EFI_MTFTP4_OPCODE_WRQ)) {\r