]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c
Removed unused library instances for Option ROM package DSC files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Option.c
CommitLineData
772db4bb 1/** @file\r
dab714aa 2 Routines to process MTFTP4 options.\r
3 \r
4Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
772db4bb 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
dab714aa 8http://opensource.org/licenses/bsd-license.php<BR>\r
772db4bb 9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
772db4bb 13**/\r
14\r
15#include "Mtftp4Impl.h"\r
16\r
67a58d0f 17CHAR8 *mMtftp4SupportedOptions[MTFTP4_SUPPORTED_OPTIONS] = {\r
772db4bb 18 "blksize",\r
19 "timeout",\r
20 "tsize",\r
21 "multicast"\r
22};\r
23\r
24\r
25/**\r
26 Go through the packet to fill the Options array with the start\r
27 addresses of each MTFTP option name/value pair.\r
28\r
29 @param Packet The packet to check\r
30 @param PacketLen The packet's length\r
31 @param Count The size of the Options on input. The actual\r
32 options on output\r
33 @param Options The option array to fill in\r
34\r
35 @retval EFI_INVALID_PARAMETER The packet is mal-formated\r
36 @retval EFI_BUFFER_TOO_SMALL The Options array is too small\r
37 @retval EFI_SUCCESS The packet has been parsed into the Options array.\r
38\r
39**/\r
772db4bb 40EFI_STATUS\r
41Mtftp4FillOptions (\r
dab714aa 42 IN EFI_MTFTP4_PACKET *Packet,\r
43 IN UINT32 PacketLen,\r
44 IN OUT UINT32 *Count,\r
45 OUT EFI_MTFTP4_OPTION *Options OPTIONAL\r
772db4bb 46 )\r
47{\r
48 UINT8 *Cur;\r
49 UINT8 *Last;\r
50 UINT8 Num;\r
51 UINT8 *Name;\r
52 UINT8 *Value;\r
53\r
54 Num = 0;\r
55 Cur = (UINT8 *) Packet + MTFTP4_OPCODE_LEN;\r
56 Last = (UINT8 *) Packet + PacketLen - 1;\r
57\r
58 //\r
59 // process option name and value pairs. The last byte is always zero\r
60 //\r
61 while (Cur < Last) {\r
62 Name = Cur;\r
63\r
64 while (*Cur != 0) {\r
65 Cur++;\r
66 }\r
67\r
68 if (Cur == Last) {\r
69 return EFI_INVALID_PARAMETER;\r
70 }\r
71\r
72 Value = ++Cur;\r
73\r
74 while (*Cur != 0) {\r
75 Cur++;\r
76 }\r
77\r
78 Num++;\r
79\r
80 if ((Options != NULL) && (Num <= *Count)) {\r
81 Options[Num - 1].OptionStr = Name;\r
82 Options[Num - 1].ValueStr = Value;\r
83 }\r
84\r
85 Cur++;\r
86 }\r
87\r
88 if ((*Count < Num) || (Options == NULL)) {\r
89 *Count = Num;\r
90 return EFI_BUFFER_TOO_SMALL;\r
91 }\r
92\r
93 *Count = Num;\r
94 return EFI_SUCCESS;\r
95}\r
96\r
97\r
98/**\r
dab714aa 99 Allocate and fill in a array of Mtftp options from the Packet. \r
100 \r
101 It first calls Mtftp4FillOption to get the option number, then allocate\r
772db4bb 102 the array, at last, call Mtftp4FillOption again to save the options.\r
103\r
104 @param Packet The packet to parse\r
105 @param PacketLen The length of the packet\r
106 @param OptionCount The number of options in the packet\r
107 @param OptionList The point to get the option array.\r
108\r
109 @retval EFI_INVALID_PARAMETER The parametera are invalid or packet isn't a\r
110 well-formated OACK packet.\r
111 @retval EFI_SUCCESS The option array is build\r
112 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the array\r
113\r
114**/\r
115EFI_STATUS\r
116Mtftp4ExtractOptions (\r
dab714aa 117 IN EFI_MTFTP4_PACKET *Packet,\r
118 IN UINT32 PacketLen,\r
119 OUT UINT32 *OptionCount,\r
120 OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL\r
772db4bb 121 )\r
122{\r
123 EFI_STATUS Status;\r
124\r
125 *OptionCount = 0;\r
126\r
127 if (OptionList != NULL) {\r
128 *OptionList = NULL;\r
129 }\r
130\r
131 if (NTOHS (Packet->OpCode) != EFI_MTFTP4_OPCODE_OACK) {\r
132 return EFI_INVALID_PARAMETER;\r
133 }\r
134\r
135 if (PacketLen == MTFTP4_OPCODE_LEN) {\r
136 return EFI_SUCCESS;\r
137 }\r
138\r
139 //\r
140 // The last byte must be zero to terminate the options\r
141 //\r
142 if (*((UINT8 *) Packet + PacketLen - 1) != 0) {\r
143 return EFI_INVALID_PARAMETER;\r
144 }\r
145\r
146 //\r
147 // Get the number of options\r
148 //\r
149 Status = Mtftp4FillOptions (Packet, PacketLen, OptionCount, NULL);\r
150\r
151 if ((Status == EFI_SUCCESS) || (Status != EFI_BUFFER_TOO_SMALL)) {\r
152 return Status;\r
153 }\r
154\r
155 //\r
156 // Allocate memory for the options, then call Mtftp4FillOptions to\r
157 // fill it if caller want that.\r
158 //\r
159 if (OptionList == NULL) {\r
160 return EFI_SUCCESS;\r
161 }\r
162\r
e48e37fc 163 *OptionList = AllocatePool (*OptionCount * sizeof (EFI_MTFTP4_OPTION));\r
772db4bb 164\r
165 if (*OptionList == NULL) {\r
166 return EFI_OUT_OF_RESOURCES;\r
167 }\r
168\r
169 Mtftp4FillOptions (Packet, PacketLen, OptionCount, *OptionList);\r
170 return EFI_SUCCESS;\r
171}\r
172\r
173\r
174/**\r
175 Check whether two ascii strings are equel, ignore the case.\r
176\r
177 @param Str1 The first ascii string\r
178 @param Str2 The second ascii string\r
179\r
180 @retval TRUE Two strings are equal when case is ignored.\r
181 @retval FALSE Two string are not equal.\r
182\r
183**/\r
184BOOLEAN\r
185NetStringEqualNoCase (\r
dab714aa 186 IN UINT8 *Str1,\r
187 IN UINT8 *Str2\r
772db4bb 188 )\r
189{\r
190 UINT8 Ch1;\r
191 UINT8 Ch2;\r
192\r
193 ASSERT ((Str1 != NULL) && (Str2 != NULL));\r
194\r
195 for (; (*Str1 != '\0') && (*Str2 != '\0'); Str1++, Str2++) {\r
196 Ch1 = *Str1;\r
197 Ch2 = *Str2;\r
198\r
199 //\r
200 // Convert them to lower case then compare two\r
201 //\r
202 if (('A' <= Ch1) && (Ch1 <= 'Z')) {\r
203 Ch1 += 'a' - 'A';\r
204 }\r
205\r
206 if (('A' <= Ch2) && (Ch2 <= 'Z')) {\r
207 Ch2 += 'a' - 'A';\r
208 }\r
209\r
210 if (Ch1 != Ch2) {\r
211 return FALSE;\r
212 }\r
213 }\r
214\r
215 return (BOOLEAN) (*Str1 == *Str2);\r
216}\r
217\r
218\r
219/**\r
220 Convert a string to a UINT32 number.\r
221\r
222 @param Str The string to convert from\r
223\r
224 @return The number get from the string\r
225\r
226**/\r
227UINT32\r
228NetStringToU32 (\r
dab714aa 229 IN UINT8 *Str\r
772db4bb 230 )\r
231{\r
232 UINT32 Num;\r
233\r
234 ASSERT (Str != NULL);\r
235\r
236 Num = 0;\r
237\r
238 for (; NET_IS_DIGIT (*Str); Str++) {\r
239 Num = Num * 10 + (*Str - '0');\r
240 }\r
241\r
242 return Num;\r
243}\r
244\r
245\r
246/**\r
247 Convert a string of the format "192.168.0.1" to an IP address.\r
248\r
249 @param Str The string representation of IP\r
250 @param Ip The varible to get IP.\r
251\r
252 @retval EFI_INVALID_PARAMETER The IP string is invalid.\r
253 @retval EFI_SUCCESS The IP is parsed into the Ip\r
254\r
255**/\r
772db4bb 256EFI_STATUS\r
257NetStringToIp (\r
dab714aa 258 IN UINT8 *Str,\r
259 OUT IP4_ADDR *Ip\r
772db4bb 260 )\r
261{\r
262 UINT32 Byte;\r
263 UINT32 Addr;\r
264 UINTN Index;\r
265\r
266 *Ip = 0;\r
267 Addr = 0;\r
268\r
269 for (Index = 0; Index < 4; Index++) {\r
270 if (!NET_IS_DIGIT (*Str)) {\r
271 return EFI_INVALID_PARAMETER;\r
272 }\r
273\r
274 Byte = NetStringToU32 (Str);\r
275\r
276 if (Byte > 255) {\r
277 return EFI_INVALID_PARAMETER;\r
278 }\r
279\r
280 Addr = (Addr << 8) | Byte;\r
281\r
282 //\r
283 // Skip all the digitals and check whether the sepeator is the dot\r
284 //\r
285 while (NET_IS_DIGIT (*Str)) {\r
286 Str++;\r
287 }\r
288\r
289 if ((Index < 3) && (*Str != '.')) {\r
290 return EFI_INVALID_PARAMETER;\r
291 }\r
292\r
293 Str++;\r
294 }\r
295\r
296 *Ip = Addr;\r
297\r
298 return EFI_SUCCESS;\r
299}\r
300\r
301\r
302/**\r
303 Parse the MTFTP multicast option.\r
304\r
305 @param Value The Mtftp multicast value string\r
306 @param Option The option to save the info into.\r
307\r
308 @retval EFI_INVALID_PARAMETER The multicast value string is invalid.\r
309 @retval EFI_SUCCESS The multicast value is parsed into the Option\r
310\r
311**/\r
772db4bb 312EFI_STATUS\r
313Mtftp4ExtractMcast (\r
dab714aa 314 IN UINT8 *Value,\r
315 IN OUT MTFTP4_OPTION *Option\r
772db4bb 316 )\r
317{\r
318 EFI_STATUS Status;\r
319 UINT32 Num;\r
320\r
321 //\r
322 // The multicast option is formated like "204.0.0.1,1857,1"\r
323 // The server can also omit the ip and port, use ",,1"\r
324 //\r
325 if (*Value == ',') {\r
326 Option->McastIp = 0;\r
327 } else {\r
328 Status = NetStringToIp (Value, &Option->McastIp);\r
329\r
330 if (EFI_ERROR (Status)) {\r
331 return Status;\r
332 }\r
333\r
dab714aa 334 while ((*Value != 0) && (*Value != ',')) {\r
772db4bb 335 Value++;\r
336 }\r
337 }\r
338\r
339 if (*Value != ',') {\r
340 return EFI_INVALID_PARAMETER;\r
341 }\r
342\r
343 Value++;\r
344\r
345 //\r
346 // Convert the port setting. the server can send us a port number or\r
347 // empty string. such as the port in ",,1"\r
348 //\r
349 if (*Value == ',') {\r
350 Option->McastPort = 0;\r
351 } else {\r
352 Num = NetStringToU32 (Value);\r
353\r
354 if (Num > 65535) {\r
355 return EFI_INVALID_PARAMETER;\r
356 }\r
357\r
dab714aa 358 Option->McastPort = (UINT16) Num;\r
772db4bb 359\r
360 while (NET_IS_DIGIT (*Value)) {\r
361 Value++;\r
362 }\r
363 }\r
364\r
365 if (*Value != ',') {\r
366 return EFI_INVALID_PARAMETER;\r
367 }\r
368\r
369 Value++;\r
370\r
371 //\r
372 // Check the master/slave setting, 1 for master, 0 for slave.\r
373 //\r
374 Num = NetStringToU32 (Value);\r
375\r
376 if ((Num != 0) && (Num != 1)) {\r
377 return EFI_INVALID_PARAMETER;\r
378 }\r
379\r
dab714aa 380 Option->Master = (BOOLEAN) (Num == 1);\r
772db4bb 381\r
382 while (NET_IS_DIGIT (*Value)) {\r
383 Value++;\r
384 }\r
385\r
386 if (*Value != '\0') {\r
387 return EFI_INVALID_PARAMETER;\r
388 }\r
389\r
390 return EFI_SUCCESS;\r
391}\r
392\r
393\r
394/**\r
395 Parse the option in Options array to MTFTP4_OPTION which program\r
396 can access directly.\r
397\r
398 @param Options The option array, which contains addresses of each\r
dab714aa 399 option's name/value string.\r
772db4bb 400 @param Count The number of options in the Options\r
401 @param Request Whether this is a request or OACK. The format of\r
402 multicast is different according to this setting.\r
403 @param MtftpOption The MTFTP4_OPTION for easy access.\r
404\r
405 @retval EFI_INVALID_PARAMETER The option is mal-formated\r
406 @retval EFI_UNSUPPORTED Some option isn't supported\r
407 @retval EFI_SUCCESS The option are OK and has been parsed.\r
408\r
409**/\r
410EFI_STATUS\r
411Mtftp4ParseOption (\r
dab714aa 412 IN EFI_MTFTP4_OPTION *Options,\r
413 IN UINT32 Count,\r
414 IN BOOLEAN Request,\r
415 OUT MTFTP4_OPTION *MtftpOption\r
772db4bb 416 )\r
417{\r
418 EFI_STATUS Status;\r
419 UINT32 Index;\r
420 UINT32 Value;\r
421 EFI_MTFTP4_OPTION *This;\r
422\r
423 MtftpOption->Exist = 0;\r
424\r
425 for (Index = 0; Index < Count; Index++) {\r
426 This = Options + Index;\r
427\r
428 if ((This->OptionStr == NULL) || (This->ValueStr == NULL)) {\r
429 return EFI_INVALID_PARAMETER;\r
430 }\r
431\r
67a58d0f 432 if (NetStringEqualNoCase (This->OptionStr, (UINT8 *) "blksize")) {\r
772db4bb 433 //\r
434 // block size option, valid value is between [8, 65464]\r
435 //\r
436 Value = NetStringToU32 (This->ValueStr);\r
437\r
438 if ((Value < 8) || (Value > 65464)) {\r
439 return EFI_INVALID_PARAMETER;\r
440 }\r
441\r
442 MtftpOption->BlkSize = (UINT16) Value;\r
443 MtftpOption->Exist |= MTFTP4_BLKSIZE_EXIST;\r
444\r
67a58d0f 445 } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *) "timeout")) {\r
772db4bb 446 //\r
447 // timeout option, valid value is between [1, 255]\r
448 //\r
449 Value = NetStringToU32 (This->ValueStr);\r
450\r
451 if ((Value < 1) || (Value > 255)) {\r
452 return EFI_INVALID_PARAMETER;\r
453 }\r
454\r
455 MtftpOption->Timeout = (UINT8) Value;\r
456\r
67a58d0f 457 } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *) "tsize")) {\r
772db4bb 458 //\r
459 // tsize option, the biggest transfer supported is 4GB with block size option\r
460 //\r
461 MtftpOption->Tsize = NetStringToU32 (This->ValueStr);\r
462 MtftpOption->Exist |= MTFTP4_TSIZE_EXIST;\r
463\r
67a58d0f 464 } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *) "multicast")) {\r
772db4bb 465 //\r
466 // Multicast option, if it is a request, the value must be a zero\r
467 // length string, otherwise, it is formated like "204.0.0.1,1857,1\0"\r
468 //\r
469 if (Request) {\r
470 if (*(This->ValueStr) != '\0') {\r
471 return EFI_INVALID_PARAMETER;\r
472 }\r
473\r
474 } else {\r
475 Status = Mtftp4ExtractMcast (This->ValueStr, MtftpOption);\r
476\r
477 if (EFI_ERROR (Status)) {\r
478 return Status;\r
479 }\r
480 }\r
481\r
482 MtftpOption->Exist |= MTFTP4_MCAST_EXIST;\r
483\r
484 } else if (Request) {\r
485 //\r
486 // Ignore the unsupported option if it is a reply, and return\r
487 // EFI_UNSUPPORTED if it's a request according to the UEFI spec.\r
488 //\r
489 return EFI_UNSUPPORTED;\r
490 }\r
491 }\r
492\r
493 return EFI_SUCCESS;\r
494}\r
495\r
496\r
497/**\r
498 Parse the options in the OACK packet to MTFTP4_OPTION which program\r
499 can access directly.\r
500\r
501 @param Packet The OACK packet to parse\r
502 @param PacketLen The length of the packet\r
503 @param MtftpOption The MTFTP_OPTION for easy access.\r
504\r
505 @retval EFI_INVALID_PARAMETER The packet option is mal-formated\r
506 @retval EFI_UNSUPPORTED Some option isn't supported\r
507 @retval EFI_SUCCESS The option are OK and has been parsed.\r
508\r
509**/\r
510EFI_STATUS\r
511Mtftp4ParseOptionOack (\r
dab714aa 512 IN EFI_MTFTP4_PACKET *Packet,\r
513 IN UINT32 PacketLen,\r
514 OUT MTFTP4_OPTION *MtftpOption\r
772db4bb 515 )\r
516{\r
517 EFI_MTFTP4_OPTION *OptionList;\r
518 EFI_STATUS Status;\r
519 UINT32 Count;\r
520\r
521 MtftpOption->Exist = 0;\r
522\r
523 Status = Mtftp4ExtractOptions (Packet, PacketLen, &Count, &OptionList);\r
524\r
525 if (EFI_ERROR (Status) || (Count == 0)) {\r
526 return Status;\r
527 }\r
528\r
529 Status = Mtftp4ParseOption (OptionList, Count, FALSE, MtftpOption);\r
530\r
e48e37fc 531 gBS->FreePool (OptionList);\r
772db4bb 532 return Status;\r
533}\r