+++ /dev/null
-/** @file\r
- Interface routine for Mtftp4.\r
-\r
-(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-\r
-#include "Mtftp4Impl.h"\r
-\r
-\r
-/**\r
- Clean up the MTFTP session to get ready for new operation.\r
-\r
- @param Instance The MTFTP session to clean up\r
- @param Result The result to return to the caller who initiated\r
- the operation.\r
-**/\r
-VOID\r
-Mtftp4CleanOperation (\r
- IN OUT MTFTP4_PROTOCOL *Instance,\r
- IN EFI_STATUS Result\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- LIST_ENTRY *Next;\r
- MTFTP4_BLOCK_RANGE *Block;\r
- EFI_MTFTP4_TOKEN *Token;\r
-\r
- //\r
- // Free various resources.\r
- //\r
- Token = Instance->Token;\r
-\r
- if (Token != NULL) {\r
- Token->Status = Result;\r
-\r
- if (Token->Event != NULL) {\r
- gBS->SignalEvent (Token->Event);\r
- }\r
-\r
- Instance->Token = NULL;\r
- }\r
-\r
- ASSERT (Instance->UnicastPort != NULL);\r
- UdpIoCleanIo (Instance->UnicastPort);\r
-\r
- if (Instance->LastPacket != NULL) {\r
- NetbufFree (Instance->LastPacket);\r
- Instance->LastPacket = NULL;\r
- }\r
-\r
- if (Instance->McastUdpPort != NULL) {\r
- gBS->CloseProtocol (\r
- Instance->McastUdpPort->UdpHandle,\r
- &gEfiUdp4ProtocolGuid,\r
- gMtftp4DriverBinding.DriverBindingHandle,\r
- Instance->Handle\r
- );\r
- UdpIoFreeIo (Instance->McastUdpPort);\r
- Instance->McastUdpPort = NULL;\r
- }\r
-\r
- NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->Blocks) {\r
- Block = NET_LIST_USER_STRUCT (Entry, MTFTP4_BLOCK_RANGE, Link);\r
- RemoveEntryList (Entry);\r
- FreePool (Block);\r
- }\r
-\r
- ZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION));\r
-\r
- Instance->Operation = 0;\r
-\r
- Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE;\r
- Instance->WindowSize = 1;\r
- Instance->TotalBlock = 0;\r
- Instance->AckedBlock = 0;\r
- Instance->LastBlock = 0;\r
- Instance->ServerIp = 0;\r
- Instance->ListeningPort = 0;\r
- Instance->ConnectedPort = 0;\r
- Instance->Gateway = 0;\r
- Instance->PacketToLive = 0;\r
- Instance->MaxRetry = 0;\r
- Instance->CurRetry = 0;\r
- Instance->Timeout = 0;\r
- Instance->McastIp = 0;\r
- Instance->McastPort = 0;\r
- Instance->Master = TRUE;\r
-}\r
-\r
-\r
-/**\r
- Check packet for GetInfo.\r
-\r
- GetInfo is implemented with EfiMtftp4ReadFile. It use Mtftp4GetInfoCheckPacket\r
- to inspect the first packet from server, then abort the session.\r
-\r
- @param This The MTFTP4 protocol instance\r
- @param Token The user's token\r
- @param PacketLen The length of the packet\r
- @param Packet The received packet.\r
-\r
- @retval EFI_ABORTED Abort the ReadFile operation and return.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Mtftp4GetInfoCheckPacket (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_TOKEN *Token,\r
- IN UINT16 PacketLen,\r
- IN EFI_MTFTP4_PACKET *Packet\r
- )\r
-{\r
- MTFTP4_GETINFO_STATE *State;\r
- EFI_STATUS Status;\r
- UINT16 OpCode;\r
- EFI_MTFTP4_ERROR_HEADER *ErrorHeader;\r
-\r
- State = (MTFTP4_GETINFO_STATE *) Token->Context;\r
- OpCode = NTOHS (Packet->OpCode);\r
-\r
- //\r
- // Set the GetInfo's return status according to the OpCode.\r
- //\r
- switch (OpCode) {\r
- case EFI_MTFTP4_OPCODE_ERROR:\r
- ErrorHeader = (EFI_MTFTP4_ERROR_HEADER *) Packet;\r
- if (ErrorHeader->ErrorCode == EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND) {\r
- DEBUG ((EFI_D_ERROR, "TFTP error code 1 (File Not Found)\n"));\r
- } else {\r
- DEBUG ((EFI_D_ERROR, "TFTP error code %d\n", ErrorHeader->ErrorCode));\r
- }\r
- State->Status = EFI_TFTP_ERROR;\r
- break;\r
-\r
- case EFI_MTFTP4_OPCODE_OACK:\r
- State->Status = EFI_SUCCESS;\r
- break;\r
-\r
- default:\r
- State->Status = EFI_PROTOCOL_ERROR;\r
- }\r
-\r
- //\r
- // Allocate buffer then copy the packet over. Use gBS->AllocatePool\r
- // in case AllocatePool will implements something tricky.\r
- //\r
- Status = gBS->AllocatePool (EfiBootServicesData, PacketLen, (VOID **) State->Packet);\r
-\r
- if (EFI_ERROR (Status)) {\r
- State->Status = EFI_OUT_OF_RESOURCES;\r
- return EFI_ABORTED;\r
- }\r
-\r
- *(State->PacketLen) = PacketLen;\r
- CopyMem (*(State->Packet), Packet, PacketLen);\r
-\r
- return EFI_ABORTED;\r
-}\r
-\r
-\r
-/**\r
- Check whether the override data is valid.\r
-\r
- It will first validate whether the server is a valid unicast. If a gateway\r
- is provided in the Override, it also check that it is a unicast on the\r
- connected network.\r
-\r
- @param Instance The MTFTP instance\r
- @param Override The override data to validate.\r
-\r
- @retval TRUE The override data is valid\r
- @retval FALSE The override data is invalid\r
-\r
-**/\r
-BOOLEAN\r
-Mtftp4OverrideValid (\r
- IN MTFTP4_PROTOCOL *Instance,\r
- IN EFI_MTFTP4_OVERRIDE_DATA *Override\r
- )\r
-{\r
- EFI_MTFTP4_CONFIG_DATA *Config;\r
- IP4_ADDR Ip;\r
- IP4_ADDR Netmask;\r
- IP4_ADDR Gateway;\r
-\r
- CopyMem (&Ip, &Override->ServerIp, sizeof (IP4_ADDR));\r
- if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {\r
- return FALSE;\r
- }\r
-\r
- Config = &Instance->Config;\r
-\r
- CopyMem (&Gateway, &Override->GatewayIp, sizeof (IP4_ADDR));\r
- Gateway = NTOHL (Gateway);\r
-\r
- if (!Config->UseDefaultSetting && (Gateway != 0)) {\r
- CopyMem (&Netmask, &Config->SubnetMask, sizeof (IP4_ADDR));\r
- CopyMem (&Ip, &Config->StationIp, sizeof (IP4_ADDR));\r
-\r
- Netmask = NTOHL (Netmask);\r
- Ip = NTOHL (Ip);\r
-\r
- if ((Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-/**\r
- Poll the UDP to get the IP4 default address, which may be retrieved\r
- by DHCP.\r
-\r
- The default time out value is 5 seconds. If IP has retrieved the default address,\r
- the UDP is reconfigured.\r
-\r
- @param Instance The Mtftp instance\r
- @param UdpIo The UDP_IO to poll\r
- @param UdpCfgData The UDP configure data to reconfigure the UDP_IO\r
-\r
- @retval TRUE The default address is retrieved and UDP is reconfigured.\r
- @retval FALSE Some error occured.\r
-\r
-**/\r
-BOOLEAN\r
-Mtftp4GetMapping (\r
- IN MTFTP4_PROTOCOL *Instance,\r
- IN UDP_IO *UdpIo,\r
- IN EFI_UDP4_CONFIG_DATA *UdpCfgData\r
- )\r
-{\r
- MTFTP4_SERVICE *Service;\r
- EFI_IP4_MODE_DATA Ip4Mode;\r
- EFI_UDP4_PROTOCOL *Udp;\r
- EFI_STATUS Status;\r
-\r
- ASSERT (Instance->Config.UseDefaultSetting);\r
-\r
- Service = Instance->Service;\r
- Udp = UdpIo->Protocol.Udp4;\r
-\r
- Status = gBS->SetTimer (\r
- Service->TimerToGetMap,\r
- TimerRelative,\r
- MTFTP4_TIME_TO_GETMAP * TICKS_PER_SECOND\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
- Udp->Poll (Udp);\r
-\r
- if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&\r
- Ip4Mode.IsConfigured) {\r
-\r
- Udp->Configure (Udp, NULL);\r
- return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-\r
-/**\r
- Configure the UDP port for unicast receiving.\r
-\r
- @param UdpIo The UDP_IO instance\r
- @param Instance The MTFTP session\r
-\r
- @retval EFI_SUCCESS The UDP port is successfully configured for the\r
- session to unicast receive.\r
-\r
-**/\r
-EFI_STATUS\r
-Mtftp4ConfigUnicastPort (\r
- IN UDP_IO *UdpIo,\r
- IN MTFTP4_PROTOCOL *Instance\r
- )\r
-{\r
- EFI_MTFTP4_CONFIG_DATA *Config;\r
- EFI_UDP4_CONFIG_DATA UdpConfig;\r
- EFI_STATUS Status;\r
- IP4_ADDR Ip;\r
-\r
- Config = &Instance->Config;\r
-\r
- UdpConfig.AcceptBroadcast = FALSE;\r
- UdpConfig.AcceptPromiscuous = FALSE;\r
- UdpConfig.AcceptAnyPort = FALSE;\r
- UdpConfig.AllowDuplicatePort = FALSE;\r
- UdpConfig.TypeOfService = 0;\r
- UdpConfig.TimeToLive = 64;\r
- UdpConfig.DoNotFragment = FALSE;\r
- UdpConfig.ReceiveTimeout = 0;\r
- UdpConfig.TransmitTimeout = 0;\r
- UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;\r
- IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);\r
- IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);\r
- UdpConfig.StationPort = Config->LocalPort;\r
- UdpConfig.RemotePort = 0;\r
-\r
- Ip = HTONL (Instance->ServerIp);\r
- IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);\r
-\r
- Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);\r
-\r
- if ((Status == EFI_NO_MAPPING) && Mtftp4GetMapping (Instance, UdpIo, &UdpConfig)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (!Config->UseDefaultSetting && !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 = UdpIo->Protocol.Udp4->Routes (\r
- UdpIo->Protocol.Udp4,\r
- FALSE,\r
- &mZeroIp4Addr,\r
- &mZeroIp4Addr,\r
- &Config->GatewayIp\r
- );\r
- if (EFI_ERROR (Status)) {\r
- UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, NULL);\r
- }\r
- }\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Start the MTFTP session to do the operation, such as read file,\r
- write file, and read directory.\r
-\r
- @param This The MTFTP session\r
- @param Token The token than encapsues the user's request.\r
- @param Operation The operation to do\r
-\r
- @retval EFI_INVALID_PARAMETER Some of the parameters are invalid.\r
- @retval EFI_NOT_STARTED The MTFTP session hasn't been configured.\r
- @retval EFI_ALREADY_STARTED There is pending operation for the session.\r
- @retval EFI_SUCCESS The operation is successfully started.\r
-\r
-**/\r
-EFI_STATUS\r
-Mtftp4Start (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_TOKEN *Token,\r
- IN UINT16 Operation\r
- )\r
-{\r
- MTFTP4_PROTOCOL *Instance;\r
- EFI_MTFTP4_OVERRIDE_DATA *Override;\r
- EFI_MTFTP4_CONFIG_DATA *Config;\r
- EFI_TPL OldTpl;\r
- EFI_STATUS Status;\r
- EFI_STATUS TokenStatus;\r
-\r
- //\r
- // Validate the parameters\r
- //\r
- if ((This == NULL) || (Token == NULL) || (Token->Filename == NULL) ||\r
- ((Token->OptionCount != 0) && (Token->OptionList == NULL))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // User must provide at least one method to collect the data for download.\r
- //\r
- if (((Operation == EFI_MTFTP4_OPCODE_RRQ) || (Operation == EFI_MTFTP4_OPCODE_DIR)) &&\r
- ((Token->Buffer == NULL) && (Token->CheckPacket == NULL))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // User must provide at least one method to provide the data for upload.\r
- //\r
- if ((Operation == EFI_MTFTP4_OPCODE_WRQ) &&\r
- ((Token->Buffer == NULL) && (Token->PacketNeeded == NULL))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-\r
- Status = EFI_SUCCESS;\r
- TokenStatus = EFI_SUCCESS;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- if (Instance->State != MTFTP4_STATE_CONFIGED) {\r
- Status = EFI_NOT_STARTED;\r
- }\r
-\r
- if (Instance->Operation != 0) {\r
- Status = EFI_ACCESS_DENIED;\r
- }\r
-\r
- if ((Token->OverrideData != NULL) && !Mtftp4OverrideValid (Instance, Token->OverrideData)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
- }\r
-\r
- //\r
- // Set the Operation now to prevent the application start other\r
- // operations.\r
- //\r
- Instance->Operation = Operation;\r
- Override = Token->OverrideData;\r
-\r
- if (Token->OptionCount != 0) {\r
- Status = Mtftp4ParseOption (\r
- Token->OptionList,\r
- Token->OptionCount,\r
- TRUE,\r
- Instance->Operation,\r
- &Instance->RequestOption\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- TokenStatus = EFI_DEVICE_ERROR;\r
- goto ON_ERROR;\r
- }\r
- }\r
-\r
- //\r
- // Set the operation parameters from the configuration or override data.\r
- //\r
- Config = &Instance->Config;\r
- Instance->Token = Token;\r
- Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE;\r
- Instance->WindowSize = MTFTP4_DEFAULT_WINDOWSIZE;\r
-\r
- CopyMem (&Instance->ServerIp, &Config->ServerIp, sizeof (IP4_ADDR));\r
- Instance->ServerIp = NTOHL (Instance->ServerIp);\r
-\r
- Instance->ListeningPort = Config->InitialServerPort;\r
- Instance->ConnectedPort = 0;\r
-\r
- CopyMem (&Instance->Gateway, &Config->GatewayIp, sizeof (IP4_ADDR));\r
- Instance->Gateway = NTOHL (Instance->Gateway);\r
-\r
- Instance->MaxRetry = Config->TryCount;\r
- Instance->Timeout = Config->TimeoutValue;\r
- Instance->Master = TRUE;\r
-\r
- if (Override != NULL) {\r
- CopyMem (&Instance->ServerIp, &Override->ServerIp, sizeof (IP4_ADDR));\r
- CopyMem (&Instance->Gateway, &Override->GatewayIp, sizeof (IP4_ADDR));\r
-\r
- Instance->ServerIp = NTOHL (Instance->ServerIp);\r
- Instance->Gateway = NTOHL (Instance->Gateway);\r
-\r
- Instance->ListeningPort = Override->ServerPort;\r
- Instance->MaxRetry = Override->TryCount;\r
- Instance->Timeout = Override->TimeoutValue;\r
- }\r
-\r
- if (Instance->ListeningPort == 0) {\r
- Instance->ListeningPort = MTFTP4_DEFAULT_SERVER_PORT;\r
- }\r
-\r
- if (Instance->MaxRetry == 0) {\r
- Instance->MaxRetry = MTFTP4_DEFAULT_RETRY;\r
- }\r
-\r
- if (Instance->Timeout == 0) {\r
- Instance->Timeout = MTFTP4_DEFAULT_TIMEOUT;\r
- }\r
-\r
- //\r
- // Config the unicast UDP child to send initial request\r
- //\r
- Status = Mtftp4ConfigUnicastPort (Instance->UnicastPort, Instance);\r
- if (EFI_ERROR (Status)) {\r
- TokenStatus = EFI_DEVICE_ERROR;\r
- goto ON_ERROR;\r
- }\r
-\r
- //\r
- // Set initial status.\r
- //\r
- Token->Status = EFI_NOT_READY;\r
-\r
- //\r
- // Build and send an initial requests\r
- //\r
- if (Operation == EFI_MTFTP4_OPCODE_WRQ) {\r
- Status = Mtftp4WrqStart (Instance, Operation);\r
- } else {\r
- Status = Mtftp4RrqStart (Instance, Operation);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- TokenStatus = EFI_DEVICE_ERROR;\r
- goto ON_ERROR;\r
- }\r
-\r
- gBS->RestoreTPL(OldTpl);\r
-\r
- if (Token->Event != NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Return immediately for asynchronous operation or poll the\r
- // instance for synchronous operation.\r
- //\r
- while (Token->Status == EFI_NOT_READY) {\r
- This->Poll (This);\r
- }\r
-\r
- return Token->Status;\r
-\r
-ON_ERROR:\r
- Mtftp4CleanOperation (Instance, TokenStatus);\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Reads the current operational settings.\r
-\r
- The GetModeData()function reads the current operational settings of this\r
- EFI MTFTPv4 Protocol driver instance.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
- @param ModeData Pointer to storage for the EFI MTFTPv4 Protocol\r
- driver mode data.\r
-\r
- @retval EFI_SUCCESS The configuration data was successfully returned.\r
- @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated.\r
- @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4GetModeData (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- OUT EFI_MTFTP4_MODE_DATA *ModeData\r
- )\r
-{\r
- MTFTP4_PROTOCOL *Instance;\r
- EFI_TPL OldTpl;\r
-\r
- if ((This == NULL) || (ModeData == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
- CopyMem(&ModeData->ConfigData, &Instance->Config, sizeof (Instance->Config));\r
- ModeData->SupportedOptionCount = MTFTP4_SUPPORTED_OPTIONS;\r
- ModeData->SupportedOptoins = (UINT8 **) mMtftp4SupportedOptions;\r
- ModeData->UnsupportedOptionCount = 0;\r
- ModeData->UnsupportedOptoins = NULL;\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-/**\r
- Initializes, changes, or resets the default operational setting for this\r
- EFI MTFTPv4 Protocol driver instance.\r
-\r
- The Configure() function is used to set and change the configuration data for\r
- this EFI MTFTPv4 Protocol driver instance. The configuration data can be reset\r
- to startup defaults by calling Configure() with MtftpConfigData set to NULL.\r
- Whenever the instance is reset, any pending operation is aborted. By changing\r
- the EFI MTFTPv4 Protocol driver instance configuration data, the client can\r
- connect to different MTFTPv4 servers. The configuration parameters in\r
- MtftpConfigData are used as the default parameters in later MTFTPv4 operations\r
- and can be overridden in later operations.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
- @param ConfigData MtftpConfigDataPointer to the configuration data\r
- structure\r
-\r
- @retval EFI_SUCCESS The EFI MTFTPv4 Protocol driver was configured\r
- successfully.\r
- @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:\r
- 1.This is NULL.\r
- 2.MtftpConfigData.UseDefaultSetting is FALSE and\r
- MtftpConfigData.StationIp is not a valid IPv4\r
- unicast address.\r
- 3.MtftpCofigData.UseDefaultSetting is FALSE and\r
- MtftpConfigData.SubnetMask is invalid.\r
- 4.MtftpCofigData.ServerIp is not a valid IPv4\r
- unicast address.\r
- 5.MtftpConfigData.UseDefaultSetting is FALSE and\r
- MtftpConfigData.GatewayIp is not a valid IPv4\r
- unicast address or is not in the same subnet\r
- with station address.\r
- @retval EFI_ACCESS_DENIED The EFI configuration could not be changed at this\r
- time because there is one MTFTP background operation\r
- in progress.\r
- @retval EFI_NO_MAPPING When using a default address, configuration\r
- (DHCP, BOOTP, RARP, etc.) has not finished yet.\r
- @retval EFI_UNSUPPORTED A configuration protocol (DHCP, BOOTP, RARP, etc.)\r
- could not be located when clients choose to use\r
- the default address settings.\r
- @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv4 Protocol driver instance data could\r
- not be allocated.\r
- @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
- The EFI MTFTPv4 Protocol driver instance is not\r
- configured.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4Configure (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_CONFIG_DATA *ConfigData\r
- )\r
-{\r
- MTFTP4_PROTOCOL *Instance;\r
- EFI_TPL OldTpl;\r
- IP4_ADDR Ip;\r
- IP4_ADDR Netmask;\r
- IP4_ADDR Gateway;\r
- IP4_ADDR ServerIp;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-\r
- if (ConfigData == NULL) {\r
- //\r
- // Reset the operation if ConfigData is NULL\r
- //\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- Mtftp4CleanOperation (Instance, EFI_ABORTED);\r
- ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA));\r
- Instance->State = MTFTP4_STATE_UNCONFIGED;\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- } else {\r
- //\r
- // Configure the parameters for new operation.\r
- //\r
- CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR));\r
- CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR));\r
- CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR));\r
- CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR));\r
-\r
- Ip = NTOHL (Ip);\r
- Netmask = NTOHL (Netmask);\r
- Gateway = NTOHL (Gateway);\r
- ServerIp = NTOHL (ServerIp);\r
-\r
- if (ServerIp == 0 || IP4_IS_LOCAL_BROADCAST (ServerIp)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!ConfigData->UseDefaultSetting &&\r
- ((!IP4_IS_VALID_NETMASK (Netmask) || (Netmask != 0 && !NetIp4IsUnicast (Ip, Netmask))))) {\r
-\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((Gateway != 0) &&\r
- ((Netmask != 0xFFFFFFFF && !IP4_NET_EQUAL (Gateway, Ip, Netmask)) || (Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)))) {\r
-\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
- if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) {\r
- gBS->RestoreTPL (OldTpl);\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));;\r
- Instance->State = MTFTP4_STATE_CONFIGED;\r
-\r
- gBS->RestoreTPL (OldTpl);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-/**\r
- Parses the options in an MTFTPv4 OACK packet.\r
-\r
- The ParseOptions() function parses the option fields in an MTFTPv4 OACK packet\r
- and returns the number of options that were found and optionally a list of\r
- pointers to the options in the packet.\r
- If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is\r
- returned and *OptionCount and *OptionList stop at the last valid option.\r
- The OptionList is allocated by this function, and caller should free it when used.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
- @param PacketLen Length of the OACK packet to be parsed.\r
- @param Packet Pointer to the OACK packet to be parsed.\r
- @param OptionCount Pointer to the number of options in following OptionList.\r
- @param OptionList Pointer to EFI_MTFTP4_OPTION storage. Call the\r
- EFI Boot Service FreePool() to release theOptionList\r
- if the options in this OptionList are not needed\r
- any more\r
-\r
- @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and\r
- OptionList parameters have been updated.\r
- @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
- 1.PacketLen is 0.\r
- 2.Packet is NULL or Packet is not a valid MTFTPv4 packet.\r
- 3.OptionCount is NULL.\r
- @retval EFI_NOT_FOUND No options were found in the OACK packet.\r
- @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array cannot be allocated.\r
- @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4ParseOptions (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN UINT32 PacketLen,\r
- IN EFI_MTFTP4_PACKET *Packet,\r
- OUT UINT32 *OptionCount,\r
- OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) ||\r
- (Packet == NULL) || (OptionCount == NULL)) {\r
-\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (*OptionCount == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Downloads a file from an MTFTPv4 server.\r
-\r
- The ReadFile() function is used to initialize and start an MTFTPv4 download\r
- process and optionally wait for completion. When the download operation completes,\r
- whether successfully or not, the Token.Status field is updated by the EFI MTFTPv4\r
- Protocol driver and then Token.Event is signaled (if it is not NULL).\r
- Data can be downloaded from the MTFTPv4 server into either of the following locations:\r
- 1.A fixed buffer that is pointed to by Token.Buffer\r
- 2.A download service function that is pointed to by Token.CheckPacket\r
- If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket\r
- will be called first. If the call is successful, the packet will be stored in\r
- Token.Buffer.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
- @param Token Pointer to the token structure to provide the\r
- parameters that are used in this operation.\r
-\r
- @retval EFI_SUCCESS The data file has been transferred successfully.\r
- @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
- @retval EFI_BUFFER_TOO_SMALL BufferSize is not large enough to hold the downloaded\r
- data in downloading process.\r
- @retval EFI_ABORTED Current operation is aborted by user.\r
- @retval EFI_ICMP_ERROR An ICMP ERROR packet was received.\r
- @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server.\r
- @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received.\r
- @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.\r
- @retval EFI_NO_MEDIA There was a media error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4ReadFile (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_TOKEN *Token\r
- )\r
-{\r
- return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_RRQ);\r
-}\r
-\r
-\r
-/**\r
- Sends a data file to an MTFTPv4 server. May be unsupported in some EFI implementations\r
-\r
- The WriteFile() function is used to initialize an uploading operation with the\r
- given option list and optionally wait for completion. If one or more of the\r
- options is not supported by the server, the unsupported options are ignored and\r
- a standard TFTP process starts instead. When the upload process completes,\r
- whether successfully or not, Token.Event is signaled, and the EFI MTFTPv4 Protocol\r
- driver updates Token.Status.\r
- The caller can supply the data to be uploaded in the following two modes:\r
- 1.Through the user-provided buffer\r
- 2.Through a callback function\r
- With the user-provided buffer, the Token.BufferSize field indicates the length\r
- of the buffer, and the driver will upload the data in the buffer. With an\r
- EFI_MTFTP4_PACKET_NEEDED callback function, the driver will call this callback\r
- function to get more data from the user to upload. See the definition of\r
- EFI_MTFTP4_PACKET_NEEDED for more information. These two modes cannot be used at\r
- the same time. The callback function will be ignored if the user provides the buffer.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
- @param Token Pointer to the token structure to provide the\r
- parameters that are used in this function\r
-\r
- @retval EFI_SUCCESS The upload session has started.\r
- @retval EFI_UNSUPPORTED The operation is not supported by this implementation.\r
- @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
- 1. This is NULL.\r
- 2. Token is NULL.\r
- 3. Token.Filename is NULL.\r
- 4. Token.OptionCount is not zero and\r
- Token.OptionList is NULL.\r
- 5. One or more options in Token.OptionList have wrong\r
- format.\r
- 6. Token.Buffer and Token.PacketNeeded are both\r
- NULL.\r
- 7. One or more IPv4 addresses in Token.OverrideData\r
- are not valid unicast IPv4 addresses if\r
- Token.OverrideData is not NULL.\r
- @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the\r
- unsupported list of structure EFI_MTFTP4_MODE_DATA.\r
- @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started.\r
- @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,\r
- BOOTP, RARP, etc.) is not finished yet.\r
- @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4\r
- session.\r
- @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
- @retval EFI_ACCESS_DENIED The previous operation has not completed yet.\r
- @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4WriteFile (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_TOKEN *Token\r
- )\r
-{\r
- return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_WRQ);\r
-}\r
-\r
-\r
-/**\r
- Downloads a data file "directory" from an MTFTPv4 server.\r
- May be unsupported in some EFI implementations\r
-\r
- The ReadDirectory() function is used to return a list of files on the MTFTPv4\r
- server that are logically (or operationally) related to Token.Filename. The\r
- directory request packet that is sent to the server is built with the option\r
- list that was provided by caller, if present.\r
- The file information that the server returns is put into either of the following\r
- locations:\r
- 1.A fixed buffer that is pointed to by Token.Buffer\r
- 2.A download service function that is pointed to by Token.CheckPacket\r
- If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket will\r
- be called first. If the call is successful, the packet will be stored in Token.Buffer.\r
- The returned directory listing in the Token.Buffer or EFI_MTFTP4_PACKET consists\r
- of a list of two or three variable-length ASCII strings, each terminated by a\r
- null character, for each file in the directory. If the multicast option is involved,\r
- the first field of each directory entry is the static multicast IP address and\r
- UDP port number that is associated with the file name. The format of the field\r
- is ip:ip:ip:ip:port. If the multicast option is not involved, this field and its\r
- terminating null character are not present.\r
- The next field of each directory entry is the file name and the last field is\r
- the file information string. The information string contains the file size and\r
- the create/modify timestamp. The format of the information string is filesize\r
- yyyy-mm-dd hh:mm:ss:ffff. The timestamp is Coordinated Universal Time\r
- (UTC; also known as Greenwich Mean Time [GMT]).\r
- The only difference between ReadFile and ReadDirectory is the opcode used.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
- @param Token Pointer to the token structure to provide the\r
- parameters that are used in this function\r
-\r
- @retval EFI_SUCCESS The MTFTPv4 related file "directory" has been downloaded.\r
- @retval EFI_UNSUPPORTED The operation is not supported by this implementation.\r
- @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
- 1. This is NULL.\r
- 2. Token is NULL.\r
- 3. Token.Filename is NULL.\r
- 4. Token.OptionCount is not zero and\r
- Token.OptionList is NULL.\r
- 5. One or more options in Token.OptionList have wrong\r
- format.\r
- 6. Token.Buffer and Token.PacketNeeded are both\r
- NULL.\r
- 7. One or more IPv4 addresses in Token.OverrideData\r
- are not valid unicast IPv4 addresses if\r
- Token.OverrideData is not NULL.\r
- @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the\r
- unsupported list of structure EFI_MTFTP4_MODE_DATA.\r
- @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started.\r
- @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,\r
- BOOTP, RARP, etc.) is not finished yet.\r
- @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4\r
- session.\r
- @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
- @retval EFI_ACCESS_DENIED The previous operation has not completed yet.\r
- @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4ReadDirectory (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_TOKEN *Token\r
- )\r
-{\r
- return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_DIR);\r
-}\r
-\r
-\r
-/**\r
- Gets information about a file from an MTFTPv4 server.\r
-\r
- The GetInfo() function assembles an MTFTPv4 request packet with options;\r
- sends it to the MTFTPv4 server; and may return an MTFTPv4 OACK, MTFTPv4 ERROR,\r
- or ICMP ERROR packet. Retries occur only if no response packets are received\r
- from the MTFTPv4 server before the timeout expires.\r
- It is implemented with EfiMtftp4ReadFile: build a token, then pass it to\r
- EfiMtftp4ReadFile. In its check packet callback abort the opertions.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
- @param OverrideData Data that is used to override the existing\r
- parameters. If NULL, the default parameters that\r
- were set in the EFI_MTFTP4_PROTOCOL.Configure()\r
- function are used\r
- @param Filename Pointer to null-terminated ASCII file name string\r
- @param ModeStr Pointer to null-terminated ASCII mode string. If NULL, "octet"\r
- will be used\r
- @param OptionCount Number of option/value string pairs in OptionList\r
- @param OptionList Pointer to array of option/value string pairs.\r
- Ignored if OptionCount is zero\r
- @param PacketLength The number of bytes in the returned packet\r
- @param Packet PacketThe pointer to the received packet. This\r
- buffer must be freed by the caller.\r
-\r
- @retval EFI_SUCCESS An MTFTPv4 OACK packet was received and is in\r
- the Buffer.\r
- @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
- 1.This is NULL.\r
- 2.Filename is NULL.\r
- 3.OptionCount is not zero and OptionList is NULL.\r
- 4.One or more options in OptionList have wrong format.\r
- 5.PacketLength is NULL.\r
- 6.One or more IPv4 addresses in OverrideData are\r
- not valid unicast IPv4 addresses if OverrideData\r
- is not NULL.\r
- @retval EFI_UNSUPPORTED One or more options in the OptionList are in the\r
- unsupported list of structure EFI_MTFTP4_MODE_DATA\r
- @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started.\r
- @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,\r
- BOOTP, RARP, etc.) has not finished yet.\r
- @retval EFI_ACCESS_DENIED The previous operation has not completed yet.\r
- @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
- @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received and is in\r
- the Buffer.\r
- @retval EFI_ICMP_ERROR An ICMP ERROR packet was received and the Packet\r
- is set to NULL.\r
- @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv4 packet was received and is\r
- in the Buffer.\r
- @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server.\r
- @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.\r
- @retval EFI_NO_MEDIA There was a media error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4GetInfo (\r
- IN EFI_MTFTP4_PROTOCOL *This,\r
- IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData OPTIONAL,\r
- IN UINT8 *Filename,\r
- IN UINT8 *ModeStr OPTIONAL,\r
- IN UINT8 OptionCount,\r
- IN EFI_MTFTP4_OPTION *OptionList OPTIONAL,\r
- OUT UINT32 *PacketLength,\r
- OUT EFI_MTFTP4_PACKET **Packet OPTIONAL\r
- )\r
-{\r
- EFI_MTFTP4_TOKEN Token;\r
- MTFTP4_GETINFO_STATE State;\r
- EFI_STATUS Status;\r
-\r
- if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) ||\r
- ((OptionCount != 0) && (OptionList == NULL))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Packet != NULL) {\r
- *Packet = NULL;\r
- }\r
-\r
- *PacketLength = 0;\r
- State.Packet = Packet;\r
- State.PacketLen = PacketLength;\r
- State.Status = EFI_SUCCESS;\r
-\r
- //\r
- // Fill in the Token to issue an synchronous ReadFile operation\r
- //\r
- Token.Status = EFI_SUCCESS;\r
- Token.Event = NULL;\r
- Token.OverrideData = OverrideData;\r
- Token.Filename = Filename;\r
- Token.ModeStr = ModeStr;\r
- Token.OptionCount = OptionCount;\r
- Token.OptionList = OptionList;\r
- Token.BufferSize = 0;\r
- Token.Buffer = NULL;\r
- Token.Context = &State;\r
- Token.CheckPacket = Mtftp4GetInfoCheckPacket;\r
- Token.TimeoutCallback = NULL;\r
- Token.PacketNeeded = NULL;\r
-\r
- Status = EfiMtftp4ReadFile (This, &Token);\r
-\r
- if (EFI_ABORTED == Status) {\r
- return State.Status;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Polls for incoming data packets and processes outgoing data packets.\r
-\r
- The Poll() function can be used by network drivers and applications to increase\r
- the rate that data packets are moved between the communications device and the\r
- transmit and receive queues.\r
- In some systems, the periodic timer event in the managed network driver may not\r
- poll the underlying communications device fast enough to transmit and/or receive\r
- all data packets without missing incoming packets or dropping outgoing packets.\r
- Drivers and applications that are experiencing packet loss should try calling\r
- the Poll() function more often.\r
-\r
- @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
-\r
- @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
- @retval EFI_NOT_STARTED This EFI MTFTPv4 Protocol instance has not been started.\r
- @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,\r
- BOOTP, RARP, etc.) is not finished yet.\r
- @retval EFI_INVALID_PARAMETER This is NULL.\r
- @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
- @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive\r
- queue. Consider increasing the polling rate.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4Poll (\r
- IN EFI_MTFTP4_PROTOCOL *This\r
- )\r
-{\r
- MTFTP4_PROTOCOL *Instance;\r
- EFI_UDP4_PROTOCOL *Udp;\r
- EFI_STATUS Status;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-\r
- if (Instance->State == MTFTP4_STATE_UNCONFIGED) {\r
- return EFI_NOT_STARTED;\r
- } else if (Instance->State == MTFTP4_STATE_DESTROY) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Udp = Instance->UnicastPort->Protocol.Udp4;\r
- Status = Udp->Poll (Udp);\r
- Mtftp4OnTimerTick (NULL, Instance->Service);\r
- return Status;\r
-}\r
-\r
-EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate = {\r
- EfiMtftp4GetModeData,\r
- EfiMtftp4Configure,\r
- EfiMtftp4GetInfo,\r
- EfiMtftp4ParseOptions,\r
- EfiMtftp4ReadFile,\r
- EfiMtftp4WriteFile,\r
- EfiMtftp4ReadDirectory,\r
- EfiMtftp4Poll\r
-};\r