1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102 |
- /** @file
- Interface routine for Mtftp4.
- (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "Mtftp4Impl.h"
- /**
- Clean up the MTFTP session to get ready for new operation.
- @param Instance The MTFTP session to clean up
- @param Result The result to return to the caller who initiated
- the operation.
- **/
- VOID
- Mtftp4CleanOperation (
- IN OUT MTFTP4_PROTOCOL *Instance,
- IN EFI_STATUS Result
- )
- {
- LIST_ENTRY *Entry;
- LIST_ENTRY *Next;
- MTFTP4_BLOCK_RANGE *Block;
- EFI_MTFTP4_TOKEN *Token;
- //
- // Free various resources.
- //
- Token = Instance->Token;
- if (Token != NULL) {
- Token->Status = Result;
- if (Token->Event != NULL) {
- gBS->SignalEvent (Token->Event);
- }
- Instance->Token = NULL;
- }
- ASSERT (Instance->UnicastPort != NULL);
- UdpIoCleanIo (Instance->UnicastPort);
- if (Instance->LastPacket != NULL) {
- NetbufFree (Instance->LastPacket);
- Instance->LastPacket = NULL;
- }
- if (Instance->McastUdpPort != NULL) {
- 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);
- FreePool (Block);
- }
- ZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION));
- 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;
- Instance->ConnectedPort = 0;
- Instance->Gateway = 0;
- Instance->PacketToLive = 0;
- Instance->MaxRetry = 0;
- Instance->CurRetry = 0;
- Instance->Timeout = 0;
- Instance->McastIp = 0;
- Instance->McastPort = 0;
- Instance->Master = TRUE;
- }
- /**
- Check packet for GetInfo.
- 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
- @param PacketLen The length of the packet
- @param Packet The received packet.
- @retval EFI_ABORTED Abort the ReadFile operation and return.
- **/
- EFI_STATUS
- EFIAPI
- Mtftp4GetInfoCheckPacket (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token,
- IN UINT16 PacketLen,
- IN EFI_MTFTP4_PACKET *Packet
- )
- {
- MTFTP4_GETINFO_STATE *State;
- EFI_STATUS Status;
- UINT16 OpCode;
- EFI_MTFTP4_ERROR_HEADER *ErrorHeader;
- State = (MTFTP4_GETINFO_STATE *)Token->Context;
- OpCode = NTOHS (Packet->OpCode);
- //
- // Set the GetInfo's return status according to the OpCode.
- //
- switch (OpCode) {
- case EFI_MTFTP4_OPCODE_ERROR:
- ErrorHeader = (EFI_MTFTP4_ERROR_HEADER *)Packet;
- if (ErrorHeader->ErrorCode == EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND) {
- DEBUG ((DEBUG_ERROR, "TFTP error code 1 (File Not Found)\n"));
- } else {
- DEBUG ((DEBUG_ERROR, "TFTP error code %d\n", ErrorHeader->ErrorCode));
- }
- State->Status = EFI_TFTP_ERROR;
- break;
- case EFI_MTFTP4_OPCODE_OACK:
- State->Status = EFI_SUCCESS;
- break;
- default:
- State->Status = EFI_PROTOCOL_ERROR;
- }
- //
- // Allocate buffer then copy the packet over. Use gBS->AllocatePool
- // in case AllocatePool will implements something tricky.
- //
- Status = gBS->AllocatePool (EfiBootServicesData, PacketLen, (VOID **)State->Packet);
- if (EFI_ERROR (Status)) {
- State->Status = EFI_OUT_OF_RESOURCES;
- return EFI_ABORTED;
- }
- *(State->PacketLen) = PacketLen;
- CopyMem (*(State->Packet), Packet, PacketLen);
- return EFI_ABORTED;
- }
- /**
- 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.
- @param Instance The MTFTP instance
- @param Override The override data to validate.
- @retval TRUE The override data is valid
- @retval FALSE The override data is invalid
- **/
- BOOLEAN
- Mtftp4OverrideValid (
- IN MTFTP4_PROTOCOL *Instance,
- IN EFI_MTFTP4_OVERRIDE_DATA *Override
- )
- {
- EFI_MTFTP4_CONFIG_DATA *Config;
- IP4_ADDR Ip;
- IP4_ADDR Netmask;
- IP4_ADDR Gateway;
- CopyMem (&Ip, &Override->ServerIp, sizeof (IP4_ADDR));
- if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
- return FALSE;
- }
- Config = &Instance->Config;
- CopyMem (&Gateway, &Override->GatewayIp, sizeof (IP4_ADDR));
- Gateway = NTOHL (Gateway);
- if (!Config->UseDefaultSetting && (Gateway != 0)) {
- CopyMem (&Netmask, &Config->SubnetMask, sizeof (IP4_ADDR));
- CopyMem (&Ip, &Config->StationIp, sizeof (IP4_ADDR));
- Netmask = NTOHL (Netmask);
- Ip = NTOHL (Ip);
- if (((Netmask != 0) && !NetIp4IsUnicast (Gateway, Netmask)) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) {
- return FALSE;
- }
- }
- return TRUE;
- }
- /**
- 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.
- @param Instance The Mtftp instance
- @param UdpIo The UDP_IO to poll
- @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
- @retval TRUE The default address is retrieved and UDP is reconfigured.
- @retval FALSE Some error occurred.
- **/
- BOOLEAN
- Mtftp4GetMapping (
- IN MTFTP4_PROTOCOL *Instance,
- IN UDP_IO *UdpIo,
- IN EFI_UDP4_CONFIG_DATA *UdpCfgData
- )
- {
- MTFTP4_SERVICE *Service;
- EFI_IP4_MODE_DATA Ip4Mode;
- EFI_UDP4_PROTOCOL *Udp;
- EFI_STATUS Status;
- ASSERT (Instance->Config.UseDefaultSetting);
- Service = Instance->Service;
- Udp = UdpIo->Protocol.Udp4;
- Status = gBS->SetTimer (
- Service->TimerToGetMap,
- TimerRelative,
- MTFTP4_TIME_TO_GETMAP * TICKS_PER_SECOND
- );
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
- Udp->Poll (Udp);
- if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&
- Ip4Mode.IsConfigured)
- {
- Udp->Configure (Udp, NULL);
- return (BOOLEAN)(Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);
- }
- }
- return FALSE;
- }
- /**
- Configure the UDP port for unicast receiving.
- @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.
- **/
- EFI_STATUS
- Mtftp4ConfigUnicastPort (
- IN UDP_IO *UdpIo,
- IN MTFTP4_PROTOCOL *Instance
- )
- {
- EFI_MTFTP4_CONFIG_DATA *Config;
- EFI_UDP4_CONFIG_DATA UdpConfig;
- EFI_STATUS Status;
- IP4_ADDR Ip;
- Config = &Instance->Config;
- UdpConfig.AcceptBroadcast = FALSE;
- UdpConfig.AcceptPromiscuous = FALSE;
- UdpConfig.AcceptAnyPort = FALSE;
- UdpConfig.AllowDuplicatePort = FALSE;
- UdpConfig.TypeOfService = 0;
- UdpConfig.TimeToLive = 64;
- UdpConfig.DoNotFragment = FALSE;
- UdpConfig.ReceiveTimeout = 0;
- UdpConfig.TransmitTimeout = 0;
- UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
- 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);
- IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);
- Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);
- if ((Status == EFI_NO_MAPPING) && Mtftp4GetMapping (Instance, UdpIo, &UdpConfig)) {
- return EFI_SUCCESS;
- }
- if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {
- //
- // The station IP address is manually configured and the Gateway IP is not 0.
- // Add the default route for this UDP instance.
- //
- Status = UdpIo->Protocol.Udp4->Routes (
- UdpIo->Protocol.Udp4,
- FALSE,
- &mZeroIp4Addr,
- &mZeroIp4Addr,
- &Config->GatewayIp
- );
- if (EFI_ERROR (Status)) {
- UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, NULL);
- }
- }
- return Status;
- }
- /**
- Start the MTFTP session to do the operation, such as read file,
- write file, and read directory.
- @param This The MTFTP session
- @param Token The token than encapsules the user's request.
- @param Operation The operation to do
- @retval EFI_INVALID_PARAMETER Some of the parameters are invalid.
- @retval EFI_NOT_STARTED The MTFTP session hasn't been configured.
- @retval EFI_ALREADY_STARTED There is pending operation for the session.
- @retval EFI_SUCCESS The operation is successfully started.
- **/
- EFI_STATUS
- Mtftp4Start (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token,
- IN UINT16 Operation
- )
- {
- MTFTP4_PROTOCOL *Instance;
- EFI_MTFTP4_OVERRIDE_DATA *Override;
- EFI_MTFTP4_CONFIG_DATA *Config;
- EFI_TPL OldTpl;
- EFI_STATUS Status;
- EFI_STATUS TokenStatus;
- //
- // Validate the parameters
- //
- if ((This == NULL) || (Token == NULL) || (Token->Filename == NULL) ||
- ((Token->OptionCount != 0) && (Token->OptionList == NULL)))
- {
- return EFI_INVALID_PARAMETER;
- }
- //
- // User must provide at least one method to collect the data for download.
- //
- if (((Operation == EFI_MTFTP4_OPCODE_RRQ) || (Operation == EFI_MTFTP4_OPCODE_DIR)) &&
- ((Token->Buffer == NULL) && (Token->CheckPacket == NULL)))
- {
- return EFI_INVALID_PARAMETER;
- }
- //
- // User must provide at least one method to provide the data for upload.
- //
- if ((Operation == EFI_MTFTP4_OPCODE_WRQ) &&
- ((Token->Buffer == NULL) && (Token->PacketNeeded == NULL)))
- {
- return EFI_INVALID_PARAMETER;
- }
- Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
- Status = EFI_SUCCESS;
- TokenStatus = EFI_SUCCESS;
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- if (Instance->State != MTFTP4_STATE_CONFIGED) {
- Status = EFI_NOT_STARTED;
- }
- if (Instance->Operation != 0) {
- 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;
- }
- //
- // Set the Operation now to prevent the application start other
- // operations.
- //
- Instance->Operation = Operation;
- Override = Token->OverrideData;
- 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;
- }
- }
- //
- // Set the operation parameters from the configuration or override data.
- //
- 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);
- Instance->ListeningPort = Config->InitialServerPort;
- Instance->ConnectedPort = 0;
- CopyMem (&Instance->Gateway, &Config->GatewayIp, sizeof (IP4_ADDR));
- Instance->Gateway = NTOHL (Instance->Gateway);
- Instance->MaxRetry = Config->TryCount;
- Instance->Timeout = Config->TimeoutValue;
- Instance->Master = TRUE;
- if (Override != NULL) {
- CopyMem (&Instance->ServerIp, &Override->ServerIp, sizeof (IP4_ADDR));
- CopyMem (&Instance->Gateway, &Override->GatewayIp, sizeof (IP4_ADDR));
- Instance->ServerIp = NTOHL (Instance->ServerIp);
- Instance->Gateway = NTOHL (Instance->Gateway);
- Instance->ListeningPort = Override->ServerPort;
- Instance->MaxRetry = Override->TryCount;
- Instance->Timeout = Override->TimeoutValue;
- }
- if (Instance->ListeningPort == 0) {
- Instance->ListeningPort = MTFTP4_DEFAULT_SERVER_PORT;
- }
- if (Instance->MaxRetry == 0) {
- Instance->MaxRetry = MTFTP4_DEFAULT_RETRY;
- }
- if (Instance->Timeout == 0) {
- Instance->Timeout = MTFTP4_DEFAULT_TIMEOUT;
- }
- //
- // 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
- //
- if (Operation == EFI_MTFTP4_OPCODE_WRQ) {
- Status = Mtftp4WrqStart (Instance, Operation);
- } else {
- Status = Mtftp4RrqStart (Instance, Operation);
- }
- if (EFI_ERROR (Status)) {
- TokenStatus = EFI_DEVICE_ERROR;
- goto ON_ERROR;
- }
- 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);
- }
- return Token->Status;
- ON_ERROR:
- Mtftp4CleanOperation (Instance, TokenStatus);
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- /**
- 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.MtftpConfigData.UseDefaultSetting is FALSE and
- MtftpConfigData.SubnetMask is invalid.
- 4.MtftpConfigData.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;
- }
- return EFI_SUCCESS;
- }
- /**
- 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.
- **/
- EFI_STATUS
- EFIAPI
- EfiMtftp4ReadFile (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token
- )
- {
- return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_RRQ);
- }
- /**
- 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.
- **/
- EFI_STATUS
- EFIAPI
- EfiMtftp4WriteFile (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token
- )
- {
- return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_WRQ);
- }
- /**
- 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.
- **/
- EFI_STATUS
- EFIAPI
- EfiMtftp4ReadDirectory (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token
- )
- {
- return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_DIR);
- }
- /**
- 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 operations.
- @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;
- //
- // 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_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.
- **/
- EFI_STATUS
- EFIAPI
- EfiMtftp4Poll (
- IN EFI_MTFTP4_PROTOCOL *This
- )
- {
- MTFTP4_PROTOCOL *Instance;
- EFI_UDP4_PROTOCOL *Udp;
- EFI_STATUS Status;
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
- if (Instance->State == MTFTP4_STATE_UNCONFIGED) {
- return EFI_NOT_STARTED;
- } else if (Instance->State == MTFTP4_STATE_DESTROY) {
- return EFI_DEVICE_ERROR;
- }
- Udp = Instance->UnicastPort->Protocol.Udp4;
- Status = Udp->Poll (Udp);
- Mtftp4OnTimerTick (NULL, Instance->Service);
- return Status;
- }
- EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate = {
- EfiMtftp4GetModeData,
- EfiMtftp4Configure,
- EfiMtftp4GetInfo,
- EfiMtftp4ParseOptions,
- EfiMtftp4ReadFile,
- EfiMtftp4WriteFile,
- EfiMtftp4ReadDirectory,
- EfiMtftp4Poll
- };
|