TianoCore EDK2 master
Loading...
Searching...
No Matches
Mtftp6Rrq.c
Go to the documentation of this file.
1
10#include "Mtftp6Impl.h"
11
25 IN MTFTP6_INSTANCE *Instance,
26 IN UINT16 BlockNum
27 )
28{
30 NET_BUF *Packet;
31 EFI_STATUS Status;
32
33 Status = EFI_SUCCESS;
34
35 //
36 // Allocate net buffer to create ack packet.
37 //
38 Packet = NetbufAlloc (sizeof (EFI_MTFTP6_ACK_HEADER));
39
40 if (Packet == NULL) {
41 return EFI_OUT_OF_RESOURCES;
42 }
43
45 Packet,
46 sizeof (EFI_MTFTP6_ACK_HEADER),
47 FALSE
48 );
49 ASSERT (Ack != NULL);
50
51 Ack->Ack.OpCode = HTONS (EFI_MTFTP6_OPCODE_ACK);
52 Ack->Ack.Block[0] = HTONS (BlockNum);
53
54 //
55 // Reset current retry count of the instance.
56 //
57 Instance->CurRetry = 0;
58 Instance->LastPacket = Packet;
59
60 Status = Mtftp6TransmitPacket (Instance, Packet);
61 if (!EFI_ERROR (Status)) {
62 Instance->AckedBlock = Instance->TotalBlock;
63 }
64
65 return Status;
66}
67
86 IN MTFTP6_INSTANCE *Instance,
87 IN EFI_MTFTP6_PACKET *Packet,
88 IN UINT32 Len,
89 OUT NET_BUF **UdpPacket
90 )
91{
92 EFI_MTFTP6_TOKEN *Token;
93 EFI_STATUS Status;
94 UINT16 Block;
95 UINT64 Start;
96 UINT32 DataLen;
97 UINT64 BlockCounter;
98 BOOLEAN Completed;
99
100 Completed = FALSE;
101 Token = Instance->Token;
102 Block = NTOHS (Packet->Data.Block);
103 DataLen = Len - MTFTP6_DATA_HEAD_LEN;
104
105 //
106 // This is the last block, save the block num
107 //
108 if (DataLen < Instance->BlkSize) {
109 Completed = TRUE;
110 Instance->LastBlk = Block;
111 Mtftp6SetLastBlockNum (&Instance->BlkList, Block);
112 }
113
114 //
115 // Remove this block number from the file hole. If Mtftp6RemoveBlockNum
116 // returns EFI_NOT_FOUND, the block has been saved, don't save it again.
117 // Note that : For bigger files, allowing the block counter to roll over
118 // to accept transfers of unlimited size. So BlockCounter is memorised as
119 // continuous block counter.
120 //
121 Status = Mtftp6RemoveBlockNum (&Instance->BlkList, Block, Completed, &BlockCounter);
122
123 if (Status == EFI_NOT_FOUND) {
124 return EFI_SUCCESS;
125 } else if (EFI_ERROR (Status)) {
126 return Status;
127 }
128
129 if (Token->CheckPacket != NULL) {
130 //
131 // Callback to the check packet routine with the received packet.
132 //
133 Status = Token->CheckPacket (&Instance->Mtftp6, Token, (UINT16)Len, Packet);
134
135 if (EFI_ERROR (Status)) {
136 //
137 // Free the received packet before send new packet in ReceiveNotify,
138 // since the Udp6Io might need to be reconfigured.
139 //
140 NetbufFree (*UdpPacket);
141 *UdpPacket = NULL;
142 //
143 // Send the Mtftp6 error message if user aborted the current session.
144 //
146 Instance,
148 (UINT8 *)"User aborted download"
149 );
150
151 return EFI_ABORTED;
152 }
153 }
154
155 if (Token->Buffer != NULL) {
156 Start = MultU64x32 (BlockCounter - 1, Instance->BlkSize);
157 if (Start + DataLen <= Token->BufferSize) {
158 CopyMem ((UINT8 *)Token->Buffer + Start, Packet->Data.Data, DataLen);
159 //
160 // Update the file size when received the last block
161 //
162 if ((Instance->LastBlk == Block) && Completed) {
163 Token->BufferSize = Start + DataLen;
164 }
165 } else if (Instance->LastBlk != 0) {
166 //
167 // Don't save the data if the buffer is too small, return
168 // EFI_BUFFER_TOO_SMALL if received the last packet. This
169 // will give a accurate file length.
170 //
171 Token->BufferSize = Start + DataLen;
172
173 //
174 // Free the received packet before send new packet in ReceiveNotify,
175 // since the udpio might need to be reconfigured.
176 //
177 NetbufFree (*UdpPacket);
178 *UdpPacket = NULL;
179 //
180 // Send the Mtftp6 error message if no enough buffer.
181 //
183 Instance,
185 (UINT8 *)"User provided memory block is too small"
186 );
187
188 return EFI_BUFFER_TOO_SMALL;
189 }
190 }
191
192 return EFI_SUCCESS;
193}
194
213 IN MTFTP6_INSTANCE *Instance,
214 IN EFI_MTFTP6_PACKET *Packet,
215 IN UINT32 Len,
216 OUT NET_BUF **UdpPacket,
217 OUT BOOLEAN *IsCompleted
218 )
219{
220 EFI_STATUS Status;
221 UINT16 BlockNum;
222 INTN Expected;
223
224 *IsCompleted = FALSE;
225 Status = EFI_SUCCESS;
226 BlockNum = NTOHS (Packet->Data.Block);
227 Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);
228
229 ASSERT (Expected >= 0);
230
231 //
232 // If we are active (Master) and received an unexpected packet, transmit
233 // the ACK for the block we received, then restart receiving the
234 // expected one. If we are passive (Slave), save the block.
235 //
236 if (Instance->IsMaster && (Expected != BlockNum)) {
237 //
238 // Free the received packet before send new packet in ReceiveNotify,
239 // since the udpio might need to be reconfigured.
240 //
241 NetbufFree (*UdpPacket);
242 *UdpPacket = NULL;
243
244 //
245 // If Expected is 0, (UINT16) (Expected - 1) is also the expected Ack number (65535).
246 //
247 return Mtftp6RrqSendAck (Instance, (UINT16)(Expected - 1));
248 }
249
250 Status = Mtftp6RrqSaveBlock (Instance, Packet, Len, UdpPacket);
251
252 if (EFI_ERROR (Status)) {
253 return Status;
254 }
255
256 //
257 // Record the total received and saved block number.
258 //
259 Instance->TotalBlock++;
260
261 //
262 // Reset the passive client's timer whenever it received a valid data packet.
263 //
264 if (!Instance->IsMaster) {
265 Instance->PacketToLive = Instance->Timeout * 2;
266 }
267
268 //
269 // Check whether we have received all the blocks. Send the ACK if we
270 // are active (unicast client or master client for multicast download).
271 // If we have received all the blocks, send an ACK even if we are passive
272 // to tell the server that we are done.
273 //
274 Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);
275
276 if (Instance->IsMaster || (Expected < 0)) {
277 if (Expected < 0) {
278 //
279 // If we are passive client, then the just received Block maybe
280 // isn't the last block. We need to send an ACK to the last block
281 // to inform the server that we are done. If we are active client,
282 // the Block == Instance->LastBlock.
283 //
284 BlockNum = Instance->LastBlk;
285 *IsCompleted = TRUE;
286 } else {
287 BlockNum = (UINT16)(Expected - 1);
288 }
289
290 //
291 // Free the received packet before send new packet in ReceiveNotify,
292 // since the udpio might need to be reconfigured.
293 //
294 NetbufFree (*UdpPacket);
295 *UdpPacket = NULL;
296
297 if ((Instance->WindowSize == (Instance->TotalBlock - Instance->AckedBlock)) || (Expected < 0)) {
298 Status = Mtftp6RrqSendAck (Instance, BlockNum);
299 }
300 }
301
302 return Status;
303}
304
321BOOLEAN
323 IN MTFTP6_INSTANCE *Instance,
324 IN MTFTP6_EXT_OPTION_INFO *ReplyInfo,
325 IN MTFTP6_EXT_OPTION_INFO *RequestInfo
326 )
327{
328 //
329 // It is invalid for server to return options we don't request
330 //
331 if ((ReplyInfo->BitMap & ~RequestInfo->BitMap) != 0) {
332 return FALSE;
333 }
334
335 //
336 // Server can only specify a smaller block size and windowsize to be used and
337 // return the timeout matches that requested.
338 //
339 if ((((ReplyInfo->BitMap & MTFTP6_OPT_BLKSIZE_BIT) != 0) && (ReplyInfo->BlkSize > RequestInfo->BlkSize)) ||
340 (((ReplyInfo->BitMap & MTFTP6_OPT_WINDOWSIZE_BIT) != 0) && (ReplyInfo->BlkSize > RequestInfo->BlkSize)) ||
341 (((ReplyInfo->BitMap & MTFTP6_OPT_TIMEOUT_BIT) != 0) && (ReplyInfo->Timeout != RequestInfo->Timeout))
342 )
343 {
344 return FALSE;
345 }
346
347 //
348 // The server can send ",,master" to client to change its master
349 // setting. But if it use the specific multicast channel, it can't
350 // change the setting.
351 //
352 if (((ReplyInfo->BitMap & MTFTP6_OPT_MCAST_BIT) != 0) && !NetIp6IsUnspecifiedAddr (&Instance->McastIp)) {
353 if (!NetIp6IsUnspecifiedAddr (&ReplyInfo->McastIp) && (CompareMem (
354 &ReplyInfo->McastIp,
355 &Instance->McastIp,
356 sizeof (EFI_IPv6_ADDRESS)
357 ) != 0))
358 {
359 return FALSE;
360 }
361
362 if ((ReplyInfo->McastPort != 0) && (ReplyInfo->McastPort != Instance->McastPort)) {
363 return FALSE;
364 }
365 }
366
367 return TRUE;
368}
369
381EFIAPI
383 IN UDP_IO *McastIo,
384 IN VOID *Context
385 )
386{
387 EFI_STATUS Status;
388 EFI_UDP6_PROTOCOL *Udp6;
389 EFI_UDP6_CONFIG_DATA *Udp6Cfg;
390 EFI_IPv6_ADDRESS Group;
391 MTFTP6_INSTANCE *Instance;
392
393 Udp6 = McastIo->Protocol.Udp6;
394 Udp6Cfg = &(McastIo->Config.Udp6);
395 Instance = (MTFTP6_INSTANCE *)Context;
396
397 //
398 // Set the configure data for the mcast Udp6Io.
399 //
400 ZeroMem (Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));
401
402 Udp6Cfg->AcceptPromiscuous = FALSE;
403 Udp6Cfg->AcceptAnyPort = FALSE;
404 Udp6Cfg->AllowDuplicatePort = FALSE;
405 Udp6Cfg->TrafficClass = 0;
406 Udp6Cfg->HopLimit = 128;
407 Udp6Cfg->ReceiveTimeout = 0;
408 Udp6Cfg->TransmitTimeout = 0;
409 Udp6Cfg->StationPort = Instance->McastPort;
410 Udp6Cfg->RemotePort = 0;
411
412 CopyMem (
413 &Udp6Cfg->RemoteAddress,
414 &Instance->ServerIp,
415 sizeof (EFI_IPv6_ADDRESS)
416 );
417
418 //
419 // Configure the mcast Udp6Io.
420 //
421 Status = Udp6->Configure (Udp6, Udp6Cfg);
422
423 if (EFI_ERROR (Status)) {
424 return Status;
425 }
426
427 //
428 // Join the multicast group
429 //
430 CopyMem (&Group, &Instance->McastIp, sizeof (EFI_IPv6_ADDRESS));
431
432 return Udp6->Groups (Udp6, TRUE, &Group);
433}
434
452 IN MTFTP6_INSTANCE *Instance,
453 IN EFI_MTFTP6_PACKET *Packet,
454 IN UINT32 Len,
455 OUT NET_BUF **UdpPacket,
456 OUT BOOLEAN *IsCompleted
457 )
458{
459 EFI_MTFTP6_OPTION *Options;
460 UINT32 Count;
462 EFI_STATUS Status;
463 INTN Expected;
464 EFI_UDP6_PROTOCOL *Udp6;
465
466 *IsCompleted = FALSE;
467 Options = NULL;
468
469 //
470 // If already started the master download, don't change the
471 // setting. Master download always succeeds.
472 //
473 Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);
474 ASSERT (Expected != -1);
475
476 if (Instance->IsMaster && (Expected != 1)) {
477 return EFI_SUCCESS;
478 }
479
480 ZeroMem (&ExtInfo, sizeof (MTFTP6_EXT_OPTION_INFO));
481
482 //
483 // Parse the options in the packet.
484 //
485 Status = Mtftp6ParseStart (Packet, Len, &Count, &Options);
486
487 if (EFI_ERROR (Status)) {
488 return Status;
489 }
490
491 ASSERT (Options != NULL);
492
493 //
494 // Parse the extensive options in the packet.
495 //
496 Status = Mtftp6ParseExtensionOption (Options, Count, FALSE, Instance->Operation, &ExtInfo);
497
498 if (EFI_ERROR (Status) || !Mtftp6RrqOackValid (Instance, &ExtInfo, &Instance->ExtInfo)) {
499 //
500 // Don't send an ERROR packet if the error is EFI_OUT_OF_RESOURCES.
501 //
502 if (Status != EFI_OUT_OF_RESOURCES) {
503 //
504 // Free the received packet before send new packet in ReceiveNotify,
505 // since the udpio might need to be reconfigured.
506 //
507 NetbufFree (*UdpPacket);
508 *UdpPacket = NULL;
509 //
510 // Send the Mtftp6 error message if invalid packet.
511 //
513 Instance,
515 (UINT8 *)"Malformatted OACK packet"
516 );
517 }
518
519 return EFI_TFTP_ERROR;
520 }
521
522 if ((ExtInfo.BitMap & MTFTP6_OPT_MCAST_BIT) != 0) {
523 //
524 // Save the multicast info. Always update the Master, only update the
525 // multicast IP address, block size, window size, timeoute at the first time. If IP
526 // address is updated, create a UDP child to receive the multicast.
527 //
528 Instance->IsMaster = ExtInfo.IsMaster;
529
530 if (NetIp6IsUnspecifiedAddr (&Instance->McastIp)) {
531 if (NetIp6IsUnspecifiedAddr (&ExtInfo.McastIp) || (ExtInfo.McastPort == 0)) {
532 //
533 // Free the received packet before send new packet in ReceiveNotify,
534 // since the udpio might need to be reconfigured.
535 //
536 NetbufFree (*UdpPacket);
537 *UdpPacket = NULL;
538 //
539 // Send the Mtftp6 error message if invalid multi-cast setting.
540 //
542 Instance,
544 (UINT8 *)"Illegal multicast setting"
545 );
546
547 return EFI_TFTP_ERROR;
548 }
549
550 //
551 // Create a UDP child then start receive the multicast from it.
552 //
553 CopyMem (
554 &Instance->McastIp,
555 &ExtInfo.McastIp,
556 sizeof (EFI_IP_ADDRESS)
557 );
558
559 Instance->McastPort = ExtInfo.McastPort;
560 if (Instance->McastUdpIo == NULL) {
561 Instance->McastUdpIo = UdpIoCreateIo (
562 Instance->Service->Controller,
563 Instance->Service->Image,
565 UDP_IO_UDP6_VERSION,
566 Instance
567 );
568 if (Instance->McastUdpIo != NULL) {
569 Status = gBS->OpenProtocol (
570 Instance->McastUdpIo->UdpHandle,
571 &gEfiUdp6ProtocolGuid,
572 (VOID **)&Udp6,
573 Instance->Service->Image,
574 Instance->Handle,
575 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
576 );
577 if (EFI_ERROR (Status)) {
578 UdpIoFreeIo (Instance->McastUdpIo);
579 Instance->McastUdpIo = NULL;
580 return EFI_DEVICE_ERROR;
581 }
582 }
583 }
584
585 if (Instance->McastUdpIo == NULL) {
586 return EFI_DEVICE_ERROR;
587 }
588
589 Status = UdpIoRecvDatagram (
590 Instance->McastUdpIo,
592 Instance,
593 0
594 );
595
596 if (EFI_ERROR (Status)) {
597 //
598 // Free the received packet before send new packet in ReceiveNotify,
599 // since the udpio might need to be reconfigured.
600 //
601 NetbufFree (*UdpPacket);
602 *UdpPacket = NULL;
603 //
604 // Send the Mtftp6 error message if failed to create Udp6Io to receive.
605 //
607 Instance,
609 (UINT8 *)"Failed to create socket to receive multicast packet"
610 );
611
612 return Status;
613 }
614
615 //
616 // Update the parameters used.
617 //
618 if (ExtInfo.BlkSize != 0) {
619 Instance->BlkSize = ExtInfo.BlkSize;
620 }
621
622 if (ExtInfo.WindowSize != 0) {
623 Instance->WindowSize = ExtInfo.WindowSize;
624 }
625
626 if (ExtInfo.Timeout != 0) {
627 Instance->Timeout = ExtInfo.Timeout;
628 }
629 }
630 } else {
631 Instance->IsMaster = TRUE;
632
633 if (ExtInfo.BlkSize != 0) {
634 Instance->BlkSize = ExtInfo.BlkSize;
635 }
636
637 if (ExtInfo.WindowSize != 0) {
638 Instance->WindowSize = ExtInfo.WindowSize;
639 }
640
641 if (ExtInfo.Timeout != 0) {
642 Instance->Timeout = ExtInfo.Timeout;
643 }
644 }
645
646 //
647 // Free the received packet before send new packet in ReceiveNotify,
648 // since the udpio might need to be reconfigured.
649 //
650 NetbufFree (*UdpPacket);
651 *UdpPacket = NULL;
652 //
653 // Send an ACK to (Expected - 1) which is 0 for unicast download,
654 // or tell the server we want to receive the Expected block.
655 //
656 return Mtftp6RrqSendAck (Instance, (UINT16)(Expected - 1));
657}
658
668VOID
669EFIAPI
671 IN NET_BUF *UdpPacket,
672 IN UDP_END_POINT *UdpEpt,
673 IN EFI_STATUS IoStatus,
674 IN VOID *Context
675 )
676{
677 MTFTP6_INSTANCE *Instance;
678 EFI_MTFTP6_PACKET *Packet;
679 BOOLEAN IsCompleted;
680 BOOLEAN IsMcast;
681 EFI_STATUS Status;
682 UINT16 Opcode;
683 UINT32 TotalNum;
684 UINT32 Len;
685
686 Instance = (MTFTP6_INSTANCE *)Context;
687
688 NET_CHECK_SIGNATURE (Instance, MTFTP6_INSTANCE_SIGNATURE);
689
690 Status = EFI_SUCCESS;
691 Packet = NULL;
692 IsCompleted = FALSE;
693 IsMcast = FALSE;
694 TotalNum = 0;
695
696 //
697 // Return error status if Udp6 instance failed to receive.
698 //
699 if (EFI_ERROR (IoStatus)) {
700 Status = IoStatus;
701 goto ON_EXIT;
702 }
703
704 ASSERT (UdpPacket != NULL);
705
706 if (UdpPacket->TotalSize < MTFTP6_OPCODE_LEN) {
707 goto ON_EXIT;
708 }
709
710 //
711 // Find the port this packet is from to restart receive correctly.
712 //
713 if (CompareMem (
714 Ip6Swap128 (&UdpEpt->LocalAddr.v6),
715 &Instance->McastIp,
716 sizeof (EFI_IPv6_ADDRESS)
717 ) == 0)
718 {
719 IsMcast = TRUE;
720 } else {
721 IsMcast = FALSE;
722 }
723
724 //
725 // Client send initial request to server's listening port. Server
726 // will select a UDP port to communicate with the client. The server
727 // is required to use the same port as RemotePort to multicast the
728 // data.
729 //
730 if (UdpEpt->RemotePort != Instance->ServerDataPort) {
731 if (Instance->ServerDataPort != 0) {
732 goto ON_EXIT;
733 } else {
734 //
735 // For the subsequent exchange of requests, reconfigure the udpio as
736 // (serverip, serverport, localip, localport).
737 // Usually, the client set serverport as 0 to receive and reset it
738 // once the first packet arrives to send ack.
739 //
740 Instance->ServerDataPort = UdpEpt->RemotePort;
741 }
742 }
743
744 //
745 // Copy the MTFTP packet to a continuous buffer if it isn't already so.
746 //
747 Len = UdpPacket->TotalSize;
748 TotalNum = UdpPacket->BlockOpNum;
749
750 if (TotalNum > 1) {
751 Packet = AllocateZeroPool (Len);
752
753 if (Packet == NULL) {
754 Status = EFI_OUT_OF_RESOURCES;
755 goto ON_EXIT;
756 }
757
758 NetbufCopy (UdpPacket, 0, Len, (UINT8 *)Packet);
759 } else {
760 Packet = (EFI_MTFTP6_PACKET *)NetbufGetByte (UdpPacket, 0, NULL);
761 ASSERT (Packet != NULL);
762 }
763
764 Opcode = NTOHS (Packet->OpCode);
765
766 //
767 // Callback to the user's CheckPacket if provided. Abort the transmission
768 // if CheckPacket returns an EFI_ERROR code.
769 //
770 if ((Instance->Token->CheckPacket != NULL) &&
771 ((Opcode == EFI_MTFTP6_OPCODE_OACK) || (Opcode == EFI_MTFTP6_OPCODE_ERROR))
772 )
773 {
774 Status = Instance->Token->CheckPacket (
775 &Instance->Mtftp6,
776 Instance->Token,
777 (UINT16)Len,
778 Packet
779 );
780
781 if (EFI_ERROR (Status)) {
782 //
783 // Send an error message to the server to inform it
784 //
785 if (Opcode != EFI_MTFTP6_OPCODE_ERROR) {
786 //
787 // Free the received packet before send new packet in ReceiveNotify,
788 // since the udpio might need to be reconfigured.
789 //
790 NetbufFree (UdpPacket);
791 UdpPacket = NULL;
792 //
793 // Send the Mtftp6 error message if user aborted the current session.
794 //
796 Instance,
798 (UINT8 *)"User aborted the transfer"
799 );
800 }
801
802 Status = EFI_ABORTED;
803 goto ON_EXIT;
804 }
805 }
806
807 //
808 // Switch the process routines by the operation code.
809 //
810 switch (Opcode) {
812 if ((Len > (UINT32)(MTFTP6_DATA_HEAD_LEN + Instance->BlkSize)) || (Len < (UINT32)MTFTP6_DATA_HEAD_LEN)) {
813 goto ON_EXIT;
814 }
815
816 //
817 // Handle the data packet of Rrq.
818 //
819 Status = Mtftp6RrqHandleData (
820 Instance,
821 Packet,
822 Len,
823 &UdpPacket,
824 &IsCompleted
825 );
826 break;
827
829 if (IsMcast || (Len <= MTFTP6_OPCODE_LEN)) {
830 goto ON_EXIT;
831 }
832
833 //
834 // Handle the Oack packet of Rrq.
835 //
836 Status = Mtftp6RrqHandleOack (
837 Instance,
838 Packet,
839 Len,
840 &UdpPacket,
841 &IsCompleted
842 );
843 break;
844
845 default:
846 //
847 // Drop and return error if received error message.
848 //
849 Status = EFI_TFTP_ERROR;
850 break;
851 }
852
853ON_EXIT:
854 //
855 // Free the resources, then if !EFI_ERROR (Status), restart the
856 // receive, otherwise end the session.
857 //
858 if ((Packet != NULL) && (TotalNum > 1)) {
859 FreePool (Packet);
860 }
861
862 if (UdpPacket != NULL) {
863 NetbufFree (UdpPacket);
864 }
865
866 if (!EFI_ERROR (Status) && !IsCompleted) {
867 if (IsMcast) {
868 Status = UdpIoRecvDatagram (
869 Instance->McastUdpIo,
871 Instance,
872 0
873 );
874 } else {
875 Status = UdpIoRecvDatagram (
876 Instance->UdpIo,
878 Instance,
879 0
880 );
881 }
882 }
883
884 //
885 // Clean up the current session if failed to continue.
886 //
887 if (EFI_ERROR (Status) || IsCompleted) {
888 Mtftp6OperationClean (Instance, Status);
889 }
890}
891
906 IN MTFTP6_INSTANCE *Instance,
907 IN UINT16 Operation
908 )
909{
910 EFI_STATUS Status;
911
912 //
913 // The valid block number range are [1, 0xffff]. For example:
914 // the client sends an RRQ request to the server, the server
915 // transfers the DATA1 block. If option negotiation is ongoing,
916 // the server will send back an OACK, then client will send ACK0.
917 //
918 Status = Mtftp6InitBlockRange (&Instance->BlkList, 1, 0xffff);
919
920 if (EFI_ERROR (Status)) {
921 return Status;
922 }
923
924 Status = Mtftp6SendRequest (Instance, Operation);
925
926 if (EFI_ERROR (Status)) {
927 return Status;
928 }
929
930 return UdpIoRecvDatagram (
931 Instance->UdpIo,
933 Instance,
934 0
935 );
936}
INT64 INTN
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define EFI_MTFTP6_OPCODE_ERROR
The MTFTPv6 packet is an error packet.
Definition: Mtftp6.h:39
#define EFI_MTFTP6_OPCODE_OACK
The MTFTPv6 packet is an option acknowledgement packet.
Definition: Mtftp6.h:40
#define EFI_MTFTP6_ERRORCODE_ACCESS_VIOLATION
Definition: Mtftp6.h:60
#define EFI_MTFTP6_ERRORCODE_DISK_FULL
Definition: Mtftp6.h:64
#define EFI_MTFTP6_OPCODE_ACK
The MTFTPv6 packet is an acknowledgement packet.
Definition: Mtftp6.h:38
#define EFI_MTFTP6_ERRORCODE_REQUEST_DENIED
Definition: Mtftp6.h:84
#define EFI_MTFTP6_OPCODE_DATA
The MTFTPv6 packet is a data packet.
Definition: Mtftp6.h:37
#define EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION
Definition: Mtftp6.h:68
EFI_STATUS Mtftp6ParseExtensionOption(IN EFI_MTFTP6_OPTION *Options, IN UINT32 Count, IN BOOLEAN IsRequest, IN UINT16 Operation, IN MTFTP6_EXT_OPTION_INFO *ExtInfo)
Definition: Mtftp6Option.c:147
EFI_STATUS Mtftp6ParseStart(IN EFI_MTFTP6_PACKET *Packet, IN UINT32 PacketLen, IN OUT UINT32 *OptionCount, OUT EFI_MTFTP6_OPTION **OptionList OPTIONAL)
Definition: Mtftp6Option.c:340
EFI_STATUS Mtftp6RrqStart(IN MTFTP6_INSTANCE *Instance, IN UINT16 Operation)
Definition: Mtftp6Rrq.c:905
EFI_STATUS Mtftp6RrqSaveBlock(IN MTFTP6_INSTANCE *Instance, IN EFI_MTFTP6_PACKET *Packet, IN UINT32 Len, OUT NET_BUF **UdpPacket)
Definition: Mtftp6Rrq.c:85
BOOLEAN Mtftp6RrqOackValid(IN MTFTP6_INSTANCE *Instance, IN MTFTP6_EXT_OPTION_INFO *ReplyInfo, IN MTFTP6_EXT_OPTION_INFO *RequestInfo)
Definition: Mtftp6Rrq.c:322
VOID EFIAPI Mtftp6RrqInput(IN NET_BUF *UdpPacket, IN UDP_END_POINT *UdpEpt, IN EFI_STATUS IoStatus, IN VOID *Context)
Definition: Mtftp6Rrq.c:670
EFI_STATUS Mtftp6RrqHandleOack(IN MTFTP6_INSTANCE *Instance, IN EFI_MTFTP6_PACKET *Packet, IN UINT32 Len, OUT NET_BUF **UdpPacket, OUT BOOLEAN *IsCompleted)
Definition: Mtftp6Rrq.c:451
EFI_STATUS EFIAPI Mtftp6RrqConfigMcastUdpIo(IN UDP_IO *McastIo, IN VOID *Context)
Definition: Mtftp6Rrq.c:382
EFI_STATUS Mtftp6RrqHandleData(IN MTFTP6_INSTANCE *Instance, IN EFI_MTFTP6_PACKET *Packet, IN UINT32 Len, OUT NET_BUF **UdpPacket, OUT BOOLEAN *IsCompleted)
Definition: Mtftp6Rrq.c:212
EFI_STATUS Mtftp6RrqSendAck(IN MTFTP6_INSTANCE *Instance, IN UINT16 BlockNum)
Definition: Mtftp6Rrq.c:24
EFI_STATUS Mtftp6RemoveBlockNum(IN LIST_ENTRY *Head, IN UINT16 Num, IN BOOLEAN Completed, OUT UINT64 *BlockCounter)
EFI_STATUS Mtftp6SendError(IN MTFTP6_INSTANCE *Instance, IN UINT16 ErrCode, IN UINT8 *ErrInfo)
EFI_STATUS Mtftp6TransmitPacket(IN MTFTP6_INSTANCE *Instance, IN NET_BUF *Packet)
EFI_STATUS Mtftp6SendRequest(IN MTFTP6_INSTANCE *Instance, IN UINT16 Operation)
INTN Mtftp6GetNextBlockNum(IN LIST_ENTRY *Head)
Definition: Mtftp6Support.c:92
EFI_STATUS Mtftp6InitBlockRange(IN LIST_ENTRY *Head, IN UINT16 Start, IN UINT16 End)
Definition: Mtftp6Support.c:64
VOID Mtftp6SetLastBlockNum(IN LIST_ENTRY *Head, IN UINT16 Last)
VOID Mtftp6OperationClean(IN MTFTP6_INSTANCE *Instance, IN EFI_STATUS Result)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:195
UINT32 EFIAPI NetbufCopy(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT8 *Dest)
Definition: NetBuffer.c:1206
EFI_IPv6_ADDRESS *EFIAPI Ip6Swap128(EFI_IPv6_ADDRESS *Ip6)
Definition: DxeNetLib.c:892
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
Definition: NetBuffer.c:89
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
Definition: DxeNetLib.c:766
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
Definition: NetBuffer.c:1015
UINT8 *EFIAPI NetbufGetByte(IN NET_BUF *Nbuf, IN UINT32 Offset, OUT UINT32 *Index OPTIONAL)
Definition: NetBuffer.c:359
EFI_STATUS EFIAPI UdpIoRecvDatagram(IN UDP_IO *UdpIo, IN UDP_IO_CALLBACK CallBack, IN VOID *Context, IN UINT32 HeadLen)
Definition: DxeUdpIoLib.c:1084
EFI_STATUS EFIAPI UdpIoFreeIo(IN UDP_IO *UdpIo)
Definition: DxeUdpIoLib.c:809
UDP_IO *EFIAPI UdpIoCreateIo(IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle, IN UDP_IO_CONFIG Configure, IN UINT8 UdpVersion, IN VOID *Context)
Definition: DxeUdpIoLib.c:602
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
UINT64 BufferSize
Definition: Mtftp6.h:430
VOID * Buffer
Definition: Mtftp6.h:436
EFI_MTFTP6_CHECK_PACKET CheckPacket
Definition: Mtftp6.h:446
UINT16 Block[1]
Definition: Mtftp6.h:147
UINT16 StationPort
Definition: Udp6.h:168
BOOLEAN AcceptAnyPort
Definition: Udp6.h:126
UINT16 RemotePort
Definition: Udp6.h:182
BOOLEAN AcceptPromiscuous
Definition: Udp6.h:122
BOOLEAN AllowDuplicatePort
Definition: Udp6.h:131
EFI_IPv6_ADDRESS RemoteAddress
Definition: Udp6.h:175
UINT32 ReceiveTimeout
Definition: Udp6.h:144
UINT32 TransmitTimeout
Definition: Udp6.h:149
UINT8 TrafficClass
Definition: Udp6.h:135
EFI_MTFTP6_ACK_HEADER Ack
Acknowledgement packet header.
Definition: Mtftp6.h:209
UINT16 OpCode
Type of packets as defined by the MTFTPv6 packet opcodes.
Definition: Mtftp6.h:204