X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FMtftp4Dxe%2FMtftp4Impl.c;h=70bd693e4e3a6f172a543421a850e10cf5bebd1d;hp=3c2b4e101952a3388fa1796a90a10f1857b25acd;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=e48e37fce2611df7a52aff271835ff72ee396d9b diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c index 3c2b4e1019..70bd693e4e 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c @@ -1,74 +1,14 @@ /** @file + Interface routine for Mtftp4. -Copyright (c) 2006 - 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Mtftp4Impl.c - -Abstract: - - Interface routine for Mtftp4 - +(C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "Mtftp4Impl.h" - -STATIC -EFI_STATUS -EFIAPI -EfiMtftp4ReadFile ( - IN EFI_MTFTP4_PROTOCOL *This, - IN EFI_MTFTP4_TOKEN *Token - ); - - -/** - Get the current operation parameter for the MTFTP session - - @param This The MTFTP protocol instance - @param ModeData The MTFTP mode data - - @retval EFI_INVALID_PARAMETER This or ModeData is NULL - @retval EFI_SUCCESS The operation parameter is saved in ModeData - -**/ -STATIC -EFI_STATUS -EFIAPI -EfiMtftp4GetModeData ( - IN EFI_MTFTP4_PROTOCOL *This, - OUT EFI_MTFTP4_MODE_DATA *ModeData - ) -{ - MTFTP4_PROTOCOL *Instance; - EFI_TPL OldTpl; - - if ((This == NULL) || (ModeData == NULL)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - CopyMem(&ModeData->ConfigData, &Instance->Config, sizeof (Instance->Config)); - ModeData->SupportedOptionCount = MTFTP4_SUPPORTED_OPTIONS; - ModeData->SupportedOptoins = (UINT8 **) mMtftp4SupportedOptions; - ModeData->UnsupportedOptionCount = 0; - ModeData->UnsupportedOptoins = NULL; - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} +#include "Mtftp4Impl.h" /** @@ -77,14 +17,11 @@ EfiMtftp4GetModeData ( @param Instance The MTFTP session to clean up @param Result The result to return to the caller who initiated the operation. - - @return None - **/ VOID Mtftp4CleanOperation ( - IN MTFTP4_PROTOCOL *Instance, - IN EFI_STATUS Result + IN OUT MTFTP4_PROTOCOL *Instance, + IN EFI_STATUS Result ) { LIST_ENTRY *Entry; @@ -108,7 +45,7 @@ Mtftp4CleanOperation ( } ASSERT (Instance->UnicastPort != NULL); - UdpIoCleanPort (Instance->UnicastPort); + UdpIoCleanIo (Instance->UnicastPort); if (Instance->LastPacket != NULL) { NetbufFree (Instance->LastPacket); @@ -116,14 +53,20 @@ Mtftp4CleanOperation ( } if (Instance->McastUdpPort != NULL) { - UdpIoFreePort (Instance->McastUdpPort); + gBS->CloseProtocol ( + Instance->McastUdpPort->UdpHandle, + &gEfiUdp4ProtocolGuid, + gMtftp4DriverBinding.DriverBindingHandle, + Instance->Handle + ); + UdpIoFreeIo (Instance->McastUdpPort); Instance->McastUdpPort = NULL; } NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->Blocks) { Block = NET_LIST_USER_STRUCT (Entry, MTFTP4_BLOCK_RANGE, Link); RemoveEntryList (Entry); - gBS->FreePool (Block); + FreePool (Block); } ZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION)); @@ -131,6 +74,9 @@ Mtftp4CleanOperation ( Instance->Operation = 0; Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE; + Instance->WindowSize = 1; + Instance->TotalBlock = 0; + Instance->AckedBlock = 0; Instance->LastBlock = 0; Instance->ServerIp = 0; Instance->ListeningPort = 0; @@ -147,101 +93,10 @@ Mtftp4CleanOperation ( /** - Configure the MTFTP session for new operation or reset the current - operation if ConfigData is NULL. - - @param This The MTFTP session to configure - @param ConfigData The configure parameters - - @retval EFI_INVALID_PARAMETER Some of the parameter is invalid. - @retval EFI_ACCESS_DENIED There is pending operation - @retval EFI_SUCCESS The instance is configured for operation. - -**/ -STATIC -EFI_STATUS -EFIAPI -EfiMtftp4Configure ( - IN EFI_MTFTP4_PROTOCOL *This, - IN EFI_MTFTP4_CONFIG_DATA *ConfigData - ) -{ - MTFTP4_PROTOCOL *Instance; - EFI_TPL OldTpl; - IP4_ADDR Ip; - IP4_ADDR Netmask; - IP4_ADDR Gateway; - IP4_ADDR ServerIp; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - - if (ConfigData == NULL) { - // - // Reset the operation if ConfigData is NULL - // - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Mtftp4CleanOperation (Instance, EFI_ABORTED); - ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA)); - Instance->State = MTFTP4_STATE_UNCONFIGED; - - gBS->RestoreTPL (OldTpl); - - } else { - // - // Configure the parameters for new operation. - // - CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR)); - CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR)); - CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR)); - CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR)); - - Ip = NTOHL (Ip); - Netmask = NTOHL (Netmask); - Gateway = NTOHL (Gateway); - ServerIp = NTOHL (ServerIp); - - if (!Ip4IsUnicast (ServerIp, 0)) { - return EFI_INVALID_PARAMETER; - } - - if (!ConfigData->UseDefaultSetting && - ((!IP4_IS_VALID_NETMASK (Netmask) || !Ip4IsUnicast (Ip, Netmask)))) { - - return EFI_INVALID_PARAMETER; - } - - if ((Gateway != 0) && - (!IP4_NET_EQUAL (Gateway, Ip, Netmask) || !Ip4IsUnicast (Gateway, Netmask))) { + Check packet for GetInfo. - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) { - gBS->RestoreTPL (OldTpl); - return EFI_ACCESS_DENIED; - } - - CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));; - Instance->State = MTFTP4_STATE_CONFIGED; - - gBS->RestoreTPL (OldTpl); - } - - return EFI_SUCCESS; -} - - -/** - Check packet for GetInfo. GetInfo is implemented with EfiMtftp4ReadFile. - It use Mtftp4GetInfoCheckPacket to inspect the first packet from server, - then abort the session. + GetInfo is implemented with EfiMtftp4ReadFile. It use Mtftp4GetInfoCheckPacket + to inspect the first packet from server, then abort the session. @param This The MTFTP4 protocol instance @param Token The user's token @@ -251,8 +106,8 @@ EfiMtftp4Configure ( @retval EFI_ABORTED Abort the ReadFile operation and return. **/ -STATIC EFI_STATUS +EFIAPI Mtftp4GetInfoCheckPacket ( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token, @@ -260,13 +115,12 @@ Mtftp4GetInfoCheckPacket ( IN EFI_MTFTP4_PACKET *Packet ) { - MTFTP4_PROTOCOL *Instance; MTFTP4_GETINFO_STATE *State; EFI_STATUS Status; UINT16 OpCode; + EFI_MTFTP4_ERROR_HEADER *ErrorHeader; - Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - State = &Instance->GetInfoState; + State = (MTFTP4_GETINFO_STATE *) Token->Context; OpCode = NTOHS (Packet->OpCode); // @@ -274,6 +128,12 @@ Mtftp4GetInfoCheckPacket ( // switch (OpCode) { case EFI_MTFTP4_OPCODE_ERROR: + ErrorHeader = (EFI_MTFTP4_ERROR_HEADER *) Packet; + if (ErrorHeader->ErrorCode == EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND) { + DEBUG ((EFI_D_ERROR, "TFTP error code 1 (File Not Found)\n")); + } else { + DEBUG ((EFI_D_ERROR, "TFTP error code %d\n", ErrorHeader->ErrorCode)); + } State->Status = EFI_TFTP_ERROR; break; @@ -304,147 +164,19 @@ Mtftp4GetInfoCheckPacket ( /** - Get the information of the download from the server. It is implemented - with EfiMtftp4ReadFile: build a token, then pass it to EfiMtftp4ReadFile. - In its check packet callback abort the opertions. - - @param This The MTFTP protocol instance - @param OverrideData The MTFTP override data - @param Filename The file to get information - @param ModeStr The mode to use - @param OptionCount The number of options to append - @param OptionList The options to append - @param PacketLength The variable to receive the packet length - @param Packet The variable to receive the packet. - - @retval EFI_INVALID_PARAMETER The parameter is invaid - @retval EFI_SUCCESS The information is got - @retval Others Failed to get the information. - -**/ -STATIC -EFI_STATUS -EFIAPI -EfiMtftp4GetInfo ( - IN EFI_MTFTP4_PROTOCOL *This, - IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData, OPTIONAL - IN UINT8 *Filename, - IN UINT8 *ModeStr, OPTIONAL - IN UINT8 OptionCount, - IN EFI_MTFTP4_OPTION *OptionList, - OUT UINT32 *PacketLength, - OUT EFI_MTFTP4_PACKET **Packet OPTIONAL - ) -{ - EFI_MTFTP4_TOKEN Token; - MTFTP4_PROTOCOL *Instance; - MTFTP4_GETINFO_STATE *State; - EFI_STATUS Status; - - if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) || - (OptionCount && (OptionList == NULL))) { - return EFI_INVALID_PARAMETER; - } - - if (Packet != NULL) { - *Packet = NULL; - } - - *PacketLength = 0; - Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - State = &Instance->GetInfoState; - State->Packet = Packet; - State->PacketLen = PacketLength; - State->Status = EFI_SUCCESS; - - // - // Fill in the Token to issue an synchronous ReadFile operation - // - Token.Status = EFI_SUCCESS; - Token.Event = NULL; - Token.OverrideData = OverrideData; - Token.Filename = Filename; - Token.ModeStr = ModeStr; - Token.OptionCount = OptionCount; - Token.OptionList = OptionList; - Token.BufferSize = 0; - Token.Buffer = NULL; - Token.CheckPacket = Mtftp4GetInfoCheckPacket; - Token.TimeoutCallback = NULL; - Token.PacketNeeded = NULL; - - Status = EfiMtftp4ReadFile (This, &Token); - - if (EFI_ABORTED == Status) { - return State->Status; - } - - return Status; -} - - -/** - Parse the packet into an array of options. The OptionList is allocated - by this function, and caller should free it when used. - - @param This The MTFTP protocol instance - @param PacketLen The length of the packet - @param Packet The packet to parse - @param OptionCount The size of the OptionList array allocated. - @param OptionList The allocated option array to save the option - addresses. - - @retval EFI_INVALID_PARAMETER The parameters are invalid. - @retval EFI_NOT_FOUND There is no valid option in the packet - @retval EFI_SUCCESS The packet is parsed. - -**/ -STATIC -EFI_STATUS -EFIAPI -EfiMtftp4ParseOptions ( - IN EFI_MTFTP4_PROTOCOL *This, - IN UINT32 PacketLen, - IN EFI_MTFTP4_PACKET *Packet, - IN OUT UINT32 *OptionCount, - OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL - ) -{ - EFI_STATUS Status; - - if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) || - (Packet == NULL) || (OptionCount == NULL)) { + Check whether the override data is valid. - return EFI_INVALID_PARAMETER; - } - - Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList); - - if (EFI_ERROR (Status)) { - return Status; - } - - if (*OptionCount == 0) { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - - -/** - Check whether the override data is valid. It will first - validate whether the server is a valid unicast. If a gateway - is provided in the Override, it also check that it is a - unicast on the connected network. + It will first validate whether the server is a valid unicast. If a gateway + is provided in the Override, it also check that it is a unicast on the + connected network. @param Instance The MTFTP instance @param Override The override data to validate. - @return TRUE if the override data is valid, otherwise FALSE. + @retval TRUE The override data is valid + @retval FALSE The override data is invalid **/ -STATIC BOOLEAN Mtftp4OverrideValid ( IN MTFTP4_PROTOCOL *Instance, @@ -457,7 +189,7 @@ Mtftp4OverrideValid ( IP4_ADDR Gateway; CopyMem (&Ip, &Override->ServerIp, sizeof (IP4_ADDR)); - if (!Ip4IsUnicast (NTOHL (Ip), 0)) { + if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) { return FALSE; } @@ -473,7 +205,7 @@ Mtftp4OverrideValid ( Netmask = NTOHL (Netmask); Ip = NTOHL (Ip); - if (!Ip4IsUnicast (Gateway, Netmask) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) { + if ((Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) { return FALSE; } } @@ -484,22 +216,23 @@ Mtftp4OverrideValid ( /** Poll the UDP to get the IP4 default address, which may be retrieved - by DHCP. The default time out value is 5 seconds. If IP has retrieved - the default address, the UDP is reconfigured. + by DHCP. + + The default time out value is 5 seconds. If IP has retrieved the default address, + the UDP is reconfigured. @param Instance The Mtftp instance - @param UdpPort The UDP port to poll - @param UdpCfgData The UDP configure data to reconfigure the UDP - port. + @param UdpIo The UDP_IO to poll + @param UdpCfgData The UDP configure data to reconfigure the UDP_IO - @return TRUE if the default address is retrieved and UDP is reconfigured. - @return Otherwise FALSE. + @retval TRUE The default address is retrieved and UDP is reconfigured. + @retval FALSE Some error occured. **/ BOOLEAN Mtftp4GetMapping ( IN MTFTP4_PROTOCOL *Instance, - IN UDP_IO_PORT *UdpPort, + IN UDP_IO *UdpIo, IN EFI_UDP4_CONFIG_DATA *UdpCfgData ) { @@ -511,7 +244,7 @@ Mtftp4GetMapping ( ASSERT (Instance->Config.UseDefaultSetting); Service = Instance->Service; - Udp = UdpPort->Udp; + Udp = UdpIo->Protocol.Udp4; Status = gBS->SetTimer ( Service->TimerToGetMap, @@ -522,7 +255,7 @@ Mtftp4GetMapping ( return FALSE; } - while (!EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) { + while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) { Udp->Poll (Udp); if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) && @@ -540,17 +273,16 @@ Mtftp4GetMapping ( /** Configure the UDP port for unicast receiving. - @param UdpIo The UDP port + @param UdpIo The UDP_IO instance @param Instance The MTFTP session @retval EFI_SUCCESS The UDP port is successfully configured for the session to unicast receive. **/ -STATIC EFI_STATUS Mtftp4ConfigUnicastPort ( - IN UDP_IO_PORT *UdpIo, + IN UDP_IO *UdpIo, IN MTFTP4_PROTOCOL *Instance ) { @@ -571,15 +303,15 @@ Mtftp4ConfigUnicastPort ( UdpConfig.ReceiveTimeout = 0; UdpConfig.TransmitTimeout = 0; UdpConfig.UseDefaultAddress = Config->UseDefaultSetting; - UdpConfig.StationAddress = Config->StationIp; - UdpConfig.SubnetMask = Config->SubnetMask; - UdpConfig.StationPort = 0; + IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp); + IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask); + UdpConfig.StationPort = Config->LocalPort; UdpConfig.RemotePort = 0; Ip = HTONL (Instance->ServerIp); - CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS)); + IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip); - Status = UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfig); + Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig); if ((Status == EFI_NO_MAPPING) && Mtftp4GetMapping (Instance, UdpIo, &UdpConfig)) { return EFI_SUCCESS; @@ -590,9 +322,15 @@ Mtftp4ConfigUnicastPort ( // The station IP address is manually configured and the Gateway IP is not 0. // Add the default route for this UDP instance. // - Status = UdpIo->Udp->Routes (UdpIo->Udp, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &Config->GatewayIp); + Status = UdpIo->Protocol.Udp4->Routes ( + UdpIo->Protocol.Udp4, + FALSE, + &mZeroIp4Addr, + &mZeroIp4Addr, + &Config->GatewayIp + ); if (EFI_ERROR (Status)) { - UdpIo->Udp->Configure (UdpIo->Udp, NULL); + UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, NULL); } } return Status; @@ -613,7 +351,6 @@ Mtftp4ConfigUnicastPort ( @retval EFI_SUCCESS The operation is successfully started. **/ -STATIC EFI_STATUS Mtftp4Start ( IN EFI_MTFTP4_PROTOCOL *This, @@ -626,6 +363,7 @@ Mtftp4Start ( EFI_MTFTP4_CONFIG_DATA *Config; EFI_TPL OldTpl; EFI_STATUS Status; + EFI_STATUS TokenStatus; // // Validate the parameters @@ -653,7 +391,9 @@ Mtftp4Start ( Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - Status = EFI_SUCCESS; + Status = EFI_SUCCESS; + TokenStatus = EFI_SUCCESS; + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (Instance->State != MTFTP4_STATE_CONFIGED) { @@ -664,6 +404,10 @@ Mtftp4Start ( Status = EFI_ACCESS_DENIED; } + if ((Token->OverrideData != NULL) && !Mtftp4OverrideValid (Instance, Token->OverrideData)) { + Status = EFI_INVALID_PARAMETER; + } + if (EFI_ERROR (Status)) { gBS->RestoreTPL (OldTpl); return Status; @@ -676,20 +420,17 @@ Mtftp4Start ( Instance->Operation = Operation; Override = Token->OverrideData; - if ((Override != NULL) && !Mtftp4OverrideValid (Instance, Override)) { - Status = EFI_INVALID_PARAMETER; - goto ON_ERROR; - } - if (Token->OptionCount != 0) { Status = Mtftp4ParseOption ( Token->OptionList, Token->OptionCount, TRUE, + Instance->Operation, &Instance->RequestOption ); if (EFI_ERROR (Status)) { + TokenStatus = EFI_DEVICE_ERROR; goto ON_ERROR; } } @@ -700,6 +441,7 @@ Mtftp4Start ( Config = &Instance->Config; Instance->Token = Token; Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE; + Instance->WindowSize = MTFTP4_DEFAULT_WINDOWSIZE; CopyMem (&Instance->ServerIp, &Config->ServerIp, sizeof (IP4_ADDR)); Instance->ServerIp = NTOHL (Instance->ServerIp); @@ -742,11 +484,16 @@ Mtftp4Start ( // Config the unicast UDP child to send initial request // Status = Mtftp4ConfigUnicastPort (Instance->UnicastPort, Instance); - if (EFI_ERROR (Status)) { + TokenStatus = EFI_DEVICE_ERROR; goto ON_ERROR; } + // + // Set initial status. + // + Token->Status = EFI_NOT_READY; + // // Build and send an initial requests // @@ -756,21 +503,21 @@ Mtftp4Start ( Status = Mtftp4RrqStart (Instance, Operation); } - gBS->RestoreTPL (OldTpl); - if (EFI_ERROR (Status)) { + TokenStatus = EFI_DEVICE_ERROR; goto ON_ERROR; } - // - // Return immediately for asynchronous operation or poll the - // instance for synchronous operation. - // - Token->Status = EFI_NOT_READY; + + gBS->RestoreTPL(OldTpl); if (Token->Event != NULL) { return EFI_SUCCESS; } + // + // Return immediately for asynchronous operation or poll the + // instance for synchronous operation. + // while (Token->Status == EFI_NOT_READY) { This->Poll (This); } @@ -778,7 +525,7 @@ Mtftp4Start ( return Token->Status; ON_ERROR: - Mtftp4CleanOperation (Instance, Status); + Mtftp4CleanOperation (Instance, TokenStatus); gBS->RestoreTPL (OldTpl); return Status; @@ -786,18 +533,269 @@ ON_ERROR: /** - Read a file from the server. + Reads the current operational settings. + + The GetModeData()function reads the current operational settings of this + EFI MTFTPv4 Protocol driver instance. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance. + @param ModeData Pointer to storage for the EFI MTFTPv4 Protocol + driver mode data. + + @retval EFI_SUCCESS The configuration data was successfully returned. + @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. + @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL. + +**/ +EFI_STATUS +EFIAPI +EfiMtftp4GetModeData ( + IN EFI_MTFTP4_PROTOCOL *This, + OUT EFI_MTFTP4_MODE_DATA *ModeData + ) +{ + MTFTP4_PROTOCOL *Instance; + EFI_TPL OldTpl; + + if ((This == NULL) || (ModeData == NULL)) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = MTFTP4_PROTOCOL_FROM_THIS (This); + CopyMem(&ModeData->ConfigData, &Instance->Config, sizeof (Instance->Config)); + ModeData->SupportedOptionCount = MTFTP4_SUPPORTED_OPTIONS; + ModeData->SupportedOptoins = (UINT8 **) mMtftp4SupportedOptions; + ModeData->UnsupportedOptionCount = 0; + ModeData->UnsupportedOptoins = NULL; + + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; +} + + + +/** + Initializes, changes, or resets the default operational setting for this + EFI MTFTPv4 Protocol driver instance. + + The Configure() function is used to set and change the configuration data for + this EFI MTFTPv4 Protocol driver instance. The configuration data can be reset + to startup defaults by calling Configure() with MtftpConfigData set to NULL. + Whenever the instance is reset, any pending operation is aborted. By changing + the EFI MTFTPv4 Protocol driver instance configuration data, the client can + connect to different MTFTPv4 servers. The configuration parameters in + MtftpConfigData are used as the default parameters in later MTFTPv4 operations + and can be overridden in later operations. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance + @param ConfigData MtftpConfigDataPointer to the configuration data + structure + + @retval EFI_SUCCESS The EFI MTFTPv4 Protocol driver was configured + successfully. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: + 1.This is NULL. + 2.MtftpConfigData.UseDefaultSetting is FALSE and + MtftpConfigData.StationIp is not a valid IPv4 + unicast address. + 3.MtftpCofigData.UseDefaultSetting is FALSE and + MtftpConfigData.SubnetMask is invalid. + 4.MtftpCofigData.ServerIp is not a valid IPv4 + unicast address. + 5.MtftpConfigData.UseDefaultSetting is FALSE and + MtftpConfigData.GatewayIp is not a valid IPv4 + unicast address or is not in the same subnet + with station address. + @retval EFI_ACCESS_DENIED The EFI configuration could not be changed at this + time because there is one MTFTP background operation + in progress. + @retval EFI_NO_MAPPING When using a default address, configuration + (DHCP, BOOTP, RARP, etc.) has not finished yet. + @retval EFI_UNSUPPORTED A configuration protocol (DHCP, BOOTP, RARP, etc.) + could not be located when clients choose to use + the default address settings. + @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv4 Protocol driver instance data could + not be allocated. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + The EFI MTFTPv4 Protocol driver instance is not + configured. + +**/ +EFI_STATUS +EFIAPI +EfiMtftp4Configure ( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_CONFIG_DATA *ConfigData + ) +{ + MTFTP4_PROTOCOL *Instance; + EFI_TPL OldTpl; + IP4_ADDR Ip; + IP4_ADDR Netmask; + IP4_ADDR Gateway; + IP4_ADDR ServerIp; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = MTFTP4_PROTOCOL_FROM_THIS (This); + + if (ConfigData == NULL) { + // + // Reset the operation if ConfigData is NULL + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Mtftp4CleanOperation (Instance, EFI_ABORTED); + ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA)); + Instance->State = MTFTP4_STATE_UNCONFIGED; + + gBS->RestoreTPL (OldTpl); + + } else { + // + // Configure the parameters for new operation. + // + CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR)); + CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR)); + CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR)); + CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR)); + + Ip = NTOHL (Ip); + Netmask = NTOHL (Netmask); + Gateway = NTOHL (Gateway); + ServerIp = NTOHL (ServerIp); + + if (ServerIp == 0 || IP4_IS_LOCAL_BROADCAST (ServerIp)) { + return EFI_INVALID_PARAMETER; + } + + if (!ConfigData->UseDefaultSetting && + ((!IP4_IS_VALID_NETMASK (Netmask) || (Netmask != 0 && !NetIp4IsUnicast (Ip, Netmask))))) { + + return EFI_INVALID_PARAMETER; + } + + if ((Gateway != 0) && + ((Netmask != 0xFFFFFFFF && !IP4_NET_EQUAL (Gateway, Ip, Netmask)) || (Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)))) { + + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) { + gBS->RestoreTPL (OldTpl); + return EFI_ACCESS_DENIED; + } + + CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));; + Instance->State = MTFTP4_STATE_CONFIGED; + + gBS->RestoreTPL (OldTpl); + } + + return EFI_SUCCESS; +} + + + +/** + Parses the options in an MTFTPv4 OACK packet. + + The ParseOptions() function parses the option fields in an MTFTPv4 OACK packet + and returns the number of options that were found and optionally a list of + pointers to the options in the packet. + If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is + returned and *OptionCount and *OptionList stop at the last valid option. + The OptionList is allocated by this function, and caller should free it when used. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance. + @param PacketLen Length of the OACK packet to be parsed. + @param Packet Pointer to the OACK packet to be parsed. + @param OptionCount Pointer to the number of options in following OptionList. + @param OptionList Pointer to EFI_MTFTP4_OPTION storage. Call the + EFI Boot Service FreePool() to release theOptionList + if the options in this OptionList are not needed + any more + + @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and + OptionList parameters have been updated. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + 1.PacketLen is 0. + 2.Packet is NULL or Packet is not a valid MTFTPv4 packet. + 3.OptionCount is NULL. + @retval EFI_NOT_FOUND No options were found in the OACK packet. + @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array cannot be allocated. + @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid. + +**/ +EFI_STATUS +EFIAPI +EfiMtftp4ParseOptions ( + IN EFI_MTFTP4_PROTOCOL *This, + IN UINT32 PacketLen, + IN EFI_MTFTP4_PACKET *Packet, + OUT UINT32 *OptionCount, + OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL + ) +{ + EFI_STATUS Status; + + if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) || + (Packet == NULL) || (OptionCount == NULL)) { + + return EFI_INVALID_PARAMETER; + } + + Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList); + + if (EFI_ERROR (Status)) { + return Status; + } + + if (*OptionCount == 0) { + return EFI_NOT_FOUND; + } - @param This The Mtftp protocol instance. - @param Token The user's request wrap token. + return EFI_SUCCESS; +} - @retval EFI_SUCCESS The ReadFile has finished, the file has been - downloaded if it is synchronous operation, - otherwise it has been initated. - @retval Others Some error happened. + +/** + Downloads a file from an MTFTPv4 server. + + The ReadFile() function is used to initialize and start an MTFTPv4 download + process and optionally wait for completion. When the download operation completes, + whether successfully or not, the Token.Status field is updated by the EFI MTFTPv4 + Protocol driver and then Token.Event is signaled (if it is not NULL). + Data can be downloaded from the MTFTPv4 server into either of the following locations: + 1.A fixed buffer that is pointed to by Token.Buffer + 2.A download service function that is pointed to by Token.CheckPacket + If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket + will be called first. If the call is successful, the packet will be stored in + Token.Buffer. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance + @param Token Pointer to the token structure to provide the + parameters that are used in this operation. + + @retval EFI_SUCCESS The data file has been transferred successfully. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_BUFFER_TOO_SMALL BufferSize is not large enough to hold the downloaded + data in downloading process. + @retval EFI_ABORTED Current operation is aborted by user. + @retval EFI_ICMP_ERROR An ICMP ERROR packet was received. + @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server. + @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + @retval EFI_NO_MEDIA There was a media error. **/ -STATIC EFI_STATUS EFIAPI EfiMtftp4ReadFile ( @@ -810,18 +808,55 @@ EfiMtftp4ReadFile ( /** - Upload a file to the server. - - @param This The MTFTP protocol session - @param Token The user's request wrap token. - - @retval EFI_SUCCESS The WriteFile has finished, the file has been - uploaded if it is synchronous operation, otherwise - it has been initated. - @retval Others Some error happened. + Sends a data file to an MTFTPv4 server. May be unsupported in some EFI implementations + + The WriteFile() function is used to initialize an uploading operation with the + given option list and optionally wait for completion. If one or more of the + options is not supported by the server, the unsupported options are ignored and + a standard TFTP process starts instead. When the upload process completes, + whether successfully or not, Token.Event is signaled, and the EFI MTFTPv4 Protocol + driver updates Token.Status. + The caller can supply the data to be uploaded in the following two modes: + 1.Through the user-provided buffer + 2.Through a callback function + With the user-provided buffer, the Token.BufferSize field indicates the length + of the buffer, and the driver will upload the data in the buffer. With an + EFI_MTFTP4_PACKET_NEEDED callback function, the driver will call this callback + function to get more data from the user to upload. See the definition of + EFI_MTFTP4_PACKET_NEEDED for more information. These two modes cannot be used at + the same time. The callback function will be ignored if the user provides the buffer. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token Pointer to the token structure to provide the + parameters that are used in this function + + @retval EFI_SUCCESS The upload session has started. + @retval EFI_UNSUPPORTED The operation is not supported by this implementation. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + 1. This is NULL. + 2. Token is NULL. + 3. Token.Filename is NULL. + 4. Token.OptionCount is not zero and + Token.OptionList is NULL. + 5. One or more options in Token.OptionList have wrong + format. + 6. Token.Buffer and Token.PacketNeeded are both + NULL. + 7. One or more IPv4 addresses in Token.OverrideData + are not valid unicast IPv4 addresses if + Token.OverrideData is not NULL. + @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the + unsupported list of structure EFI_MTFTP4_MODE_DATA. + @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, + BOOTP, RARP, etc.) is not finished yet. + @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4 + session. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. **/ -STATIC EFI_STATUS EFIAPI EfiMtftp4WriteFile ( @@ -834,19 +869,64 @@ EfiMtftp4WriteFile ( /** - Read a directory from the server. The only difference - between ReadFile and ReadDirectory is the opcode used. - - @param This The MTFTP protocol session - @param Token The user's request wrap token. - - @retval EFI_SUCCESS The ReadDirectory has finished, the directory has - been downloaded as a file if it is synchronous - operation, otherwise it has been initated. - @retval Others Some error happened. + Downloads a data file "directory" from an MTFTPv4 server. + May be unsupported in some EFI implementations + + The ReadDirectory() function is used to return a list of files on the MTFTPv4 + server that are logically (or operationally) related to Token.Filename. The + directory request packet that is sent to the server is built with the option + list that was provided by caller, if present. + The file information that the server returns is put into either of the following + locations: + 1.A fixed buffer that is pointed to by Token.Buffer + 2.A download service function that is pointed to by Token.CheckPacket + If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket will + be called first. If the call is successful, the packet will be stored in Token.Buffer. + The returned directory listing in the Token.Buffer or EFI_MTFTP4_PACKET consists + of a list of two or three variable-length ASCII strings, each terminated by a + null character, for each file in the directory. If the multicast option is involved, + the first field of each directory entry is the static multicast IP address and + UDP port number that is associated with the file name. The format of the field + is ip:ip:ip:ip:port. If the multicast option is not involved, this field and its + terminating null character are not present. + The next field of each directory entry is the file name and the last field is + the file information string. The information string contains the file size and + the create/modify timestamp. The format of the information string is filesize + yyyy-mm-dd hh:mm:ss:ffff. The timestamp is Coordinated Universal Time + (UTC; also known as Greenwich Mean Time [GMT]). + The only difference between ReadFile and ReadDirectory is the opcode used. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance + @param Token Pointer to the token structure to provide the + parameters that are used in this function + + @retval EFI_SUCCESS The MTFTPv4 related file "directory" has been downloaded. + @retval EFI_UNSUPPORTED The operation is not supported by this implementation. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + 1. This is NULL. + 2. Token is NULL. + 3. Token.Filename is NULL. + 4. Token.OptionCount is not zero and + Token.OptionList is NULL. + 5. One or more options in Token.OptionList have wrong + format. + 6. Token.Buffer and Token.PacketNeeded are both + NULL. + 7. One or more IPv4 addresses in Token.OverrideData + are not valid unicast IPv4 addresses if + Token.OverrideData is not NULL. + @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the + unsupported list of structure EFI_MTFTP4_MODE_DATA. + @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, + BOOTP, RARP, etc.) is not finished yet. + @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4 + session. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. **/ -STATIC EFI_STATUS EFIAPI EfiMtftp4ReadDirectory ( @@ -859,16 +939,140 @@ EfiMtftp4ReadDirectory ( /** - Poll the network stack to accelerate the packet process. + Gets information about a file from an MTFTPv4 server. + + The GetInfo() function assembles an MTFTPv4 request packet with options; + sends it to the MTFTPv4 server; and may return an MTFTPv4 OACK, MTFTPv4 ERROR, + or ICMP ERROR packet. Retries occur only if no response packets are received + from the MTFTPv4 server before the timeout expires. + It is implemented with EfiMtftp4ReadFile: build a token, then pass it to + EfiMtftp4ReadFile. In its check packet callback abort the opertions. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance + @param OverrideData Data that is used to override the existing + parameters. If NULL, the default parameters that + were set in the EFI_MTFTP4_PROTOCOL.Configure() + function are used + @param Filename Pointer to null-terminated ASCII file name string + @param ModeStr Pointer to null-terminated ASCII mode string. If NULL, "octet" + will be used + @param OptionCount Number of option/value string pairs in OptionList + @param OptionList Pointer to array of option/value string pairs. + Ignored if OptionCount is zero + @param PacketLength The number of bytes in the returned packet + @param Packet PacketThe pointer to the received packet. This + buffer must be freed by the caller. + + @retval EFI_SUCCESS An MTFTPv4 OACK packet was received and is in + the Buffer. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + 1.This is NULL. + 2.Filename is NULL. + 3.OptionCount is not zero and OptionList is NULL. + 4.One or more options in OptionList have wrong format. + 5.PacketLength is NULL. + 6.One or more IPv4 addresses in OverrideData are + not valid unicast IPv4 addresses if OverrideData + is not NULL. + @retval EFI_UNSUPPORTED One or more options in the OptionList are in the + unsupported list of structure EFI_MTFTP4_MODE_DATA + @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, + BOOTP, RARP, etc.) has not finished yet. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received and is in + the Buffer. + @retval EFI_ICMP_ERROR An ICMP ERROR packet was received and the Packet + is set to NULL. + @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv4 packet was received and is + in the Buffer. + @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + @retval EFI_NO_MEDIA There was a media error. + +**/ +EFI_STATUS +EFIAPI +EfiMtftp4GetInfo ( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData OPTIONAL, + IN UINT8 *Filename, + IN UINT8 *ModeStr OPTIONAL, + IN UINT8 OptionCount, + IN EFI_MTFTP4_OPTION *OptionList OPTIONAL, + OUT UINT32 *PacketLength, + OUT EFI_MTFTP4_PACKET **Packet OPTIONAL + ) +{ + EFI_MTFTP4_TOKEN Token; + MTFTP4_GETINFO_STATE State; + EFI_STATUS Status; + + if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) || + ((OptionCount != 0) && (OptionList == NULL))) { + return EFI_INVALID_PARAMETER; + } + + if (Packet != NULL) { + *Packet = NULL; + } + + *PacketLength = 0; + State.Packet = Packet; + State.PacketLen = PacketLength; + State.Status = EFI_SUCCESS; - @param This The MTFTP protocol instance. + // + // Fill in the Token to issue an synchronous ReadFile operation + // + Token.Status = EFI_SUCCESS; + Token.Event = NULL; + Token.OverrideData = OverrideData; + Token.Filename = Filename; + Token.ModeStr = ModeStr; + Token.OptionCount = OptionCount; + Token.OptionList = OptionList; + Token.BufferSize = 0; + Token.Buffer = NULL; + Token.Context = &State; + Token.CheckPacket = Mtftp4GetInfoCheckPacket; + Token.TimeoutCallback = NULL; + Token.PacketNeeded = NULL; + + Status = EfiMtftp4ReadFile (This, &Token); + if (EFI_ABORTED == Status) { + return State.Status; + } + + return Status; +} + +/** + Polls for incoming data packets and processes outgoing data packets. + + The Poll() function can be used by network drivers and applications to increase + the rate that data packets are moved between the communications device and the + transmit and receive queues. + In some systems, the periodic timer event in the managed network driver may not + poll the underlying communications device fast enough to transmit and/or receive + all data packets without missing incoming packets or dropping outgoing packets. + Drivers and applications that are experiencing packet loss should try calling + the Poll() function more often. + + @param This Pointer to the EFI_MTFTP4_PROTOCOL instance + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_NOT_STARTED This EFI MTFTPv4 Protocol instance has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, + BOOTP, RARP, etc.) is not finished yet. @retval EFI_INVALID_PARAMETER This is NULL. - @retval EFI_NOT_STARTED The MTFTP session hasn't been configured. - @retval EFI_DEVICE_ERROR The MTFTP session has been destoried. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive + queue. Consider increasing the polling rate. **/ -STATIC EFI_STATUS EFIAPI EfiMtftp4Poll ( @@ -877,6 +1081,7 @@ EfiMtftp4Poll ( { MTFTP4_PROTOCOL *Instance; EFI_UDP4_PROTOCOL *Udp; + EFI_STATUS Status; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -886,12 +1091,14 @@ EfiMtftp4Poll ( if (Instance->State == MTFTP4_STATE_UNCONFIGED) { return EFI_NOT_STARTED; - } else if (Instance->State == MTFTP4_STATE_DESTORY) { + } else if (Instance->State == MTFTP4_STATE_DESTROY) { return EFI_DEVICE_ERROR; } - Udp = Instance->UnicastPort->Udp; - return Udp->Poll (Udp); + Udp = Instance->UnicastPort->Protocol.Udp4; + Status = Udp->Poll (Udp); + Mtftp4OnTimerTick (NULL, Instance->Service); + return Status; } EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate = {