]>
git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c
2 Routines to process MTFTP4 options.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php<BR>
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "Mtftp4Impl.h"
17 CHAR8
*mMtftp4SupportedOptions
[MTFTP4_SUPPORTED_OPTIONS
] = {
27 Check whether two ascii strings are equel, ignore the case.
29 @param Str1 The first ascii string
30 @param Str2 The second ascii string
32 @retval TRUE Two strings are equal when case is ignored.
33 @retval FALSE Two string are not equal.
37 NetStringEqualNoCase (
45 ASSERT ((Str1
!= NULL
) && (Str2
!= NULL
));
47 for (; (*Str1
!= '\0') && (*Str2
!= '\0'); Str1
++, Str2
++) {
52 // Convert them to lower case then compare two
54 if (('A' <= Ch1
) && (Ch1
<= 'Z')) {
58 if (('A' <= Ch2
) && (Ch2
<= 'Z')) {
67 return (BOOLEAN
) (*Str1
== *Str2
);
72 Convert a string to a UINT32 number.
74 @param Str The string to convert from
76 @return The number get from the string
90 for (; NET_IS_DIGIT (*Str
); Str
++) {
91 Num
= Num
* 10 + (*Str
- '0');
99 Convert a string of the format "192.168.0.1" to an IP address.
101 @param Str The string representation of IP
102 @param Ip The varible to get IP.
104 @retval EFI_INVALID_PARAMETER The IP string is invalid.
105 @retval EFI_SUCCESS The IP is parsed into the Ip
121 for (Index
= 0; Index
< 4; Index
++) {
122 if (!NET_IS_DIGIT (*Str
)) {
123 return EFI_INVALID_PARAMETER
;
126 Byte
= NetStringToU32 (Str
);
129 return EFI_INVALID_PARAMETER
;
132 Addr
= (Addr
<< 8) | Byte
;
135 // Skip all the digitals and check whether the sepeator is the dot
137 while (NET_IS_DIGIT (*Str
)) {
141 if ((Index
< 3) && (*Str
!= '.')) {
142 return EFI_INVALID_PARAMETER
;
155 Go through the packet to fill the Options array with the start
156 addresses of each MTFTP option name/value pair.
158 @param Packet The packet to check
159 @param PacketLen The packet's length
160 @param Count The size of the Options on input. The actual
162 @param Options The option array to fill in
164 @retval EFI_INVALID_PARAMETER The packet is mal-formated
165 @retval EFI_BUFFER_TOO_SMALL The Options array is too small
166 @retval EFI_SUCCESS The packet has been parsed into the Options array.
171 IN EFI_MTFTP4_PACKET
*Packet
,
173 IN OUT UINT32
*Count
,
174 OUT EFI_MTFTP4_OPTION
*Options OPTIONAL
184 Cur
= (UINT8
*) Packet
+ MTFTP4_OPCODE_LEN
;
185 Last
= (UINT8
*) Packet
+ PacketLen
- 1;
188 // process option name and value pairs. The last byte is always zero
198 return EFI_INVALID_PARAMETER
;
209 if ((Options
!= NULL
) && (Num
<= *Count
)) {
210 Options
[Num
- 1].OptionStr
= Name
;
211 Options
[Num
- 1].ValueStr
= Value
;
217 if ((*Count
< Num
) || (Options
== NULL
)) {
219 return EFI_BUFFER_TOO_SMALL
;
228 Allocate and fill in a array of Mtftp options from the Packet.
230 It first calls Mtftp4FillOption to get the option number, then allocate
231 the array, at last, call Mtftp4FillOption again to save the options.
233 @param Packet The packet to parse
234 @param PacketLen The length of the packet
235 @param OptionCount The number of options in the packet
236 @param OptionList The point to get the option array.
238 @retval EFI_INVALID_PARAMETER The parametera are invalid or packet isn't a
239 well-formated OACK packet.
240 @retval EFI_SUCCESS The option array is build
241 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the array
245 Mtftp4ExtractOptions (
246 IN EFI_MTFTP4_PACKET
*Packet
,
248 OUT UINT32
*OptionCount
,
249 OUT EFI_MTFTP4_OPTION
**OptionList OPTIONAL
256 if (OptionList
!= NULL
) {
260 if (NTOHS (Packet
->OpCode
) != EFI_MTFTP4_OPCODE_OACK
) {
261 return EFI_INVALID_PARAMETER
;
264 if (PacketLen
== MTFTP4_OPCODE_LEN
) {
269 // The last byte must be zero to terminate the options
271 if (*((UINT8
*) Packet
+ PacketLen
- 1) != 0) {
272 return EFI_INVALID_PARAMETER
;
276 // Get the number of options
278 Status
= Mtftp4FillOptions (Packet
, PacketLen
, OptionCount
, NULL
);
280 if ((Status
== EFI_SUCCESS
) || (Status
!= EFI_BUFFER_TOO_SMALL
)) {
285 // Allocate memory for the options, then call Mtftp4FillOptions to
286 // fill it if caller want that.
288 if (OptionList
== NULL
) {
292 *OptionList
= AllocatePool (*OptionCount
* sizeof (EFI_MTFTP4_OPTION
));
294 if (*OptionList
== NULL
) {
295 return EFI_OUT_OF_RESOURCES
;
298 Mtftp4FillOptions (Packet
, PacketLen
, OptionCount
, *OptionList
);
304 Parse the MTFTP multicast option.
306 @param Value The Mtftp multicast value string
307 @param Option The option to save the info into.
309 @retval EFI_INVALID_PARAMETER The multicast value string is invalid.
310 @retval EFI_SUCCESS The multicast value is parsed into the Option
316 IN OUT MTFTP4_OPTION
*Option
323 // The multicast option is formated like "204.0.0.1,1857,1"
324 // The server can also omit the ip and port, use ",,1"
329 Status
= NetStringToIp (Value
, &Option
->McastIp
);
331 if (EFI_ERROR (Status
)) {
335 while ((*Value
!= 0) && (*Value
!= ',')) {
341 return EFI_INVALID_PARAMETER
;
347 // Convert the port setting. the server can send us a port number or
348 // empty string. such as the port in ",,1"
351 Option
->McastPort
= 0;
353 Num
= NetStringToU32 (Value
);
356 return EFI_INVALID_PARAMETER
;
359 Option
->McastPort
= (UINT16
) Num
;
361 while (NET_IS_DIGIT (*Value
)) {
367 return EFI_INVALID_PARAMETER
;
373 // Check the master/slave setting, 1 for master, 0 for slave.
375 Num
= NetStringToU32 (Value
);
377 if ((Num
!= 0) && (Num
!= 1)) {
378 return EFI_INVALID_PARAMETER
;
381 Option
->Master
= (BOOLEAN
) (Num
== 1);
383 while (NET_IS_DIGIT (*Value
)) {
387 if (*Value
!= '\0') {
388 return EFI_INVALID_PARAMETER
;
396 Parse the option in Options array to MTFTP4_OPTION which program
399 @param Options The option array, which contains addresses of each
400 option's name/value string.
401 @param Count The number of options in the Options
402 @param Request Whether this is a request or OACK. The format of
403 multicast is different according to this setting.
404 @param Operation The current performed operation.
405 @param MtftpOption The MTFTP4_OPTION for easy access.
407 @retval EFI_INVALID_PARAMETER The option is mal-formated
408 @retval EFI_UNSUPPORTED Some option isn't supported
409 @retval EFI_SUCCESS The option are OK and has been parsed.
414 IN EFI_MTFTP4_OPTION
*Options
,
418 OUT MTFTP4_OPTION
*MtftpOption
424 EFI_MTFTP4_OPTION
*This
;
426 MtftpOption
->Exist
= 0;
428 for (Index
= 0; Index
< Count
; Index
++) {
429 This
= Options
+ Index
;
431 if ((This
->OptionStr
== NULL
) || (This
->ValueStr
== NULL
)) {
432 return EFI_INVALID_PARAMETER
;
435 if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "blksize")) {
437 // block size option, valid value is between [8, 65464]
439 Value
= NetStringToU32 (This
->ValueStr
);
441 if ((Value
< 8) || (Value
> 65464)) {
442 return EFI_INVALID_PARAMETER
;
445 MtftpOption
->BlkSize
= (UINT16
) Value
;
446 MtftpOption
->Exist
|= MTFTP4_BLKSIZE_EXIST
;
448 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "timeout")) {
450 // timeout option, valid value is between [1, 255]
452 Value
= NetStringToU32 (This
->ValueStr
);
454 if ((Value
< 1) || (Value
> 255)) {
455 return EFI_INVALID_PARAMETER
;
458 MtftpOption
->Timeout
= (UINT8
) Value
;
460 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "tsize")) {
462 // tsize option, the biggest transfer supported is 4GB with block size option
464 MtftpOption
->Tsize
= NetStringToU32 (This
->ValueStr
);
465 MtftpOption
->Exist
|= MTFTP4_TSIZE_EXIST
;
467 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "multicast")) {
469 // Multicast option, if it is a request, the value must be a zero
470 // length string, otherwise, it is formated like "204.0.0.1,1857,1\0"
473 if (*(This
->ValueStr
) != '\0') {
474 return EFI_INVALID_PARAMETER
;
478 Status
= Mtftp4ExtractMcast (This
->ValueStr
, MtftpOption
);
480 if (EFI_ERROR (Status
)) {
485 MtftpOption
->Exist
|= MTFTP4_MCAST_EXIST
;
487 } else if (NetStringEqualNoCase (This
->OptionStr
, (UINT8
*) "windowsize")) {
488 if (Operation
== EFI_MTFTP4_OPCODE_WRQ
) {
490 // Currently, windowsize is not supported in the write operation.
492 return EFI_UNSUPPORTED
;
495 Value
= NetStringToU32 (This
->ValueStr
);
498 return EFI_INVALID_PARAMETER
;
501 MtftpOption
->WindowSize
= (UINT16
) Value
;
502 MtftpOption
->Exist
|= MTFTP4_WINDOWSIZE_EXIST
;
503 } else if (Request
) {
505 // Ignore the unsupported option if it is a reply, and return
506 // EFI_UNSUPPORTED if it's a request according to the UEFI spec.
508 return EFI_UNSUPPORTED
;
517 Parse the options in the OACK packet to MTFTP4_OPTION which program
520 @param Packet The OACK packet to parse
521 @param PacketLen The length of the packet
522 @param Operation The current performed operation.
523 @param MtftpOption The MTFTP_OPTION for easy access.
525 @retval EFI_INVALID_PARAMETER The packet option is mal-formated
526 @retval EFI_UNSUPPORTED Some option isn't supported
527 @retval EFI_SUCCESS The option are OK and has been parsed.
531 Mtftp4ParseOptionOack (
532 IN EFI_MTFTP4_PACKET
*Packet
,
535 OUT MTFTP4_OPTION
*MtftpOption
538 EFI_MTFTP4_OPTION
*OptionList
;
542 MtftpOption
->Exist
= 0;
544 Status
= Mtftp4ExtractOptions (Packet
, PacketLen
, &Count
, &OptionList
);
546 if (EFI_ERROR (Status
) || (Count
== 0)) {
549 ASSERT (OptionList
!= NULL
);
551 Status
= Mtftp4ParseOption (OptionList
, Count
, FALSE
, Operation
, MtftpOption
);
553 FreePool (OptionList
);