]>
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
] = {
21 Check whether two ascii strings are equal, ignore the case.
23 @param Str1 The first ascii string
24 @param Str2 The second ascii string
26 @retval TRUE Two strings are equal when case is ignored.
27 @retval FALSE Two strings are not equal.
31 NetStringEqualNoCase (
39 ASSERT ((Str1
!= NULL
) && (Str2
!= NULL
));
41 for (; (*Str1
!= '\0') && (*Str2
!= '\0'); Str1
++, Str2
++) {
46 // Convert them to lower case then compare two
48 if (('A' <= Ch1
) && (Ch1
<= 'Z')) {
52 if (('A' <= Ch2
) && (Ch2
<= 'Z')) {
61 return (BOOLEAN
) (*Str1
== *Str2
);
66 Convert a string to a UINT32 number.
68 @param Str The string to convert from
70 @return The number get from the string
84 for (; NET_IS_DIGIT (*Str
); Str
++) {
85 Num
= Num
* 10 + (*Str
- '0');
93 Convert a string of the format "192.168.0.1" to an IP address.
95 @param Str The string representation of IP
96 @param Ip The variable to get IP.
98 @retval EFI_INVALID_PARAMETER The IP string is invalid.
99 @retval EFI_SUCCESS The IP is parsed into the Ip
115 for (Index
= 0; Index
< 4; Index
++) {
116 if (!NET_IS_DIGIT (*Str
)) {
117 return EFI_INVALID_PARAMETER
;
120 Byte
= NetStringToU32 (Str
);
123 return EFI_INVALID_PARAMETER
;
126 Addr
= (Addr
<< 8) | Byte
;
129 // Skip all the digitals and check whether the separator is the dot
131 while (NET_IS_DIGIT (*Str
)) {
135 if ((Index
< 3) && (*Str
!= '.')) {
136 return EFI_INVALID_PARAMETER
;
149 Go through the packet to fill the Options array with the start
150 addresses of each MTFTP option name/value pair.
152 @param Packet The packet to check
153 @param PacketLen The packet's length
154 @param Count The size of the Options on input. The actual
156 @param Options The option array to fill in
158 @retval EFI_INVALID_PARAMETER The packet is malformatted
159 @retval EFI_BUFFER_TOO_SMALL The Options array is too small
160 @retval EFI_SUCCESS The packet has been parsed into the Options array.
165 IN EFI_MTFTP4_PACKET
*Packet
,
167 IN OUT UINT32
*Count
,
168 OUT EFI_MTFTP4_OPTION
*Options OPTIONAL
178 Cur
= (UINT8
*) Packet
+ MTFTP4_OPCODE_LEN
;
179 Last
= (UINT8
*) Packet
+ PacketLen
- 1;
182 // process option name and value pairs. The last byte is always zero
192 return EFI_INVALID_PARAMETER
;
203 if ((Options
!= NULL
) && (Num
<= *Count
)) {
204 Options
[Num
- 1].OptionStr
= Name
;
205 Options
[Num
- 1].ValueStr
= Value
;
211 if ((*Count
< Num
) || (Options
== NULL
)) {
213 return EFI_BUFFER_TOO_SMALL
;
222 Allocate and fill in a array of Mtftp options from the Packet.
224 It first calls Mtftp4FillOption to get the option number, then allocate
225 the array, at last, call Mtftp4FillOption again to save the options.
227 @param Packet The packet to parse
228 @param PacketLen The length of the packet
229 @param OptionCount The number of options in the packet
230 @param OptionList The point to get the option array.
232 @retval EFI_INVALID_PARAMETER The parametera are invalid or packet isn't a
233 well-formatted OACK packet.
234 @retval EFI_SUCCESS The option array is build
235 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the array
239 Mtftp4ExtractOptions (
240 IN EFI_MTFTP4_PACKET
*Packet
,
242 OUT UINT32
*OptionCount
,
243 OUT EFI_MTFTP4_OPTION
**OptionList OPTIONAL
250 if (OptionList
!= NULL
) {
254 if (NTOHS (Packet
->OpCode
) != EFI_MTFTP4_OPCODE_OACK
) {
255 return EFI_INVALID_PARAMETER
;
258 if (PacketLen
== MTFTP4_OPCODE_LEN
) {
263 // The last byte must be zero to terminate the options
265 if (*((UINT8
*) Packet
+ PacketLen
- 1) != 0) {
266 return EFI_INVALID_PARAMETER
;
270 // Get the number of options
272 Status
= Mtftp4FillOptions (Packet
, PacketLen
, OptionCount
, NULL
);
274 if ((Status
== EFI_SUCCESS
) || (Status
!= EFI_BUFFER_TOO_SMALL
)) {
279 // Allocate memory for the options, then call Mtftp4FillOptions to
280 // fill it if caller want that.
282 if (OptionList
== NULL
) {
286 *OptionList
= AllocatePool (*OptionCount
* sizeof (EFI_MTFTP4_OPTION
));
288 if (*OptionList
== NULL
) {
289 return EFI_OUT_OF_RESOURCES
;
292 Mtftp4FillOptions (Packet
, PacketLen
, OptionCount
, *OptionList
);
298 Parse the MTFTP multicast option.
300 @param Value The Mtftp multicast value string
301 @param Option The option to save the info into.
303 @retval EFI_INVALID_PARAMETER The multicast value string is invalid.
304 @retval EFI_SUCCESS The multicast value is parsed into the Option
310 IN OUT MTFTP4_OPTION
*Option
317 // The multicast option is formatted like "204.0.0.1,1857,1"
318 // The server can also omit the ip and port, use ",,1"
323 Status
= NetStringToIp (Value
, &Option
->McastIp
);
325 if (EFI_ERROR (Status
)) {
329 while ((*Value
!= 0) && (*Value
!= ',')) {
335 return EFI_INVALID_PARAMETER
;
341 // Convert the port setting. the server can send us a port number or
342 // empty string. such as the port in ",,1"
345 Option
->McastPort
= 0;
347 Num
= NetStringToU32 (Value
);
350 return EFI_INVALID_PARAMETER
;
353 Option
->McastPort
= (UINT16
) Num
;
355 while (NET_IS_DIGIT (*Value
)) {
361 return EFI_INVALID_PARAMETER
;
367 // Check the master/slave setting, 1 for master, 0 for slave.
369 Num
= NetStringToU32 (Value
);
371 if ((Num
!= 0) && (Num
!= 1)) {
372 return EFI_INVALID_PARAMETER
;
375 Option
->Master
= (BOOLEAN
) (Num
== 1);
377 while (NET_IS_DIGIT (*Value
)) {
381 if (*Value
!= '\0') {
382 return EFI_INVALID_PARAMETER
;
390 Parse the option in Options array to MTFTP4_OPTION which program
393 @param Options The option array, which contains addresses of each
394 option's name/value string.
395 @param Count The number of options in the Options
396 @param Request Whether this is a request or OACK. The format of
397 multicast is different according to this setting.
398 @param Operation The current performed operation.
399 @param MtftpOption The MTFTP4_OPTION for easy access.
401 @retval EFI_INVALID_PARAMETER The option is malformatted
402 @retval EFI_UNSUPPORTED Some option isn't supported
403 @retval EFI_SUCCESS The option are OK and has been parsed.
408 IN EFI_MTFTP4_OPTION
*Options
,
412 OUT MTFTP4_OPTION
*MtftpOption
418 EFI_MTFTP4_OPTION
*This
;
420 MtftpOption
->Exist
= 0;
422 for (Index
= 0; Index
< Count
; Index
++) {
423 This
= Options
+ Index
;
425 if ((This
->OptionStr
== NULL
) || (This
->ValueStr
== NULL
)) {
426 return EFI_INVALID_PARAMETER
;
429 if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "blksize")) {
431 // block size option, valid value is between [8, 65464]
433 Value
= NetStringToU32 (This
->ValueStr
);
435 if ((Value
< 8) || (Value
> 65464)) {
436 return EFI_INVALID_PARAMETER
;
439 MtftpOption
->BlkSize
= (UINT16
) Value
;
440 MtftpOption
->Exist
|= MTFTP4_BLKSIZE_EXIST
;
442 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "timeout")) {
444 // timeout option, valid value is between [1, 255]
446 Value
= NetStringToU32 (This
->ValueStr
);
448 if ((Value
< 1) || (Value
> 255)) {
449 return EFI_INVALID_PARAMETER
;
452 MtftpOption
->Timeout
= (UINT8
) Value
;
454 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "tsize")) {
456 // tsize option, the biggest transfer supported is 4GB with block size option
458 MtftpOption
->Tsize
= NetStringToU32 (This
->ValueStr
);
459 MtftpOption
->Exist
|= MTFTP4_TSIZE_EXIST
;
461 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "multicast")) {
463 // Multicast option, if it is a request, the value must be a zero
464 // length string, otherwise, it is formatted like "204.0.0.1,1857,1\0"
467 if (*(This
->ValueStr
) != '\0') {
468 return EFI_INVALID_PARAMETER
;
472 Status
= Mtftp4ExtractMcast (This
->ValueStr
, MtftpOption
);
474 if (EFI_ERROR (Status
)) {
479 MtftpOption
->Exist
|= MTFTP4_MCAST_EXIST
;
481 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "windowsize")) {
482 if (Operation
== EFI_MTFTP4_OPCODE_WRQ
) {
484 // Currently, windowsize is not supported in the write operation.
486 return EFI_UNSUPPORTED
;
489 Value
= NetStringToU32 (This
->ValueStr
);
492 return EFI_INVALID_PARAMETER
;
495 MtftpOption
->WindowSize
= (UINT16
) Value
;
496 MtftpOption
->Exist
|= MTFTP4_WINDOWSIZE_EXIST
;
497 } else if (Request
) {
499 // Ignore the unsupported option if it is a reply, and return
500 // EFI_UNSUPPORTED if it's a request according to the UEFI spec.
502 return EFI_UNSUPPORTED
;
511 Parse the options in the OACK packet to MTFTP4_OPTION which program
514 @param Packet The OACK packet to parse
515 @param PacketLen The length of the packet
516 @param Operation The current performed operation.
517 @param MtftpOption The MTFTP_OPTION for easy access.
519 @retval EFI_INVALID_PARAMETER The packet option is malformatted
520 @retval EFI_UNSUPPORTED Some option isn't supported
521 @retval EFI_SUCCESS The option are OK and has been parsed.
525 Mtftp4ParseOptionOack (
526 IN EFI_MTFTP4_PACKET
*Packet
,
529 OUT MTFTP4_OPTION
*MtftpOption
532 EFI_MTFTP4_OPTION
*OptionList
;
536 MtftpOption
->Exist
= 0;
538 Status
= Mtftp4ExtractOptions (Packet
, PacketLen
, &Count
, &OptionList
);
540 if (EFI_ERROR (Status
) || (Count
== 0)) {
543 ASSERT (OptionList
!= NULL
);
545 Status
= Mtftp4ParseOption (OptionList
, Count
, FALSE
, Operation
, MtftpOption
);
547 FreePool (OptionList
);