/** @file\r
Mtftp6 support functions implementation.\r
\r
- Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
\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.\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
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
Initialize the block range for either RRQ or WRQ. RRQ and WRQ have\r
different requirements for Start and End. For example, during startup,\r
WRQ initializes its whole valid block range to [0, 0xffff]. This\r
- is bacause the server will send an ACK0 to inform the user to start the\r
+ is because the server will send an ACK0 to inform the user to start the\r
upload. When the client receives an ACK0, it will remove 0 from the range,\r
get the next block number, which is 1, then upload the BLOCK1. For RRQ\r
without option negotiation, the server will directly send the BLOCK1\r
\r
@param[in] Head The block range list to remove from.\r
@param[in] Num The block number to remove.\r
- @param[in] Completed Whether Num is the last block number\r
- @param[out] TotalBlock The continuous block number in all\r
+ @param[in] Completed Whether Num is the last block number.\r
+ @param[out] BlockCounter The continuous block counter instead of the value after roll-over.\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
IN LIST_ENTRY *Head,\r
IN UINT16 Num,\r
IN BOOLEAN Completed,\r
- OUT UINT64 *TotalBlock\r
+ OUT UINT64 *BlockCounter\r
)\r
{\r
MTFTP6_BLOCK_RANGE *Range;\r
// 3. (Start < Num) && (End >= Num):\r
// if End == Num, only need to decrease the End by one because\r
// we have (Start < Num) && (Num == End), so (Start <= End - 1).\r
- // if (End > Num), the hold is splited into two holes, with\r
+ // if (End > Num), the hold is split into two holes, with\r
// [Start, Num - 1] and [Num + 1, End].\r
//\r
if (Range->Start > Num) {\r
// wrap to zero, because this is the simplest to implement. Here we choose\r
// this solution.\r
//\r
- *TotalBlock = Num;\r
+ *BlockCounter = Num;\r
\r
if (Range->Round > 0) {\r
- *TotalBlock += Range->Bound + MultU64x32 ((UINT64) (Range->Round -1), (UINT32)(Range->Bound + 1)) + 1;\r
+ *BlockCounter += Range->Bound + MultU64x32 (Range->Round - 1, (UINT32)(Range->Bound + 1)) + 1;\r
}\r
\r
if (Range->Start > Range->Bound) {\r
Status = Udp6->GetModeData (Udp6, NULL, &Ip6Mode, NULL, NULL);\r
\r
if (!EFI_ERROR (Status)) {\r
+ if (Ip6Mode.AddressList != NULL) {\r
+ FreePool (Ip6Mode.AddressList);\r
+ }\r
+\r
+ if (Ip6Mode.GroupTable != NULL) {\r
+ FreePool (Ip6Mode.GroupTable);\r
+ }\r
+\r
+ if (Ip6Mode.RouteTable != NULL) {\r
+ FreePool (Ip6Mode.RouteTable);\r
+ }\r
+\r
+ if (Ip6Mode.NeighborCache != NULL) {\r
+ FreePool (Ip6Mode.NeighborCache);\r
+ }\r
+\r
+ if (Ip6Mode.PrefixTable != NULL) {\r
+ FreePool (Ip6Mode.PrefixTable);\r
+ }\r
+\r
+ if (Ip6Mode.IcmpTypeList != NULL) {\r
+ FreePool (Ip6Mode.IcmpTypeList);\r
+ }\r
\r
if (Ip6Mode.IsConfigured) {\r
//\r
EFI_MTFTP6_PACKET *Packet;\r
EFI_MTFTP6_OPTION *Options;\r
EFI_MTFTP6_TOKEN *Token;\r
+ RETURN_STATUS Status;\r
NET_BUF *Nbuf;\r
UINT8 *Mode;\r
UINT8 *Cur;\r
- UINT32 Len1;\r
- UINT32 Len2;\r
- UINT32 Len;\r
UINTN Index;\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
//\r
// Compute the size of new Mtftp6 packet.\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.\r
//\r
- if ((Nbuf = NetbufAlloc (Len)) == NULL) {\r
+ if ((Nbuf = NetbufAlloc (BufferLength)) == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
//\r
// Copy the opcode, filename and mode into packet.\r
//\r
- Packet = (EFI_MTFTP6_PACKET *) NetbufAllocSpace (Nbuf, Len, FALSE);\r
+ Packet = (EFI_MTFTP6_PACKET *) NetbufAllocSpace (Nbuf, BufferLength, FALSE);\r
ASSERT (Packet != NULL);\r
\r
Packet->OpCode = HTONS (Operation);\r
+ BufferLength -= sizeof (Packet->OpCode);\r
+\r
Cur = Packet->Rrq.Filename;\r
- Cur = (UINT8 *) AsciiStrCpyS ((CHAR8 *) Cur, Len - 2, (CHAR8 *) Token->Filename);\r
- Cur += AsciiStrLen ((CHAR8 *) Token->Filename) + 1;\r
- Cur = (UINT8 *) AsciiStrCpyS ((CHAR8 *) Cur, Len - 2 - (AsciiStrLen ((CHAR8 *) Token->Filename) + 1), (CHAR8 *) Mode);\r
- Cur += AsciiStrLen ((CHAR8 *) Mode) + 1;\r
- Len -= ((UINT32) AsciiStrLen ((CHAR8 *) Token->Filename) + (UINT32) AsciiStrLen ((CHAR8 *) Mode) + 4);\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
//\r
// Copy all the extension options into the packet.\r
//\r
for (Index = 0; Index < Token->OptionCount; ++Index) {\r
- Cur = (UINT8 *) AsciiStrCpyS ((CHAR8 *) Cur, Len, (CHAR8 *) Options[Index].OptionStr);\r
- Cur += AsciiStrLen ((CHAR8 *) Options[Index].OptionStr) + 1;\r
- Len -= (UINT32)(AsciiStrLen ((CHAR8 *) Options[Index].OptionStr) + 1);\r
- Cur = (UINT8 *) AsciiStrCpyS ((CHAR8 *) Cur, Len, (CHAR8 *) Options[Index].ValueStr);\r
- Cur += AsciiStrLen ((CHAR8 *) (CHAR8 *) Options[Index].ValueStr) + 1;\r
- Len -= (UINT32)(AsciiStrLen ((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
//\r
TftpError->OpCode = HTONS (EFI_MTFTP6_OPCODE_ERROR);\r
TftpError->Error.ErrorCode = HTONS (ErrCode);\r
\r
- AsciiStrCpyS ((CHAR8 *) TftpError->Error.ErrorMessage, sizeof (TftpError->Error.ErrorMessage) / sizeof (TftpError->Error.ErrorMessage[0]), (CHAR8 *) ErrInfo);\r
+ AsciiStrCpyS ((CHAR8 *) TftpError->Error.ErrorMessage, AsciiStrLen ((CHAR8 *) ErrInfo) + 1 , (CHAR8 *) ErrInfo);\r
\r
//\r
// Save the packet buf for retransmit\r
Instance->ServerDataPort = 0;\r
Instance->McastPort = 0;\r
Instance->BlkSize = 0;\r
+ Instance->Operation = 0;\r
+ Instance->WindowSize = 1;\r
+ Instance->TotalBlock = 0;\r
+ Instance->AckedBlock = 0;\r
Instance->LastBlk = 0;\r
Instance->PacketToLive = 0;\r
Instance->MaxRetry = 0;\r
write file, and read directory.\r
\r
@param[in] This The MTFTP session.\r
- @param[in] Token The token than encapsues the user's request.\r
+ @param[in] Token The token than encapsules the user's request.\r
@param[in] OpCode The operation to perform.\r
\r
@retval EFI_INVALID_PARAMETER Some of the parameters are invalid.\r
Status = EFI_SUCCESS;\r
Instance->OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
\r
+ Instance->Operation = OpCode;\r
+\r
//\r
// Parse the extension options in the request packet.\r
//\r
Token->OptionList,\r
Token->OptionCount,\r
TRUE,\r
+ Instance->Operation,\r
&Instance->ExtInfo\r
);\r
\r
if (Instance->BlkSize == 0) {\r
Instance->BlkSize = MTFTP6_DEFAULT_BLK_SIZE;\r
}\r
+ if (Instance->WindowSize == 0) {\r
+ Instance->WindowSize = MTFTP6_DEFAULT_WINDOWSIZE;\r
+ }\r
if (Instance->MaxRetry == 0) {\r
Instance->MaxRetry = MTFTP6_DEFAULT_MAX_RETRY;\r
}\r
}\r
\r
//\r
- // Retransmit the packet if haven't reach the maxmium retry count,\r
+ // Retransmit the packet if haven't reach the maximum retry count,\r
// otherwise exit the transfer.\r
//\r
if (Instance->CurRetry < Instance->MaxRetry) {\r