]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Impl.c
1 /** @file
2 Interface routine for Mtftp4.
3
4 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10
11 #include "Mtftp4Impl.h"
12
13
14 /**
15 Clean up the MTFTP session to get ready for new operation.
16
17 @param Instance The MTFTP session to clean up
18 @param Result The result to return to the caller who initiated
19 the operation.
20 **/
21 VOID
22 Mtftp4CleanOperation (
23 IN OUT MTFTP4_PROTOCOL *Instance,
24 IN EFI_STATUS Result
25 )
26 {
27 LIST_ENTRY *Entry;
28 LIST_ENTRY *Next;
29 MTFTP4_BLOCK_RANGE *Block;
30 EFI_MTFTP4_TOKEN *Token;
31
32 //
33 // Free various resources.
34 //
35 Token = Instance->Token;
36
37 if (Token != NULL) {
38 Token->Status = Result;
39
40 if (Token->Event != NULL) {
41 gBS->SignalEvent (Token->Event);
42 }
43
44 Instance->Token = NULL;
45 }
46
47 ASSERT (Instance->UnicastPort != NULL);
48 UdpIoCleanIo (Instance->UnicastPort);
49
50 if (Instance->LastPacket != NULL) {
51 NetbufFree (Instance->LastPacket);
52 Instance->LastPacket = NULL;
53 }
54
55 if (Instance->McastUdpPort != NULL) {
56 gBS->CloseProtocol (
57 Instance->McastUdpPort->UdpHandle,
58 &gEfiUdp4ProtocolGuid,
59 gMtftp4DriverBinding.DriverBindingHandle,
60 Instance->Handle
61 );
62 UdpIoFreeIo (Instance->McastUdpPort);
63 Instance->McastUdpPort = NULL;
64 }
65
66 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->Blocks) {
67 Block = NET_LIST_USER_STRUCT (Entry, MTFTP4_BLOCK_RANGE, Link);
68 RemoveEntryList (Entry);
69 FreePool (Block);
70 }
71
72 ZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION));
73
74 Instance->Operation = 0;
75
76 Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE;
77 Instance->WindowSize = 1;
78 Instance->TotalBlock = 0;
79 Instance->AckedBlock = 0;
80 Instance->LastBlock = 0;
81 Instance->ServerIp = 0;
82 Instance->ListeningPort = 0;
83 Instance->ConnectedPort = 0;
84 Instance->Gateway = 0;
85 Instance->PacketToLive = 0;
86 Instance->MaxRetry = 0;
87 Instance->CurRetry = 0;
88 Instance->Timeout = 0;
89 Instance->McastIp = 0;
90 Instance->McastPort = 0;
91 Instance->Master = TRUE;
92 }
93
94
95 /**
96 Check packet for GetInfo.
97
98 GetInfo is implemented with EfiMtftp4ReadFile. It use Mtftp4GetInfoCheckPacket
99 to inspect the first packet from server, then abort the session.
100
101 @param This The MTFTP4 protocol instance
102 @param Token The user's token
103 @param PacketLen The length of the packet
104 @param Packet The received packet.
105
106 @retval EFI_ABORTED Abort the ReadFile operation and return.
107
108 **/
109 EFI_STATUS
110 EFIAPI
111 Mtftp4GetInfoCheckPacket (
112 IN EFI_MTFTP4_PROTOCOL *This,
113 IN EFI_MTFTP4_TOKEN *Token,
114 IN UINT16 PacketLen,
115 IN EFI_MTFTP4_PACKET *Packet
116 )
117 {
118 MTFTP4_GETINFO_STATE *State;
119 EFI_STATUS Status;
120 UINT16 OpCode;
121 EFI_MTFTP4_ERROR_HEADER *ErrorHeader;
122
123 State = (MTFTP4_GETINFO_STATE *) Token->Context;
124 OpCode = NTOHS (Packet->OpCode);
125
126 //
127 // Set the GetInfo's return status according to the OpCode.
128 //
129 switch (OpCode) {
130 case EFI_MTFTP4_OPCODE_ERROR:
131 ErrorHeader = (EFI_MTFTP4_ERROR_HEADER *) Packet;
132 if (ErrorHeader->ErrorCode == EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND) {
133 DEBUG ((EFI_D_ERROR, "TFTP error code 1 (File Not Found)\n"));
134 } else {
135 DEBUG ((EFI_D_ERROR, "TFTP error code %d\n", ErrorHeader->ErrorCode));
136 }
137 State->Status = EFI_TFTP_ERROR;
138 break;
139
140 case EFI_MTFTP4_OPCODE_OACK:
141 State->Status = EFI_SUCCESS;
142 break;
143
144 default:
145 State->Status = EFI_PROTOCOL_ERROR;
146 }
147
148 //
149 // Allocate buffer then copy the packet over. Use gBS->AllocatePool
150 // in case AllocatePool will implements something tricky.
151 //
152 Status = gBS->AllocatePool (EfiBootServicesData, PacketLen, (VOID **) State->Packet);
153
154 if (EFI_ERROR (Status)) {
155 State->Status = EFI_OUT_OF_RESOURCES;
156 return EFI_ABORTED;
157 }
158
159 *(State->PacketLen) = PacketLen;
160 CopyMem (*(State->Packet), Packet, PacketLen);
161
162 return EFI_ABORTED;
163 }
164
165
166 /**
167 Check whether the override data is valid.
168
169 It will first validate whether the server is a valid unicast. If a gateway
170 is provided in the Override, it also check that it is a unicast on the
171 connected network.
172
173 @param Instance The MTFTP instance
174 @param Override The override data to validate.
175
176 @retval TRUE The override data is valid
177 @retval FALSE The override data is invalid
178
179 **/
180 BOOLEAN
181 Mtftp4OverrideValid (
182 IN MTFTP4_PROTOCOL *Instance,
183 IN EFI_MTFTP4_OVERRIDE_DATA *Override
184 )
185 {
186 EFI_MTFTP4_CONFIG_DATA *Config;
187 IP4_ADDR Ip;
188 IP4_ADDR Netmask;
189 IP4_ADDR Gateway;
190
191 CopyMem (&Ip, &Override->ServerIp, sizeof (IP4_ADDR));
192 if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
193 return FALSE;
194 }
195
196 Config = &Instance->Config;
197
198 CopyMem (&Gateway, &Override->GatewayIp, sizeof (IP4_ADDR));
199 Gateway = NTOHL (Gateway);
200
201 if (!Config->UseDefaultSetting && (Gateway != 0)) {
202 CopyMem (&Netmask, &Config->SubnetMask, sizeof (IP4_ADDR));
203 CopyMem (&Ip, &Config->StationIp, sizeof (IP4_ADDR));
204
205 Netmask = NTOHL (Netmask);
206 Ip = NTOHL (Ip);
207
208 if ((Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) {
209 return FALSE;
210 }
211 }
212
213 return TRUE;
214 }
215
216
217 /**
218 Poll the UDP to get the IP4 default address, which may be retrieved
219 by DHCP.
220
221 The default time out value is 5 seconds. If IP has retrieved the default address,
222 the UDP is reconfigured.
223
224 @param Instance The Mtftp instance
225 @param UdpIo The UDP_IO to poll
226 @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
227
228 @retval TRUE The default address is retrieved and UDP is reconfigured.
229 @retval FALSE Some error occured.
230
231 **/
232 BOOLEAN
233 Mtftp4GetMapping (
234 IN MTFTP4_PROTOCOL *Instance,
235 IN UDP_IO *UdpIo,
236 IN EFI_UDP4_CONFIG_DATA *UdpCfgData
237 )
238 {
239 MTFTP4_SERVICE *Service;
240 EFI_IP4_MODE_DATA Ip4Mode;
241 EFI_UDP4_PROTOCOL *Udp;
242 EFI_STATUS Status;
243
244 ASSERT (Instance->Config.UseDefaultSetting);
245
246 Service = Instance->Service;
247 Udp = UdpIo->Protocol.Udp4;
248
249 Status = gBS->SetTimer (
250 Service->TimerToGetMap,
251 TimerRelative,
252 MTFTP4_TIME_TO_GETMAP * TICKS_PER_SECOND
253 );
254 if (EFI_ERROR (Status)) {
255 return FALSE;
256 }
257
258 while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
259 Udp->Poll (Udp);
260
261 if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&
262 Ip4Mode.IsConfigured) {
263
264 Udp->Configure (Udp, NULL);
265 return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);
266 }
267 }
268
269 return FALSE;
270 }
271
272
273 /**
274 Configure the UDP port for unicast receiving.
275
276 @param UdpIo The UDP_IO instance
277 @param Instance The MTFTP session
278
279 @retval EFI_SUCCESS The UDP port is successfully configured for the
280 session to unicast receive.
281
282 **/
283 EFI_STATUS
284 Mtftp4ConfigUnicastPort (
285 IN UDP_IO *UdpIo,
286 IN MTFTP4_PROTOCOL *Instance
287 )
288 {
289 EFI_MTFTP4_CONFIG_DATA *Config;
290 EFI_UDP4_CONFIG_DATA UdpConfig;
291 EFI_STATUS Status;
292 IP4_ADDR Ip;
293
294 Config = &Instance->Config;
295
296 UdpConfig.AcceptBroadcast = FALSE;
297 UdpConfig.AcceptPromiscuous = FALSE;
298 UdpConfig.AcceptAnyPort = FALSE;
299 UdpConfig.AllowDuplicatePort = FALSE;
300 UdpConfig.TypeOfService = 0;
301 UdpConfig.TimeToLive = 64;
302 UdpConfig.DoNotFragment = FALSE;
303 UdpConfig.ReceiveTimeout = 0;
304 UdpConfig.TransmitTimeout = 0;
305 UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
306 IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);
307 IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);
308 UdpConfig.StationPort = Config->LocalPort;
309 UdpConfig.RemotePort = 0;
310
311 Ip = HTONL (Instance->ServerIp);
312 IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);
313
314 Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);
315
316 if ((Status == EFI_NO_MAPPING) && Mtftp4GetMapping (Instance, UdpIo, &UdpConfig)) {
317 return EFI_SUCCESS;
318 }
319
320 if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {
321 //
322 // The station IP address is manually configured and the Gateway IP is not 0.
323 // Add the default route for this UDP instance.
324 //
325 Status = UdpIo->Protocol.Udp4->Routes (
326 UdpIo->Protocol.Udp4,
327 FALSE,
328 &mZeroIp4Addr,
329 &mZeroIp4Addr,
330 &Config->GatewayIp
331 );
332 if (EFI_ERROR (Status)) {
333 UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, NULL);
334 }
335 }
336 return Status;
337 }
338
339
340 /**
341 Start the MTFTP session to do the operation, such as read file,
342 write file, and read directory.
343
344 @param This The MTFTP session
345 @param Token The token than encapsues the user's request.
346 @param Operation The operation to do
347
348 @retval EFI_INVALID_PARAMETER Some of the parameters are invalid.
349 @retval EFI_NOT_STARTED The MTFTP session hasn't been configured.
350 @retval EFI_ALREADY_STARTED There is pending operation for the session.
351 @retval EFI_SUCCESS The operation is successfully started.
352
353 **/
354 EFI_STATUS
355 Mtftp4Start (
356 IN EFI_MTFTP4_PROTOCOL *This,
357 IN EFI_MTFTP4_TOKEN *Token,
358 IN UINT16 Operation
359 )
360 {
361 MTFTP4_PROTOCOL *Instance;
362 EFI_MTFTP4_OVERRIDE_DATA *Override;
363 EFI_MTFTP4_CONFIG_DATA *Config;
364 EFI_TPL OldTpl;
365 EFI_STATUS Status;
366 EFI_STATUS TokenStatus;
367
368 //
369 // Validate the parameters
370 //
371 if ((This == NULL) || (Token == NULL) || (Token->Filename == NULL) ||
372 ((Token->OptionCount != 0) && (Token->OptionList == NULL))) {
373 return EFI_INVALID_PARAMETER;
374 }
375
376 //
377 // User must provide at least one method to collect the data for download.
378 //
379 if (((Operation == EFI_MTFTP4_OPCODE_RRQ) || (Operation == EFI_MTFTP4_OPCODE_DIR)) &&
380 ((Token->Buffer == NULL) && (Token->CheckPacket == NULL))) {
381 return EFI_INVALID_PARAMETER;
382 }
383
384 //
385 // User must provide at least one method to provide the data for upload.
386 //
387 if ((Operation == EFI_MTFTP4_OPCODE_WRQ) &&
388 ((Token->Buffer == NULL) && (Token->PacketNeeded == NULL))) {
389 return EFI_INVALID_PARAMETER;
390 }
391
392 Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
393
394 Status = EFI_SUCCESS;
395 TokenStatus = EFI_SUCCESS;
396
397 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
398
399 if (Instance->State != MTFTP4_STATE_CONFIGED) {
400 Status = EFI_NOT_STARTED;
401 }
402
403 if (Instance->Operation != 0) {
404 Status = EFI_ACCESS_DENIED;
405 }
406
407 if ((Token->OverrideData != NULL) && !Mtftp4OverrideValid (Instance, Token->OverrideData)) {
408 Status = EFI_INVALID_PARAMETER;
409 }
410
411 if (EFI_ERROR (Status)) {
412 gBS->RestoreTPL (OldTpl);
413 return Status;
414 }
415
416 //
417 // Set the Operation now to prevent the application start other
418 // operations.
419 //
420 Instance->Operation = Operation;
421 Override = Token->OverrideData;
422
423 if (Token->OptionCount != 0) {
424 Status = Mtftp4ParseOption (
425 Token->OptionList,
426 Token->OptionCount,
427 TRUE,
428 Instance->Operation,
429 &Instance->RequestOption
430 );
431
432 if (EFI_ERROR (Status)) {
433 TokenStatus = EFI_DEVICE_ERROR;
434 goto ON_ERROR;
435 }
436 }
437
438 //
439 // Set the operation parameters from the configuration or override data.
440 //
441 Config = &Instance->Config;
442 Instance->Token = Token;
443 Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE;
444 Instance->WindowSize = MTFTP4_DEFAULT_WINDOWSIZE;
445
446 CopyMem (&Instance->ServerIp, &Config->ServerIp, sizeof (IP4_ADDR));
447 Instance->ServerIp = NTOHL (Instance->ServerIp);
448
449 Instance->ListeningPort = Config->InitialServerPort;
450 Instance->ConnectedPort = 0;
451
452 CopyMem (&Instance->Gateway, &Config->GatewayIp, sizeof (IP4_ADDR));
453 Instance->Gateway = NTOHL (Instance->Gateway);
454
455 Instance->MaxRetry = Config->TryCount;
456 Instance->Timeout = Config->TimeoutValue;
457 Instance->Master = TRUE;
458
459 if (Override != NULL) {
460 CopyMem (&Instance->ServerIp, &Override->ServerIp, sizeof (IP4_ADDR));
461 CopyMem (&Instance->Gateway, &Override->GatewayIp, sizeof (IP4_ADDR));
462
463 Instance->ServerIp = NTOHL (Instance->ServerIp);
464 Instance->Gateway = NTOHL (Instance->Gateway);
465
466 Instance->ListeningPort = Override->ServerPort;
467 Instance->MaxRetry = Override->TryCount;
468 Instance->Timeout = Override->TimeoutValue;
469 }
470
471 if (Instance->ListeningPort == 0) {
472 Instance->ListeningPort = MTFTP4_DEFAULT_SERVER_PORT;
473 }
474
475 if (Instance->MaxRetry == 0) {
476 Instance->MaxRetry = MTFTP4_DEFAULT_RETRY;
477 }
478
479 if (Instance->Timeout == 0) {
480 Instance->Timeout = MTFTP4_DEFAULT_TIMEOUT;
481 }
482
483 //
484 // Config the unicast UDP child to send initial request
485 //
486 Status = Mtftp4ConfigUnicastPort (Instance->UnicastPort, Instance);
487 if (EFI_ERROR (Status)) {
488 TokenStatus = EFI_DEVICE_ERROR;
489 goto ON_ERROR;
490 }
491
492 //
493 // Set initial status.
494 //
495 Token->Status = EFI_NOT_READY;
496
497 //
498 // Build and send an initial requests
499 //
500 if (Operation == EFI_MTFTP4_OPCODE_WRQ) {
501 Status = Mtftp4WrqStart (Instance, Operation);
502 } else {
503 Status = Mtftp4RrqStart (Instance, Operation);
504 }
505
506 if (EFI_ERROR (Status)) {
507 TokenStatus = EFI_DEVICE_ERROR;
508 goto ON_ERROR;
509 }
510
511 gBS->RestoreTPL(OldTpl);
512
513 if (Token->Event != NULL) {
514 return EFI_SUCCESS;
515 }
516
517 //
518 // Return immediately for asynchronous operation or poll the
519 // instance for synchronous operation.
520 //
521 while (Token->Status == EFI_NOT_READY) {
522 This->Poll (This);
523 }
524
525 return Token->Status;
526
527 ON_ERROR:
528 Mtftp4CleanOperation (Instance, TokenStatus);
529 gBS->RestoreTPL (OldTpl);
530
531 return Status;
532 }
533
534
535 /**
536 Reads the current operational settings.
537
538 The GetModeData()function reads the current operational settings of this
539 EFI MTFTPv4 Protocol driver instance.
540
541 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.
542 @param ModeData Pointer to storage for the EFI MTFTPv4 Protocol
543 driver mode data.
544
545 @retval EFI_SUCCESS The configuration data was successfully returned.
546 @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated.
547 @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL.
548
549 **/
550 EFI_STATUS
551 EFIAPI
552 EfiMtftp4GetModeData (
553 IN EFI_MTFTP4_PROTOCOL *This,
554 OUT EFI_MTFTP4_MODE_DATA *ModeData
555 )
556 {
557 MTFTP4_PROTOCOL *Instance;
558 EFI_TPL OldTpl;
559
560 if ((This == NULL) || (ModeData == NULL)) {
561 return EFI_INVALID_PARAMETER;
562 }
563
564 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
565
566 Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
567 CopyMem(&ModeData->ConfigData, &Instance->Config, sizeof (Instance->Config));
568 ModeData->SupportedOptionCount = MTFTP4_SUPPORTED_OPTIONS;
569 ModeData->SupportedOptoins = (UINT8 **) mMtftp4SupportedOptions;
570 ModeData->UnsupportedOptionCount = 0;
571 ModeData->UnsupportedOptoins = NULL;
572
573 gBS->RestoreTPL (OldTpl);
574
575 return EFI_SUCCESS;
576 }
577
578
579
580 /**
581 Initializes, changes, or resets the default operational setting for this
582 EFI MTFTPv4 Protocol driver instance.
583
584 The Configure() function is used to set and change the configuration data for
585 this EFI MTFTPv4 Protocol driver instance. The configuration data can be reset
586 to startup defaults by calling Configure() with MtftpConfigData set to NULL.
587 Whenever the instance is reset, any pending operation is aborted. By changing
588 the EFI MTFTPv4 Protocol driver instance configuration data, the client can
589 connect to different MTFTPv4 servers. The configuration parameters in
590 MtftpConfigData are used as the default parameters in later MTFTPv4 operations
591 and can be overridden in later operations.
592
593 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance
594 @param ConfigData MtftpConfigDataPointer to the configuration data
595 structure
596
597 @retval EFI_SUCCESS The EFI MTFTPv4 Protocol driver was configured
598 successfully.
599 @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
600 1.This is NULL.
601 2.MtftpConfigData.UseDefaultSetting is FALSE and
602 MtftpConfigData.StationIp is not a valid IPv4
603 unicast address.
604 3.MtftpCofigData.UseDefaultSetting is FALSE and
605 MtftpConfigData.SubnetMask is invalid.
606 4.MtftpCofigData.ServerIp is not a valid IPv4
607 unicast address.
608 5.MtftpConfigData.UseDefaultSetting is FALSE and
609 MtftpConfigData.GatewayIp is not a valid IPv4
610 unicast address or is not in the same subnet
611 with station address.
612 @retval EFI_ACCESS_DENIED The EFI configuration could not be changed at this
613 time because there is one MTFTP background operation
614 in progress.
615 @retval EFI_NO_MAPPING When using a default address, configuration
616 (DHCP, BOOTP, RARP, etc.) has not finished yet.
617 @retval EFI_UNSUPPORTED A configuration protocol (DHCP, BOOTP, RARP, etc.)
618 could not be located when clients choose to use
619 the default address settings.
620 @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv4 Protocol driver instance data could
621 not be allocated.
622 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
623 The EFI MTFTPv4 Protocol driver instance is not
624 configured.
625
626 **/
627 EFI_STATUS
628 EFIAPI
629 EfiMtftp4Configure (
630 IN EFI_MTFTP4_PROTOCOL *This,
631 IN EFI_MTFTP4_CONFIG_DATA *ConfigData
632 )
633 {
634 MTFTP4_PROTOCOL *Instance;
635 EFI_TPL OldTpl;
636 IP4_ADDR Ip;
637 IP4_ADDR Netmask;
638 IP4_ADDR Gateway;
639 IP4_ADDR ServerIp;
640
641 if (This == NULL) {
642 return EFI_INVALID_PARAMETER;
643 }
644
645 Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
646
647 if (ConfigData == NULL) {
648 //
649 // Reset the operation if ConfigData is NULL
650 //
651 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
652
653 Mtftp4CleanOperation (Instance, EFI_ABORTED);
654 ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA));
655 Instance->State = MTFTP4_STATE_UNCONFIGED;
656
657 gBS->RestoreTPL (OldTpl);
658
659 } else {
660 //
661 // Configure the parameters for new operation.
662 //
663 CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR));
664 CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR));
665 CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR));
666 CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR));
667
668 Ip = NTOHL (Ip);
669 Netmask = NTOHL (Netmask);
670 Gateway = NTOHL (Gateway);
671 ServerIp = NTOHL (ServerIp);
672
673 if (ServerIp == 0 || IP4_IS_LOCAL_BROADCAST (ServerIp)) {
674 return EFI_INVALID_PARAMETER;
675 }
676
677 if (!ConfigData->UseDefaultSetting &&
678 ((!IP4_IS_VALID_NETMASK (Netmask) || (Netmask != 0 && !NetIp4IsUnicast (Ip, Netmask))))) {
679
680 return EFI_INVALID_PARAMETER;
681 }
682
683 if ((Gateway != 0) &&
684 ((Netmask != 0xFFFFFFFF && !IP4_NET_EQUAL (Gateway, Ip, Netmask)) || (Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)))) {
685
686 return EFI_INVALID_PARAMETER;
687 }
688
689 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
690
691 if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) {
692 gBS->RestoreTPL (OldTpl);
693 return EFI_ACCESS_DENIED;
694 }
695
696 CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));;
697 Instance->State = MTFTP4_STATE_CONFIGED;
698
699 gBS->RestoreTPL (OldTpl);
700 }
701
702 return EFI_SUCCESS;
703 }
704
705
706
707 /**
708 Parses the options in an MTFTPv4 OACK packet.
709
710 The ParseOptions() function parses the option fields in an MTFTPv4 OACK packet
711 and returns the number of options that were found and optionally a list of
712 pointers to the options in the packet.
713 If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is
714 returned and *OptionCount and *OptionList stop at the last valid option.
715 The OptionList is allocated by this function, and caller should free it when used.
716
717 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.
718 @param PacketLen Length of the OACK packet to be parsed.
719 @param Packet Pointer to the OACK packet to be parsed.
720 @param OptionCount Pointer to the number of options in following OptionList.
721 @param OptionList Pointer to EFI_MTFTP4_OPTION storage. Call the
722 EFI Boot Service FreePool() to release theOptionList
723 if the options in this OptionList are not needed
724 any more
725
726 @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and
727 OptionList parameters have been updated.
728 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
729 1.PacketLen is 0.
730 2.Packet is NULL or Packet is not a valid MTFTPv4 packet.
731 3.OptionCount is NULL.
732 @retval EFI_NOT_FOUND No options were found in the OACK packet.
733 @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array cannot be allocated.
734 @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid.
735
736 **/
737 EFI_STATUS
738 EFIAPI
739 EfiMtftp4ParseOptions (
740 IN EFI_MTFTP4_PROTOCOL *This,
741 IN UINT32 PacketLen,
742 IN EFI_MTFTP4_PACKET *Packet,
743 OUT UINT32 *OptionCount,
744 OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL
745 )
746 {
747 EFI_STATUS Status;
748
749 if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) ||
750 (Packet == NULL) || (OptionCount == NULL)) {
751
752 return EFI_INVALID_PARAMETER;
753 }
754
755 Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList);
756
757 if (EFI_ERROR (Status)) {
758 return Status;
759 }
760
761 if (*OptionCount == 0) {
762 return EFI_NOT_FOUND;
763 }
764
765 return EFI_SUCCESS;
766 }
767
768
769 /**
770 Downloads a file from an MTFTPv4 server.
771
772 The ReadFile() function is used to initialize and start an MTFTPv4 download
773 process and optionally wait for completion. When the download operation completes,
774 whether successfully or not, the Token.Status field is updated by the EFI MTFTPv4
775 Protocol driver and then Token.Event is signaled (if it is not NULL).
776 Data can be downloaded from the MTFTPv4 server into either of the following locations:
777 1.A fixed buffer that is pointed to by Token.Buffer
778 2.A download service function that is pointed to by Token.CheckPacket
779 If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket
780 will be called first. If the call is successful, the packet will be stored in
781 Token.Buffer.
782
783 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance
784 @param Token Pointer to the token structure to provide the
785 parameters that are used in this operation.
786
787 @retval EFI_SUCCESS The data file has been transferred successfully.
788 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
789 @retval EFI_BUFFER_TOO_SMALL BufferSize is not large enough to hold the downloaded
790 data in downloading process.
791 @retval EFI_ABORTED Current operation is aborted by user.
792 @retval EFI_ICMP_ERROR An ICMP ERROR packet was received.
793 @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server.
794 @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received.
795 @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.
796 @retval EFI_NO_MEDIA There was a media error.
797
798 **/
799 EFI_STATUS
800 EFIAPI
801 EfiMtftp4ReadFile (
802 IN EFI_MTFTP4_PROTOCOL *This,
803 IN EFI_MTFTP4_TOKEN *Token
804 )
805 {
806 return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_RRQ);
807 }
808
809
810 /**
811 Sends a data file to an MTFTPv4 server. May be unsupported in some EFI implementations
812
813 The WriteFile() function is used to initialize an uploading operation with the
814 given option list and optionally wait for completion. If one or more of the
815 options is not supported by the server, the unsupported options are ignored and
816 a standard TFTP process starts instead. When the upload process completes,
817 whether successfully or not, Token.Event is signaled, and the EFI MTFTPv4 Protocol
818 driver updates Token.Status.
819 The caller can supply the data to be uploaded in the following two modes:
820 1.Through the user-provided buffer
821 2.Through a callback function
822 With the user-provided buffer, the Token.BufferSize field indicates the length
823 of the buffer, and the driver will upload the data in the buffer. With an
824 EFI_MTFTP4_PACKET_NEEDED callback function, the driver will call this callback
825 function to get more data from the user to upload. See the definition of
826 EFI_MTFTP4_PACKET_NEEDED for more information. These two modes cannot be used at
827 the same time. The callback function will be ignored if the user provides the buffer.
828
829 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.
830 @param Token Pointer to the token structure to provide the
831 parameters that are used in this function
832
833 @retval EFI_SUCCESS The upload session has started.
834 @retval EFI_UNSUPPORTED The operation is not supported by this implementation.
835 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
836 1. This is NULL.
837 2. Token is NULL.
838 3. Token.Filename is NULL.
839 4. Token.OptionCount is not zero and
840 Token.OptionList is NULL.
841 5. One or more options in Token.OptionList have wrong
842 format.
843 6. Token.Buffer and Token.PacketNeeded are both
844 NULL.
845 7. One or more IPv4 addresses in Token.OverrideData
846 are not valid unicast IPv4 addresses if
847 Token.OverrideData is not NULL.
848 @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the
849 unsupported list of structure EFI_MTFTP4_MODE_DATA.
850 @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started.
851 @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
852 BOOTP, RARP, etc.) is not finished yet.
853 @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4
854 session.
855 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
856 @retval EFI_ACCESS_DENIED The previous operation has not completed yet.
857 @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.
858
859 **/
860 EFI_STATUS
861 EFIAPI
862 EfiMtftp4WriteFile (
863 IN EFI_MTFTP4_PROTOCOL *This,
864 IN EFI_MTFTP4_TOKEN *Token
865 )
866 {
867 return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_WRQ);
868 }
869
870
871 /**
872 Downloads a data file "directory" from an MTFTPv4 server.
873 May be unsupported in some EFI implementations
874
875 The ReadDirectory() function is used to return a list of files on the MTFTPv4
876 server that are logically (or operationally) related to Token.Filename. The
877 directory request packet that is sent to the server is built with the option
878 list that was provided by caller, if present.
879 The file information that the server returns is put into either of the following
880 locations:
881 1.A fixed buffer that is pointed to by Token.Buffer
882 2.A download service function that is pointed to by Token.CheckPacket
883 If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket will
884 be called first. If the call is successful, the packet will be stored in Token.Buffer.
885 The returned directory listing in the Token.Buffer or EFI_MTFTP4_PACKET consists
886 of a list of two or three variable-length ASCII strings, each terminated by a
887 null character, for each file in the directory. If the multicast option is involved,
888 the first field of each directory entry is the static multicast IP address and
889 UDP port number that is associated with the file name. The format of the field
890 is ip:ip:ip:ip:port. If the multicast option is not involved, this field and its
891 terminating null character are not present.
892 The next field of each directory entry is the file name and the last field is
893 the file information string. The information string contains the file size and
894 the create/modify timestamp. The format of the information string is filesize
895 yyyy-mm-dd hh:mm:ss:ffff. The timestamp is Coordinated Universal Time
896 (UTC; also known as Greenwich Mean Time [GMT]).
897 The only difference between ReadFile and ReadDirectory is the opcode used.
898
899 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance
900 @param Token Pointer to the token structure to provide the
901 parameters that are used in this function
902
903 @retval EFI_SUCCESS The MTFTPv4 related file "directory" has been downloaded.
904 @retval EFI_UNSUPPORTED The operation is not supported by this implementation.
905 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
906 1. This is NULL.
907 2. Token is NULL.
908 3. Token.Filename is NULL.
909 4. Token.OptionCount is not zero and
910 Token.OptionList is NULL.
911 5. One or more options in Token.OptionList have wrong
912 format.
913 6. Token.Buffer and Token.PacketNeeded are both
914 NULL.
915 7. One or more IPv4 addresses in Token.OverrideData
916 are not valid unicast IPv4 addresses if
917 Token.OverrideData is not NULL.
918 @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in the
919 unsupported list of structure EFI_MTFTP4_MODE_DATA.
920 @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started.
921 @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
922 BOOTP, RARP, etc.) is not finished yet.
923 @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4
924 session.
925 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
926 @retval EFI_ACCESS_DENIED The previous operation has not completed yet.
927 @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.
928
929 **/
930 EFI_STATUS
931 EFIAPI
932 EfiMtftp4ReadDirectory (
933 IN EFI_MTFTP4_PROTOCOL *This,
934 IN EFI_MTFTP4_TOKEN *Token
935 )
936 {
937 return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_DIR);
938 }
939
940
941 /**
942 Gets information about a file from an MTFTPv4 server.
943
944 The GetInfo() function assembles an MTFTPv4 request packet with options;
945 sends it to the MTFTPv4 server; and may return an MTFTPv4 OACK, MTFTPv4 ERROR,
946 or ICMP ERROR packet. Retries occur only if no response packets are received
947 from the MTFTPv4 server before the timeout expires.
948 It is implemented with EfiMtftp4ReadFile: build a token, then pass it to
949 EfiMtftp4ReadFile. In its check packet callback abort the opertions.
950
951 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance
952 @param OverrideData Data that is used to override the existing
953 parameters. If NULL, the default parameters that
954 were set in the EFI_MTFTP4_PROTOCOL.Configure()
955 function are used
956 @param Filename Pointer to null-terminated ASCII file name string
957 @param ModeStr Pointer to null-terminated ASCII mode string. If NULL, "octet"
958 will be used
959 @param OptionCount Number of option/value string pairs in OptionList
960 @param OptionList Pointer to array of option/value string pairs.
961 Ignored if OptionCount is zero
962 @param PacketLength The number of bytes in the returned packet
963 @param Packet PacketThe pointer to the received packet. This
964 buffer must be freed by the caller.
965
966 @retval EFI_SUCCESS An MTFTPv4 OACK packet was received and is in
967 the Buffer.
968 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
969 1.This is NULL.
970 2.Filename is NULL.
971 3.OptionCount is not zero and OptionList is NULL.
972 4.One or more options in OptionList have wrong format.
973 5.PacketLength is NULL.
974 6.One or more IPv4 addresses in OverrideData are
975 not valid unicast IPv4 addresses if OverrideData
976 is not NULL.
977 @retval EFI_UNSUPPORTED One or more options in the OptionList are in the
978 unsupported list of structure EFI_MTFTP4_MODE_DATA
979 @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started.
980 @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
981 BOOTP, RARP, etc.) has not finished yet.
982 @retval EFI_ACCESS_DENIED The previous operation has not completed yet.
983 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
984 @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received and is in
985 the Buffer.
986 @retval EFI_ICMP_ERROR An ICMP ERROR packet was received and the Packet
987 is set to NULL.
988 @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv4 packet was received and is
989 in the Buffer.
990 @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server.
991 @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.
992 @retval EFI_NO_MEDIA There was a media error.
993
994 **/
995 EFI_STATUS
996 EFIAPI
997 EfiMtftp4GetInfo (
998 IN EFI_MTFTP4_PROTOCOL *This,
999 IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData OPTIONAL,
1000 IN UINT8 *Filename,
1001 IN UINT8 *ModeStr OPTIONAL,
1002 IN UINT8 OptionCount,
1003 IN EFI_MTFTP4_OPTION *OptionList OPTIONAL,
1004 OUT UINT32 *PacketLength,
1005 OUT EFI_MTFTP4_PACKET **Packet OPTIONAL
1006 )
1007 {
1008 EFI_MTFTP4_TOKEN Token;
1009 MTFTP4_GETINFO_STATE State;
1010 EFI_STATUS Status;
1011
1012 if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) ||
1013 ((OptionCount != 0) && (OptionList == NULL))) {
1014 return EFI_INVALID_PARAMETER;
1015 }
1016
1017 if (Packet != NULL) {
1018 *Packet = NULL;
1019 }
1020
1021 *PacketLength = 0;
1022 State.Packet = Packet;
1023 State.PacketLen = PacketLength;
1024 State.Status = EFI_SUCCESS;
1025
1026 //
1027 // Fill in the Token to issue an synchronous ReadFile operation
1028 //
1029 Token.Status = EFI_SUCCESS;
1030 Token.Event = NULL;
1031 Token.OverrideData = OverrideData;
1032 Token.Filename = Filename;
1033 Token.ModeStr = ModeStr;
1034 Token.OptionCount = OptionCount;
1035 Token.OptionList = OptionList;
1036 Token.BufferSize = 0;
1037 Token.Buffer = NULL;
1038 Token.Context = &State;
1039 Token.CheckPacket = Mtftp4GetInfoCheckPacket;
1040 Token.TimeoutCallback = NULL;
1041 Token.PacketNeeded = NULL;
1042
1043 Status = EfiMtftp4ReadFile (This, &Token);
1044
1045 if (EFI_ABORTED == Status) {
1046 return State.Status;
1047 }
1048
1049 return Status;
1050 }
1051
1052 /**
1053 Polls for incoming data packets and processes outgoing data packets.
1054
1055 The Poll() function can be used by network drivers and applications to increase
1056 the rate that data packets are moved between the communications device and the
1057 transmit and receive queues.
1058 In some systems, the periodic timer event in the managed network driver may not
1059 poll the underlying communications device fast enough to transmit and/or receive
1060 all data packets without missing incoming packets or dropping outgoing packets.
1061 Drivers and applications that are experiencing packet loss should try calling
1062 the Poll() function more often.
1063
1064 @param This Pointer to the EFI_MTFTP4_PROTOCOL instance
1065
1066 @retval EFI_SUCCESS Incoming or outgoing data was processed.
1067 @retval EFI_NOT_STARTED This EFI MTFTPv4 Protocol instance has not been started.
1068 @retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
1069 BOOTP, RARP, etc.) is not finished yet.
1070 @retval EFI_INVALID_PARAMETER This is NULL.
1071 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
1072 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive
1073 queue. Consider increasing the polling rate.
1074
1075 **/
1076 EFI_STATUS
1077 EFIAPI
1078 EfiMtftp4Poll (
1079 IN EFI_MTFTP4_PROTOCOL *This
1080 )
1081 {
1082 MTFTP4_PROTOCOL *Instance;
1083 EFI_UDP4_PROTOCOL *Udp;
1084 EFI_STATUS Status;
1085
1086 if (This == NULL) {
1087 return EFI_INVALID_PARAMETER;
1088 }
1089
1090 Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
1091
1092 if (Instance->State == MTFTP4_STATE_UNCONFIGED) {
1093 return EFI_NOT_STARTED;
1094 } else if (Instance->State == MTFTP4_STATE_DESTROY) {
1095 return EFI_DEVICE_ERROR;
1096 }
1097
1098 Udp = Instance->UnicastPort->Protocol.Udp4;
1099 Status = Udp->Poll (Udp);
1100 Mtftp4OnTimerTick (NULL, Instance->Service);
1101 return Status;
1102 }
1103
1104 EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate = {
1105 EfiMtftp4GetModeData,
1106 EfiMtftp4Configure,
1107 EfiMtftp4GetInfo,
1108 EfiMtftp4ParseOptions,
1109 EfiMtftp4ReadFile,
1110 EfiMtftp4WriteFile,
1111 EfiMtftp4ReadDirectory,
1112 EfiMtftp4Poll
1113 };