]>
git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Mtftp4Dxe/Mtftp4Option.c
2 Routines to process MTFTP4 options.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "Mtftp4Impl.h"
11 CHAR8
*mMtftp4SupportedOptions
[MTFTP4_SUPPORTED_OPTIONS
] = {
20 Check whether two ascii strings are equal, ignore the case.
22 @param Str1 The first ascii string
23 @param Str2 The second ascii string
25 @retval TRUE Two strings are equal when case is ignored.
26 @retval FALSE Two strings are not equal.
30 NetStringEqualNoCase (
38 ASSERT ((Str1
!= NULL
) && (Str2
!= NULL
));
40 for ( ; (*Str1
!= '\0') && (*Str2
!= '\0'); Str1
++, Str2
++) {
45 // Convert them to lower case then compare two
47 if (('A' <= Ch1
) && (Ch1
<= 'Z')) {
51 if (('A' <= Ch2
) && (Ch2
<= 'Z')) {
60 return (BOOLEAN
)(*Str1
== *Str2
);
64 Convert a string to a UINT32 number.
66 @param Str The string to convert from
68 @return The number get from the string
82 for ( ; NET_IS_DIGIT (*Str
); Str
++) {
83 Num
= Num
* 10 + (*Str
- '0');
90 Convert a string of the format "192.168.0.1" to an IP address.
92 @param Str The string representation of IP
93 @param Ip The variable to get IP.
95 @retval EFI_INVALID_PARAMETER The IP string is invalid.
96 @retval EFI_SUCCESS The IP is parsed into the Ip
112 for (Index
= 0; Index
< 4; Index
++) {
113 if (!NET_IS_DIGIT (*Str
)) {
114 return EFI_INVALID_PARAMETER
;
117 Byte
= NetStringToU32 (Str
);
120 return EFI_INVALID_PARAMETER
;
123 Addr
= (Addr
<< 8) | Byte
;
126 // Skip all the digitals and check whether the separator is the dot
128 while (NET_IS_DIGIT (*Str
)) {
132 if ((Index
< 3) && (*Str
!= '.')) {
133 return EFI_INVALID_PARAMETER
;
145 Go through the packet to fill the Options array with the start
146 addresses of each MTFTP option name/value pair.
148 @param Packet The packet to check
149 @param PacketLen The packet's length
150 @param Count The size of the Options on input. The actual
152 @param Options The option array to fill in
154 @retval EFI_INVALID_PARAMETER The packet is malformatted
155 @retval EFI_BUFFER_TOO_SMALL The Options array is too small
156 @retval EFI_SUCCESS The packet has been parsed into the Options array.
161 IN EFI_MTFTP4_PACKET
*Packet
,
163 IN OUT UINT32
*Count
,
164 OUT EFI_MTFTP4_OPTION
*Options OPTIONAL
174 Cur
= (UINT8
*)Packet
+ MTFTP4_OPCODE_LEN
;
175 Last
= (UINT8
*)Packet
+ PacketLen
- 1;
178 // process option name and value pairs. The last byte is always zero
188 return EFI_INVALID_PARAMETER
;
199 if ((Options
!= NULL
) && (Num
<= *Count
)) {
200 Options
[Num
- 1].OptionStr
= Name
;
201 Options
[Num
- 1].ValueStr
= Value
;
207 if ((*Count
< Num
) || (Options
== NULL
)) {
209 return EFI_BUFFER_TOO_SMALL
;
217 Allocate and fill in a array of Mtftp options from the Packet.
219 It first calls Mtftp4FillOption to get the option number, then allocate
220 the array, at last, call Mtftp4FillOption again to save the options.
222 @param Packet The packet to parse
223 @param PacketLen The length of the packet
224 @param OptionCount The number of options in the packet
225 @param OptionList The point to get the option array.
227 @retval EFI_INVALID_PARAMETER The parametera are invalid or packet isn't a
228 well-formatted OACK packet.
229 @retval EFI_SUCCESS The option array is build
230 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the array
234 Mtftp4ExtractOptions (
235 IN EFI_MTFTP4_PACKET
*Packet
,
237 OUT UINT32
*OptionCount
,
238 OUT EFI_MTFTP4_OPTION
**OptionList OPTIONAL
245 if (OptionList
!= NULL
) {
249 if (NTOHS (Packet
->OpCode
) != EFI_MTFTP4_OPCODE_OACK
) {
250 return EFI_INVALID_PARAMETER
;
253 if (PacketLen
== MTFTP4_OPCODE_LEN
) {
258 // The last byte must be zero to terminate the options
260 if (*((UINT8
*)Packet
+ PacketLen
- 1) != 0) {
261 return EFI_INVALID_PARAMETER
;
265 // Get the number of options
267 Status
= Mtftp4FillOptions (Packet
, PacketLen
, OptionCount
, NULL
);
269 if ((Status
== EFI_SUCCESS
) || (Status
!= EFI_BUFFER_TOO_SMALL
)) {
274 // Allocate memory for the options, then call Mtftp4FillOptions to
275 // fill it if caller want that.
277 if (OptionList
== NULL
) {
281 *OptionList
= AllocatePool (*OptionCount
* sizeof (EFI_MTFTP4_OPTION
));
283 if (*OptionList
== NULL
) {
284 return EFI_OUT_OF_RESOURCES
;
287 Mtftp4FillOptions (Packet
, PacketLen
, OptionCount
, *OptionList
);
292 Parse the MTFTP multicast option.
294 @param Value The Mtftp multicast value string
295 @param Option The option to save the info into.
297 @retval EFI_INVALID_PARAMETER The multicast value string is invalid.
298 @retval EFI_SUCCESS The multicast value is parsed into the Option
304 IN OUT MTFTP4_OPTION
*Option
311 // The multicast option is formatted like "204.0.0.1,1857,1"
312 // The server can also omit the ip and port, use ",,1"
317 Status
= NetStringToIp (Value
, &Option
->McastIp
);
319 if (EFI_ERROR (Status
)) {
323 while ((*Value
!= 0) && (*Value
!= ',')) {
329 return EFI_INVALID_PARAMETER
;
335 // Convert the port setting. the server can send us a port number or
336 // empty string. such as the port in ",,1"
339 Option
->McastPort
= 0;
341 Num
= NetStringToU32 (Value
);
344 return EFI_INVALID_PARAMETER
;
347 Option
->McastPort
= (UINT16
)Num
;
349 while (NET_IS_DIGIT (*Value
)) {
355 return EFI_INVALID_PARAMETER
;
361 // Check the master/slave setting, 1 for master, 0 for slave.
363 Num
= NetStringToU32 (Value
);
365 if ((Num
!= 0) && (Num
!= 1)) {
366 return EFI_INVALID_PARAMETER
;
369 Option
->Master
= (BOOLEAN
)(Num
== 1);
371 while (NET_IS_DIGIT (*Value
)) {
375 if (*Value
!= '\0') {
376 return EFI_INVALID_PARAMETER
;
383 Parse the option in Options array to MTFTP4_OPTION which program
386 @param Options The option array, which contains addresses of each
387 option's name/value string.
388 @param Count The number of options in the Options
389 @param Request Whether this is a request or OACK. The format of
390 multicast is different according to this setting.
391 @param Operation The current performed operation.
392 @param MtftpOption The MTFTP4_OPTION for easy access.
394 @retval EFI_INVALID_PARAMETER The option is malformatted
395 @retval EFI_UNSUPPORTED Some option isn't supported
396 @retval EFI_SUCCESS The option are OK and has been parsed.
401 IN EFI_MTFTP4_OPTION
*Options
,
405 OUT MTFTP4_OPTION
*MtftpOption
411 EFI_MTFTP4_OPTION
*This
;
413 MtftpOption
->Exist
= 0;
415 for (Index
= 0; Index
< Count
; Index
++) {
416 This
= Options
+ Index
;
418 if ((This
->OptionStr
== NULL
) || (This
->ValueStr
== NULL
)) {
419 return EFI_INVALID_PARAMETER
;
422 if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*)"blksize")) {
424 // block size option, valid value is between [8, 65464]
426 Value
= NetStringToU32 (This
->ValueStr
);
428 if ((Value
< 8) || (Value
> 65464)) {
429 return EFI_INVALID_PARAMETER
;
432 MtftpOption
->BlkSize
= (UINT16
)Value
;
433 MtftpOption
->Exist
|= MTFTP4_BLKSIZE_EXIST
;
434 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*)"timeout")) {
436 // timeout option, valid value is between [1, 255]
438 Value
= NetStringToU32 (This
->ValueStr
);
440 if ((Value
< 1) || (Value
> 255)) {
441 return EFI_INVALID_PARAMETER
;
444 MtftpOption
->Timeout
= (UINT8
)Value
;
445 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*)"tsize")) {
447 // tsize option, the biggest transfer supported is 4GB with block size option
449 MtftpOption
->Tsize
= NetStringToU32 (This
->ValueStr
);
450 MtftpOption
->Exist
|= MTFTP4_TSIZE_EXIST
;
451 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*)"multicast")) {
453 // Multicast option, if it is a request, the value must be a zero
454 // length string, otherwise, it is formatted like "204.0.0.1,1857,1\0"
457 if (*(This
->ValueStr
) != '\0') {
458 return EFI_INVALID_PARAMETER
;
461 Status
= Mtftp4ExtractMcast (This
->ValueStr
, MtftpOption
);
463 if (EFI_ERROR (Status
)) {
468 MtftpOption
->Exist
|= MTFTP4_MCAST_EXIST
;
469 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*)"windowsize")) {
470 if (Operation
== EFI_MTFTP4_OPCODE_WRQ
) {
472 // Currently, windowsize is not supported in the write operation.
474 return EFI_UNSUPPORTED
;
477 Value
= NetStringToU32 (This
->ValueStr
);
480 return EFI_INVALID_PARAMETER
;
483 MtftpOption
->WindowSize
= (UINT16
)Value
;
484 MtftpOption
->Exist
|= MTFTP4_WINDOWSIZE_EXIST
;
485 } else if (Request
) {
487 // Ignore the unsupported option if it is a reply, and return
488 // EFI_UNSUPPORTED if it's a request according to the UEFI spec.
490 return EFI_UNSUPPORTED
;
498 Parse the options in the OACK packet to MTFTP4_OPTION which program
501 @param Packet The OACK packet to parse
502 @param PacketLen The length of the packet
503 @param Operation The current performed operation.
504 @param MtftpOption The MTFTP_OPTION for easy access.
506 @retval EFI_INVALID_PARAMETER The packet option is malformatted
507 @retval EFI_UNSUPPORTED Some option isn't supported
508 @retval EFI_SUCCESS The option are OK and has been parsed.
512 Mtftp4ParseOptionOack (
513 IN EFI_MTFTP4_PACKET
*Packet
,
516 OUT MTFTP4_OPTION
*MtftpOption
519 EFI_MTFTP4_OPTION
*OptionList
;
523 MtftpOption
->Exist
= 0;
525 Status
= Mtftp4ExtractOptions (Packet
, PacketLen
, &Count
, &OptionList
);
527 if (EFI_ERROR (Status
) || (Count
== 0)) {
531 ASSERT (OptionList
!= NULL
);
533 Status
= Mtftp4ParseOption (OptionList
, Count
, FALSE
, Operation
, MtftpOption
);
535 FreePool (OptionList
);