]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/Ip6Dxe/Ip6ConfigNv.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / Ip6Dxe / Ip6ConfigNv.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 Helper functions for configuring or obtaining the parameters relating to IP6.\r
3\r
f75a7f56 4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
a3bcde70 5\r
ecf98fbc 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a3bcde70
HT
7\r
8**/\r
9\r
10#include "Ip6Impl.h"\r
11\r
d1050b9d 12CHAR16 mIp6ConfigStorageName[] = L"IP6_CONFIG_IFR_NVDATA";\r
a3bcde70
HT
13\r
14/**\r
15 The notify function of create event when performing a manual configuration.\r
16\r
17 @param[in] Event The pointer of Event.\r
18 @param[in] Context The pointer of Context.\r
19\r
20**/\r
21VOID\r
22EFIAPI\r
23Ip6ConfigManualAddressNotify (\r
d1050b9d
MK
24 IN EFI_EVENT Event,\r
25 IN VOID *Context\r
a3bcde70
HT
26 )\r
27{\r
d1050b9d 28 *((BOOLEAN *)Context) = TRUE;\r
a3bcde70
HT
29}\r
30\r
31/**\r
32 Get the configuration data for the EFI IPv6 network stack running on the\r
33 communication. It is a help function to the call EfiIp6ConfigGetData().\r
34\r
35 @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.\r
36 @param[in] DataType The type of data to get.\r
37 @param[out] DataSize The size of buffer required in bytes.\r
38 @param[out] Data The data buffer in which the configuration data is returned. The\r
39 type of the data buffer associated with the DataType.\r
40 It is the caller's responsibility to free the resource.\r
41\r
42 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
43 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:\r
44 - Ip6Config is NULL or invalid.\r
45 - DataSize is NULL.\r
46 - Data is NULL.\r
47 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources.\r
48 @retval EFI_NOT_READY The specified configuration data is not ready due to an\r
49 asynchronous configuration process already in progress.\r
50 @retval EFI_NOT_FOUND The specified configuration data was not found.\r
51\r
52**/\r
53EFI_STATUS\r
54Ip6ConfigNvGetData (\r
d1050b9d
MK
55 IN EFI_IP6_CONFIG_PROTOCOL *Ip6Config,\r
56 IN EFI_IP6_CONFIG_DATA_TYPE DataType,\r
57 OUT UINTN *DataSize,\r
58 OUT VOID **Data\r
a3bcde70
HT
59 )\r
60{\r
d1050b9d
MK
61 UINTN BufferSize;\r
62 VOID *Buffer;\r
63 EFI_STATUS Status;\r
a3bcde70
HT
64\r
65 if ((Ip6Config == NULL) || (Data == NULL) || (DataSize == NULL)) {\r
66 return EFI_INVALID_PARAMETER;\r
67 }\r
68\r
69 BufferSize = 0;\r
d1050b9d
MK
70 Status = Ip6Config->GetData (\r
71 Ip6Config,\r
72 DataType,\r
73 &BufferSize,\r
74 NULL\r
75 );\r
a3bcde70
HT
76 if (Status != EFI_BUFFER_TOO_SMALL) {\r
77 return Status;\r
78 }\r
79\r
80 Buffer = AllocateZeroPool (BufferSize);\r
81 if (Buffer == NULL) {\r
82 return EFI_OUT_OF_RESOURCES;\r
83 }\r
84\r
85 Status = Ip6Config->GetData (\r
86 Ip6Config,\r
87 DataType,\r
88 &BufferSize,\r
89 Buffer\r
90 );\r
91 if (EFI_ERROR (Status)) {\r
92 FreePool (Buffer);\r
93 return Status;\r
94 }\r
95\r
96 *DataSize = BufferSize;\r
97 *Data = Buffer;\r
98\r
99 return EFI_SUCCESS;\r
100}\r
101\r
102/**\r
103 Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified\r
104 with ListHead.\r
105\r
106 @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY.\r
107\r
108**/\r
109VOID\r
110Ip6FreeAddressInfoList (\r
d1050b9d 111 IN LIST_ENTRY *ListHead\r
a3bcde70
HT
112 )\r
113{\r
d1050b9d
MK
114 IP6_ADDRESS_INFO_ENTRY *Node;\r
115 LIST_ENTRY *Entry;\r
116 LIST_ENTRY *NextEntry;\r
a3bcde70
HT
117\r
118 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ListHead) {\r
119 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);\r
120 RemoveEntryList (&Node->Link);\r
121 FreePool (Node);\r
122 }\r
123}\r
124\r
125/**\r
126 Convert the IPv6 address into a formatted string.\r
127\r
128 @param[in] Ip6 The IPv6 address.\r
129 @param[out] Str The formatted IP string.\r
130\r
131**/\r
132VOID\r
133Ip6ToStr (\r
134 IN EFI_IPv6_ADDRESS *Ip6,\r
135 OUT CHAR16 *Str\r
136 )\r
137{\r
d1050b9d
MK
138 UINTN Index;\r
139 BOOLEAN Short;\r
140 UINTN Number;\r
141 CHAR16 FormatString[8];\r
a3bcde70
HT
142\r
143 Short = FALSE;\r
144\r
145 for (Index = 0; Index < 15; Index = Index + 2) {\r
146 if (!Short &&\r
d1050b9d
MK
147 (Index % 2 == 0) &&\r
148 (Ip6->Addr[Index] == 0) &&\r
149 (Ip6->Addr[Index + 1] == 0)\r
150 )\r
151 {\r
a3bcde70
HT
152 //\r
153 // Deal with the case of ::.\r
154 //\r
155 if (Index == 0) {\r
156 *Str = L':';\r
157 *(Str + 1) = L':';\r
158 Str = Str + 2;\r
159 } else {\r
d1050b9d
MK
160 *Str = L':';\r
161 Str = Str + 1;\r
a3bcde70
HT
162 }\r
163\r
164 while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {\r
165 Index = Index + 2;\r
166 }\r
167\r
168 Short = TRUE;\r
169\r
170 if (Index == 16) {\r
171 //\r
172 // :: is at the end of the address.\r
173 //\r
174 *Str = L'\0';\r
175 break;\r
176 }\r
177 }\r
178\r
179 ASSERT (Index < 15);\r
180\r
181 if (Ip6->Addr[Index] == 0) {\r
d1050b9d 182 Number = UnicodeSPrint (Str, 2 * IP6_STR_MAX_SIZE, L"%x:", (UINTN)Ip6->Addr[Index + 1]);\r
a3bcde70
HT
183 } else {\r
184 if (Ip6->Addr[Index + 1] < 0x10) {\r
185 CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));\r
186 } else {\r
187 CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:"));\r
188 }\r
189\r
190 Number = UnicodeSPrint (\r
191 Str,\r
192 2 * IP6_STR_MAX_SIZE,\r
d1050b9d
MK
193 (CONST CHAR16 *)FormatString,\r
194 (UINTN)Ip6->Addr[Index],\r
195 (UINTN)Ip6->Addr[Index + 1]\r
a3bcde70
HT
196 );\r
197 }\r
198\r
199 Str = Str + Number;\r
200\r
201 if (Index + 2 == 16) {\r
202 *Str = L'\0';\r
203 if (*(Str - 1) == L':') {\r
204 *(Str - 1) = L'\0';\r
205 }\r
206 }\r
207 }\r
208}\r
209\r
210/**\r
211 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.\r
212\r
213 @param[out] String The buffer to store the converted string.\r
214 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.\r
215\r
216 @retval EFI_SUCCESS The string converted successfully.\r
217 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
218\r
219**/\r
220EFI_STATUS\r
221Ip6ConvertInterfaceIdToString (\r
d1050b9d
MK
222 OUT CHAR16 *String,\r
223 IN EFI_IP6_CONFIG_INTERFACE_ID *IfId\r
a3bcde70
HT
224 )\r
225{\r
d1050b9d
MK
226 UINT8 Index;\r
227 UINTN Number;\r
a3bcde70
HT
228\r
229 if ((String == NULL) || (IfId == NULL)) {\r
230 return EFI_INVALID_PARAMETER;\r
231 }\r
232\r
233 for (Index = 0; Index < 8; Index++) {\r
234 Number = UnicodeSPrint (\r
235 String,\r
236 2 * INTERFACE_ID_STR_STORAGE,\r
237 L"%x:",\r
d1050b9d 238 (UINTN)IfId->Id[Index]\r
a3bcde70
HT
239 );\r
240 String = String + Number;\r
241 }\r
242\r
243 *(String - 1) = '\0';\r
244\r
245 return EFI_SUCCESS;\r
246}\r
247\r
248/**\r
249 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.\r
250\r
251 @param[in] String The buffer of the string to be parsed.\r
252 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.\r
253\r
254 @retval EFI_SUCCESS The operation finished successfully.\r
255 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
256\r
257**/\r
258EFI_STATUS\r
259Ip6ParseInterfaceIdFromString (\r
d1050b9d
MK
260 IN CONST CHAR16 *String,\r
261 OUT EFI_IP6_CONFIG_INTERFACE_ID *IfId\r
a3bcde70
HT
262 )\r
263{\r
d1050b9d
MK
264 UINT8 Index;\r
265 CHAR16 *IfIdStr;\r
266 CHAR16 *TempStr;\r
267 UINTN NodeVal;\r
a3bcde70
HT
268\r
269 if ((String == NULL) || (IfId == NULL)) {\r
270 return EFI_INVALID_PARAMETER;\r
271 }\r
272\r
d1050b9d 273 IfIdStr = (CHAR16 *)String;\r
a3bcde70
HT
274\r
275 ZeroMem (IfId, sizeof (EFI_IP6_CONFIG_INTERFACE_ID));\r
276\r
277 for (Index = 0; Index < 8; Index++) {\r
278 TempStr = IfIdStr;\r
279\r
280 while ((*IfIdStr != L'\0') && (*IfIdStr != L':')) {\r
281 IfIdStr++;\r
282 }\r
283\r
284 //\r
285 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.\r
286 // If the number of X is less than 8, zero is appended to the InterfaceId.\r
287 //\r
288 if ((*IfIdStr == ':') && (Index == 7)) {\r
289 return EFI_INVALID_PARAMETER;\r
290 }\r
291\r
292 //\r
293 // Convert the string to interface id. AsciiStrHexToUintn stops at the\r
294 // first character that is not a valid hex character, ':' or '\0' here.\r
295 //\r
296 NodeVal = StrHexToUintn (TempStr);\r
297 if (NodeVal > 0xFF) {\r
298 return EFI_INVALID_PARAMETER;\r
299 }\r
300\r
d1050b9d 301 IfId->Id[Index] = (UINT8)NodeVal;\r
a3bcde70
HT
302\r
303 IfIdStr++;\r
304 }\r
305\r
306 return EFI_SUCCESS;\r
307}\r
308\r
309/**\r
310 Create Hii Extend Label OpCode as the start opcode and end opcode. It is\r
311 a help function.\r
312\r
313 @param[in] StartLabelNumber The number of start label.\r
314 @param[out] StartOpCodeHandle Points to the start opcode handle.\r
315 @param[out] StartLabel Points to the created start opcode.\r
316 @param[out] EndOpCodeHandle Points to the end opcode handle.\r
317 @param[out] EndLabel Points to the created end opcode.\r
318\r
319 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this\r
320 operation.\r
321 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
322 @retval EFI_SUCCESS The operation completed successfully.\r
323\r
324**/\r
325EFI_STATUS\r
326Ip6CreateOpCode (\r
d1050b9d
MK
327 IN UINT16 StartLabelNumber,\r
328 OUT VOID **StartOpCodeHandle,\r
329 OUT EFI_IFR_GUID_LABEL **StartLabel,\r
330 OUT VOID **EndOpCodeHandle,\r
331 OUT EFI_IFR_GUID_LABEL **EndLabel\r
a3bcde70
HT
332 )\r
333{\r
d1050b9d
MK
334 EFI_STATUS Status;\r
335 EFI_IFR_GUID_LABEL *InternalStartLabel;\r
336 EFI_IFR_GUID_LABEL *InternalEndLabel;\r
a3bcde70 337\r
d1050b9d 338 if ((StartOpCodeHandle == NULL) || (StartLabel == NULL) || (EndOpCodeHandle == NULL) || (EndLabel == NULL)) {\r
a3bcde70
HT
339 return EFI_INVALID_PARAMETER;\r
340 }\r
341\r
342 *StartOpCodeHandle = NULL;\r
343 *EndOpCodeHandle = NULL;\r
344 Status = EFI_OUT_OF_RESOURCES;\r
345\r
346 //\r
347 // Initialize the container for dynamic opcodes.\r
348 //\r
349 *StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
350 if (*StartOpCodeHandle == NULL) {\r
351 return Status;\r
352 }\r
353\r
354 *EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
355 if (*EndOpCodeHandle == NULL) {\r
356 goto Exit;\r
357 }\r
358\r
359 //\r
360 // Create Hii Extend Label OpCode as the start opcode.\r
361 //\r
d1050b9d
MK
362 InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
363 *StartOpCodeHandle,\r
364 &gEfiIfrTianoGuid,\r
365 NULL,\r
366 sizeof (EFI_IFR_GUID_LABEL)\r
367 );\r
a3bcde70
HT
368 if (InternalStartLabel == NULL) {\r
369 goto Exit;\r
370 }\r
371\r
372 InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
373 InternalStartLabel->Number = StartLabelNumber;\r
374\r
375 //\r
376 // Create Hii Extend Label OpCode as the end opcode.\r
377 //\r
d1050b9d
MK
378 InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
379 *EndOpCodeHandle,\r
380 &gEfiIfrTianoGuid,\r
381 NULL,\r
382 sizeof (EFI_IFR_GUID_LABEL)\r
383 );\r
a3bcde70
HT
384 if (InternalEndLabel == NULL) {\r
385 goto Exit;\r
386 }\r
387\r
388 InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
389 InternalEndLabel->Number = LABEL_END;\r
390\r
391 *StartLabel = InternalStartLabel;\r
392 *EndLabel = InternalEndLabel;\r
393\r
394 return EFI_SUCCESS;\r
395\r
396Exit:\r
397\r
398 if (*StartOpCodeHandle != NULL) {\r
399 HiiFreeOpCodeHandle (*StartOpCodeHandle);\r
400 }\r
401\r
402 if (*EndOpCodeHandle != NULL) {\r
403 HiiFreeOpCodeHandle (*EndOpCodeHandle);\r
404 }\r
405\r
406 return Status;\r
407}\r
408\r
409/**\r
410 This function converts the different format of address list to string format and\r
7de8045a 411 then generates the corresponding text opcode to illustrate the address info in\r
a3bcde70
HT
412 IP6 configuration page. Currently, the following formats are supported:\r
413 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;\r
414 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;\r
415 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.\r
416\r
417 @param[in, out] String The pointer to the buffer to store the converted\r
418 string.\r
419 @param[in] HiiHandle A handle that was previously registered in the\r
420 HII Database.\r
421 @param[in] AddressType The address type.\r
422 @param[in] AddressInfo Pointer to the address list.\r
423 @param[in] AddressCount The address count of the address list.\r
424\r
425 @retval EFI_SUCCESS The operation finished successfully.\r
426 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
427 @retval EFI_UNSUPPORTED The AddressType is not supported.\r
428\r
429\r
430**/\r
431EFI_STATUS\r
432Ip6ConvertAddressListToString (\r
d1050b9d
MK
433 IN OUT CHAR16 *String,\r
434 IN EFI_HII_HANDLE HiiHandle,\r
435 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,\r
436 IN VOID *AddressInfo,\r
437 IN UINTN AddressCount\r
a3bcde70
HT
438 )\r
439{\r
d1050b9d
MK
440 UINTN Index;\r
441 UINTN Number;\r
442 CHAR16 *TempStr;\r
443 EFI_STATUS Status;\r
444 VOID *StartOpCodeHandle;\r
445 EFI_IFR_GUID_LABEL *StartLabel;\r
446 VOID *EndOpCodeHandle;\r
447 EFI_IFR_GUID_LABEL *EndLabel;\r
448 UINT16 StartLabelNumber;\r
449 EFI_STRING_ID TextTwo;\r
450 UINT8 *AddressHead;\r
451 UINT8 PrefixLength;\r
452 EFI_IPv6_ADDRESS *Address;\r
a3bcde70
HT
453\r
454 if ((String == NULL) || (HiiHandle == NULL) || (AddressInfo == NULL)) {\r
455 return EFI_INVALID_PARAMETER;\r
456 }\r
457\r
458 if (AddressType == Ip6ConfigNvHostAddress) {\r
459 StartLabelNumber = HOST_ADDRESS_LABEL;\r
460 } else if (AddressType == Ip6ConfigNvGatewayAddress) {\r
461 StartLabelNumber = GATEWAY_ADDRESS_LABEL;\r
462 } else if (AddressType == Ip6ConfigNvDnsAddress) {\r
463 StartLabelNumber = DNS_ADDRESS_LABEL;\r
464 } else if (AddressType == Ip6ConfigNvRouteTable) {\r
465 StartLabelNumber = ROUTE_TABLE_LABEL;\r
466 } else {\r
467 ASSERT (FALSE);\r
468 return EFI_UNSUPPORTED;\r
469 }\r
470\r
471 Status = Ip6CreateOpCode (\r
472 StartLabelNumber,\r
473 &StartOpCodeHandle,\r
474 &StartLabel,\r
475 &EndOpCodeHandle,\r
476 &EndLabel\r
477 );\r
478 if (EFI_ERROR (Status)) {\r
479 return Status;\r
480 }\r
481\r
d1050b9d 482 AddressHead = (UINT8 *)AddressInfo;\r
a3bcde70
HT
483\r
484 for (Index = 0; Index < AddressCount; Index++) {\r
485 if (AddressType == Ip6ConfigNvHostAddress) {\r
486 AddressInfo = AddressHead + sizeof (EFI_IP6_ADDRESS_INFO) * Index;\r
d1050b9d 487 Address = &((EFI_IP6_ADDRESS_INFO *)AddressInfo)->Address;\r
a3bcde70
HT
488 } else if (AddressType == Ip6ConfigNvRouteTable) {\r
489 AddressInfo = AddressHead + sizeof (EFI_IP6_ROUTE_TABLE) * Index;\r
d1050b9d 490 Address = &((EFI_IP6_ROUTE_TABLE *)AddressInfo)->Destination;\r
a3bcde70
HT
491 } else {\r
492 AddressInfo = AddressHead + sizeof (EFI_IPv6_ADDRESS) * Index;\r
493 Address = AddressInfo;\r
494 }\r
495\r
496 //\r
497 // Convert the IP address info to string.\r
498 //\r
499 Ip6ToStr (Address, String);\r
500 TempStr = String + StrLen (String);\r
501\r
502 if ((AddressType == Ip6ConfigNvHostAddress) || (AddressType == Ip6ConfigNvRouteTable)) {\r
503 if (AddressType == Ip6ConfigNvHostAddress) {\r
d1050b9d 504 PrefixLength = ((EFI_IP6_ADDRESS_INFO *)AddressInfo)->PrefixLength;\r
a3bcde70 505 } else {\r
d1050b9d 506 PrefixLength = ((EFI_IP6_ROUTE_TABLE *)AddressInfo)->PrefixLength;\r
a3bcde70
HT
507 }\r
508\r
509 //\r
510 // Append the prefix length to the string.\r
511 //\r
512 *TempStr = L'/';\r
513 TempStr++;\r
514 Number = UnicodeSPrint (TempStr, 6, L"%d", PrefixLength);\r
515 TempStr = TempStr + Number;\r
516 }\r
517\r
518 if (AddressType == Ip6ConfigNvRouteTable) {\r
519 //\r
520 // Append " >> " to the string.\r
521 //\r
d1050b9d
MK
522 Number = UnicodeSPrint (TempStr, 8, L" >> ");\r
523 TempStr = TempStr + Number;\r
a3bcde70
HT
524\r
525 //\r
526 // Append the gateway address to the string.\r
527 //\r
d1050b9d 528 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE *)AddressInfo)->Gateway, TempStr);\r
a3bcde70
HT
529 TempStr = TempStr + StrLen (TempStr);\r
530 }\r
531\r
532 //\r
533 // Generate a text opcode and update the UI.\r
534 //\r
535 TextTwo = HiiSetString (HiiHandle, 0, String, NULL);\r
536 if (TextTwo == 0) {\r
537 Status = EFI_INVALID_PARAMETER;\r
538 goto Exit;\r
539 }\r
540\r
541 HiiCreateTextOpCode (StartOpCodeHandle, STR_NULL, STR_NULL, TextTwo);\r
542\r
d1050b9d 543 String = TempStr;\r
a3bcde70
HT
544 *String = IP6_ADDRESS_DELIMITER;\r
545 String++;\r
546 }\r
547\r
548 *(String - 1) = '\0';\r
549\r
550 Status = HiiUpdateForm (\r
551 HiiHandle, // HII handle\r
9bdc6592 552 &gIp6ConfigNvDataGuid, // Formset GUID\r
a3bcde70
HT
553 FORMID_MAIN_FORM, // Form ID\r
554 StartOpCodeHandle, // Label for where to insert opcodes\r
555 EndOpCodeHandle // Replace data\r
556 );\r
557\r
558Exit:\r
559 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
560 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
561\r
562 return Status;\r
563}\r
564\r
565/**\r
566 Parse address list in string format and convert it to a list array of node in\r
567 IP6_ADDRESS_INFO_ENTRY.\r
568\r
569 @param[in] String The buffer to string to be parsed.\r
570 @param[out] ListHead The list head of array.\r
571 @param[out] AddressCount The number of list nodes in the array.\r
572\r
573 @retval EFI_SUCCESS The operation finished successfully.\r
574 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
575 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.\r
576\r
577**/\r
578EFI_STATUS\r
579Ip6ParseAddressListFromString (\r
d1050b9d
MK
580 IN CONST CHAR16 *String,\r
581 OUT LIST_ENTRY *ListHead,\r
582 OUT UINT32 *AddressCount\r
a3bcde70
HT
583 )\r
584{\r
d1050b9d
MK
585 EFI_STATUS Status;\r
586 CHAR16 *LocalString;\r
587 CHAR16 *Temp;\r
588 CHAR16 *TempStr;\r
589 EFI_IP6_ADDRESS_INFO AddressInfo;\r
590 IP6_ADDRESS_INFO_ENTRY *Node;\r
591 BOOLEAN Last;\r
592 UINT32 Count;\r
a3bcde70
HT
593\r
594 if ((String == NULL) || (ListHead == NULL) || (AddressCount == NULL)) {\r
595 return EFI_INVALID_PARAMETER;\r
596 }\r
597\r
393a3169 598 ZeroMem (&AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));\r
d1050b9d 599 LocalString = (CHAR16 *)AllocateCopyPool (StrSize (String), String);\r
a3bcde70
HT
600 if (LocalString == NULL) {\r
601 return EFI_OUT_OF_RESOURCES;\r
602 }\r
603\r
604 //\r
605 // Clean the original address list.\r
606 //\r
607 Ip6FreeAddressInfoList (ListHead);\r
608\r
609 Temp = LocalString;\r
610 Last = FALSE;\r
611 Count = 0;\r
612\r
613 while (*LocalString != L'\0') {\r
614 TempStr = LocalString;\r
615 while ((*LocalString != L'\0') && (*LocalString != IP6_ADDRESS_DELIMITER)) {\r
616 LocalString++;\r
617 }\r
618\r
619 if (*LocalString == L'\0') {\r
620 Last = TRUE;\r
621 }\r
622\r
623 *LocalString = L'\0';\r
624\r
625 Status = NetLibStrToIp6andPrefix (TempStr, &AddressInfo.Address, &AddressInfo.PrefixLength);\r
626 if (EFI_ERROR (Status)) {\r
627 goto Error;\r
628 }\r
629\r
630 if (AddressInfo.PrefixLength == 0xFF) {\r
631 AddressInfo.PrefixLength = 0;\r
632 }\r
633\r
634 if (!NetIp6IsValidUnicast (&AddressInfo.Address)) {\r
635 Status = EFI_INVALID_PARAMETER;\r
636 goto Error;\r
637 }\r
638\r
639 Node = AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY));\r
640 if (Node == NULL) {\r
641 Status = EFI_OUT_OF_RESOURCES;\r
642 goto Error;\r
643 }\r
644\r
645 CopyMem (&Node->AddrInfo, &AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));\r
646 InsertTailList (ListHead, &Node->Link);\r
647 Count++;\r
648\r
649 if (Last) {\r
650 break;\r
651 }\r
652\r
653 LocalString++;\r
654 }\r
655\r
656 FreePool (Temp);\r
657 *AddressCount = Count;\r
658 return EFI_SUCCESS;\r
659\r
660Error:\r
661 Ip6FreeAddressInfoList (ListHead);\r
662 FreePool (Temp);\r
663 return Status;\r
664}\r
665\r
666/**\r
667 This function converts the interface info to string and draws it to the IP6 UI.\r
130df890 668 The interface information includes interface name, interface type, hardware\r
669 address and route table information.\r
a3bcde70
HT
670\r
671 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.\r
672 @param[in] HiiHandle The handle that was previously registered in the\r
673 HII Database.\r
674 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.\r
675\r
676 @retval EFI_SUCCESS The operation finished successfully.\r
677 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
678 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.\r
679\r
680**/\r
681EFI_STATUS\r
682Ip6ConvertInterfaceInfoToString (\r
683 IN EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo,\r
684 IN EFI_HII_HANDLE HiiHandle,\r
685 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData\r
686 )\r
687{\r
d1050b9d
MK
688 UINT32 Index;\r
689 UINTN Number;\r
690 CHAR16 *String;\r
691 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];\r
692 CHAR16 FormatString[8];\r
693 EFI_STRING_ID StringId;\r
a3bcde70
HT
694\r
695 if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {\r
696 return EFI_INVALID_PARAMETER;\r
697 }\r
698\r
699 //\r
700 // Print the interface name.\r
701 //\r
702 StringId = HiiSetString (\r
703 HiiHandle,\r
704 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT),\r
705 IfInfo->Name,\r
706 NULL\r
707 );\r
708 if (StringId == 0) {\r
709 return EFI_OUT_OF_RESOURCES;\r
710 }\r
711\r
712 //\r
713 // Print the interface type.\r
714 //\r
715 if (IfInfo->IfType == Ip6InterfaceTypeEthernet) {\r
a4faf336 716 CopyMem (PortString, IP6_ETHERNET, sizeof (IP6_ETHERNET));\r
a3bcde70 717 } else if (IfInfo->IfType == Ip6InterfaceTypeExperimentalEthernet) {\r
a4faf336 718 CopyMem (PortString, IP6_EXPERIMENTAL_ETHERNET, sizeof (IP6_EXPERIMENTAL_ETHERNET));\r
a3bcde70
HT
719 } else {\r
720 //\r
721 // Refer to RFC1700, chapter Number Hardware Type.\r
722 //\r
723 UnicodeSPrint (PortString, 6, L"%d", IfInfo->IfType);\r
724 }\r
725\r
726 StringId = HiiSetString (\r
727 HiiHandle,\r
728 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT),\r
729 PortString,\r
730 NULL\r
731 );\r
732 if (StringId == 0) {\r
733 return EFI_OUT_OF_RESOURCES;\r
734 }\r
735\r
736 //\r
737 // Convert the hardware address.\r
738 //\r
739 String = PortString;\r
740 ASSERT (IfInfo->HwAddressSize <= 32);\r
741\r
742 for (Index = 0; Index < IfInfo->HwAddressSize; Index++) {\r
a3bcde70 743 if (IfInfo->HwAddress.Addr[Index] < 0x10) {\r
a4faf336 744 CopyMem (FormatString, L"0%x-", sizeof (L"0%x-"));\r
a3bcde70 745 } else {\r
a4faf336 746 CopyMem (FormatString, L"%x-", sizeof (L"%x-"));\r
a3bcde70
HT
747 }\r
748\r
749 Number = UnicodeSPrint (\r
750 String,\r
751 8,\r
d1050b9d
MK
752 (CONST CHAR16 *)FormatString,\r
753 (UINTN)IfInfo->HwAddress.Addr[Index]\r
a3bcde70
HT
754 );\r
755 String = String + Number;\r
756 }\r
757\r
758 if (Index != 0) {\r
759 ASSERT (String > PortString);\r
760 String--;\r
761 *String = '\0';\r
762 }\r
763\r
764 //\r
765 // Print the hardware address.\r
766 //\r
767 StringId = HiiSetString (\r
768 HiiHandle,\r
769 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT),\r
770 PortString,\r
771 NULL\r
772 );\r
773 if (StringId == 0) {\r
774 return EFI_OUT_OF_RESOURCES;\r
775 }\r
776\r
e464225c 777 return EFI_SUCCESS;\r
a3bcde70
HT
778}\r
779\r
780/**\r
781 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.\r
782\r
783 @param[in] Instance Points to IP6 config instance data.\r
784 @param[in] AddressType The address type.\r
785 @param[out] AddressInfo The pointer to the buffer to store the address list.\r
786 @param[out] AddressSize The address size of the address list.\r
787\r
788 @retval EFI_SUCCESS The operation finished successfully.\r
789 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
790 @retval EFI_UNSUPPORTED The AddressType is not supported.\r
791\r
792**/\r
793EFI_STATUS\r
794Ip6BuildNvAddressInfo (\r
d1050b9d
MK
795 IN IP6_CONFIG_INSTANCE *Instance,\r
796 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,\r
797 OUT VOID **AddressInfo,\r
798 OUT UINTN *AddressSize\r
a3bcde70
HT
799 )\r
800{\r
d1050b9d
MK
801 IP6_CONFIG_NVDATA *Ip6NvData;\r
802 LIST_ENTRY *Entry;\r
803 LIST_ENTRY *ListHead;\r
804 IP6_ADDRESS_INFO_ENTRY *Node;\r
805 VOID *AddressList;\r
806 VOID *TmpStr;\r
807 UINTN DataSize;\r
808 EFI_IPv6_ADDRESS *Ip6Address;\r
809 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;\r
a3bcde70
HT
810\r
811 if ((Instance == NULL) || (AddressInfo == NULL) || (AddressSize == NULL)) {\r
812 return EFI_INVALID_PARAMETER;\r
813 }\r
814\r
815 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
816\r
817 Ip6NvData = &Instance->Ip6NvData;\r
818\r
819 if (AddressType == Ip6ConfigNvHostAddress) {\r
820 ListHead = &Ip6NvData->ManualAddress;\r
821 DataSize = sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS) * Ip6NvData->ManualAddressCount;\r
822 } else if (AddressType == Ip6ConfigNvGatewayAddress) {\r
823 ListHead = &Ip6NvData->GatewayAddress;\r
824 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->GatewayAddressCount;\r
825 } else if (AddressType == Ip6ConfigNvDnsAddress) {\r
826 ListHead = &Ip6NvData->DnsAddress;\r
827 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->DnsAddressCount;\r
828 } else {\r
829 return EFI_UNSUPPORTED;\r
830 }\r
831\r
832 AddressList = AllocateZeroPool (DataSize);\r
833 if (AddressList == NULL) {\r
834 return EFI_OUT_OF_RESOURCES;\r
835 }\r
836\r
837 TmpStr = AddressList;\r
838\r
839 NET_LIST_FOR_EACH (Entry, ListHead) {\r
840 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);\r
841 if (AddressType == Ip6ConfigNvHostAddress) {\r
d1050b9d 842 ManualAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *)AddressList;\r
a3bcde70
HT
843 IP6_COPY_ADDRESS (&ManualAddress->Address, &Node->AddrInfo.Address);\r
844 ManualAddress->PrefixLength = Node->AddrInfo.PrefixLength;\r
d1050b9d 845 AddressList = (UINT8 *)AddressList + sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);\r
a3bcde70 846 } else {\r
d1050b9d 847 Ip6Address = (EFI_IPv6_ADDRESS *)AddressList;\r
a3bcde70 848 IP6_COPY_ADDRESS (Ip6Address, &Node->AddrInfo.Address);\r
d1050b9d 849 AddressList = (UINT8 *)AddressList + sizeof (EFI_IPv6_ADDRESS);\r
a3bcde70
HT
850 }\r
851 }\r
852\r
853 *AddressInfo = TmpStr;\r
854 *AddressSize = DataSize;\r
855 return EFI_SUCCESS;\r
856}\r
857\r
858/**\r
859 Convert the IP6 configuration data into the IFR data.\r
860\r
861 @param[in, out] IfrNvData The IFR NV data.\r
862 @param[in] Instance The IP6 config instance data.\r
863\r
864 @retval EFI_SUCCESS The operation finished successfully.\r
865 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
866 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.\r
867 @retval Others Other errors as indicated.\r
868\r
869**/\r
870EFI_STATUS\r
871Ip6ConvertConfigNvDataToIfrNvData (\r
d1050b9d
MK
872 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData,\r
873 IN IP6_CONFIG_INSTANCE *Instance\r
a3bcde70
HT
874 )\r
875{\r
d1050b9d
MK
876 IP6_CONFIG_NVDATA *Ip6NvData;\r
877 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
878 UINTN DataSize;\r
879 VOID *Data;\r
880 EFI_STATUS Status;\r
881 EFI_IP6_CONFIG_POLICY Policy;\r
882 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits;\r
883 EFI_HII_HANDLE HiiHandle;\r
a3bcde70
HT
884\r
885 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
886 return EFI_INVALID_PARAMETER;\r
887 }\r
888\r
889 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
890\r
891 Ip6Config = &Instance->Ip6Config;\r
0b2a54e2 892 Ip6NvData = &Instance->Ip6NvData;\r
a3bcde70
HT
893 Data = NULL;\r
894 DataSize = 0;\r
895 HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
896\r
897 //\r
898 // Get the current interface info.\r
899 //\r
900 Status = Ip6ConfigNvGetData (\r
901 Ip6Config,\r
902 Ip6ConfigDataTypeInterfaceInfo,\r
903 &DataSize,\r
d1050b9d 904 (VOID **)&Data\r
a3bcde70
HT
905 );\r
906 if (EFI_ERROR (Status)) {\r
907 goto Exit;\r
908 }\r
909\r
910 //\r
911 // Convert the interface info to string and print.\r
912 //\r
913 Status = Ip6ConvertInterfaceInfoToString (\r
d1050b9d 914 (EFI_IP6_CONFIG_INTERFACE_INFO *)Data,\r
a3bcde70
HT
915 HiiHandle,\r
916 IfrNvData\r
917 );\r
918 if (EFI_ERROR (Status)) {\r
919 goto Exit;\r
920 }\r
921\r
922 //\r
923 // Get the interface id.\r
924 //\r
925 DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);\r
0b2a54e2 926 ZeroMem (&Ip6NvData->InterfaceId, DataSize);\r
a3bcde70
HT
927 Status = Ip6Config->GetData (\r
928 Ip6Config,\r
929 Ip6ConfigDataTypeAltInterfaceId,\r
930 &DataSize,\r
0b2a54e2 931 &Ip6NvData->InterfaceId\r
a3bcde70
HT
932 );\r
933 if (EFI_ERROR (Status)) {\r
934 goto Exit;\r
935 }\r
936\r
0b2a54e2 937 Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
a3bcde70
HT
938\r
939 //\r
940 // Get current policy.\r
941 //\r
942 DataSize = sizeof (EFI_IP6_CONFIG_POLICY);\r
943 Status = Ip6Config->GetData (\r
944 Ip6Config,\r
945 Ip6ConfigDataTypePolicy,\r
946 &DataSize,\r
947 &Policy\r
948 );\r
949\r
950 if (EFI_ERROR (Status)) {\r
951 goto Exit;\r
952 }\r
953\r
954 if (Policy == Ip6ConfigPolicyManual) {\r
955 IfrNvData->Policy = IP6_POLICY_MANUAL;\r
956 } else if (Policy == Ip6ConfigPolicyAutomatic) {\r
957 IfrNvData->Policy = IP6_POLICY_AUTO;\r
958 } else {\r
959 ASSERT (FALSE);\r
960 Status = EFI_UNSUPPORTED;\r
961 goto Exit;\r
962 }\r
963\r
964 //\r
965 // Get Duplicate Address Detection Transmits count.\r
966 //\r
967 DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);\r
968 Status = Ip6Config->GetData (\r
969 Ip6Config,\r
970 Ip6ConfigDataTypeDupAddrDetectTransmits,\r
971 &DataSize,\r
972 &DadXmits\r
973 );\r
974\r
975 if (EFI_ERROR (Status)) {\r
976 goto Exit;\r
977 }\r
978\r
979 IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;\r
980\r
a3bcde70
HT
981Exit:\r
982 if (Data != NULL) {\r
d1050b9d 983 FreePool (Data);\r
a3bcde70
HT
984 }\r
985\r
986 return Status;\r
987}\r
988\r
989/**\r
990 Convert IFR data into IP6 configuration data. The policy, alternative interface\r
f75a7f56 991 ID, and DAD transmit counts, and will be saved.\r
a3bcde70
HT
992\r
993 @param[in] IfrNvData The IFR NV data.\r
994 @param[in, out] Instance The IP6 config instance data.\r
995\r
996 @retval EFI_SUCCESS The operation finished successfully.\r
997 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
998 @retval Others Other errors as indicated.\r
999\r
1000**/\r
1001EFI_STATUS\r
130df890 1002Ip6ConvertIfrNvDataToConfigNvDataGeneral (\r
d1050b9d
MK
1003 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,\r
1004 IN OUT IP6_CONFIG_INSTANCE *Instance\r
a3bcde70
HT
1005 )\r
1006{\r
d1050b9d
MK
1007 IP6_CONFIG_NVDATA *Ip6NvData;\r
1008 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
1009 EFI_STATUS Status;\r
a3bcde70
HT
1010\r
1011 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
1012 return EFI_INVALID_PARAMETER;\r
1013 }\r
1014\r
1015 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
1016 Ip6NvData = &Instance->Ip6NvData;\r
1017 Ip6Config = &Instance->Ip6Config;\r
1018\r
1019 //\r
1020 // Update those fields which don't have INTERACTIVE attribute.\r
1021 //\r
1022 if (IfrNvData->Policy == IP6_POLICY_AUTO) {\r
1023 Ip6NvData->Policy = Ip6ConfigPolicyAutomatic;\r
1024 } else if (IfrNvData->Policy == IP6_POLICY_MANUAL) {\r
1025 Ip6NvData->Policy = Ip6ConfigPolicyManual;\r
1026 }\r
1027\r
1028 Ip6NvData->DadTransmitCount.DupAddrDetectTransmits = IfrNvData->DadTransmitCount;\r
1029\r
1030 //\r
1031 // Set the configured policy.\r
1032 //\r
1033 Status = Ip6Config->SetData (\r
1034 Ip6Config,\r
1035 Ip6ConfigDataTypePolicy,\r
1036 sizeof (EFI_IP6_CONFIG_POLICY),\r
1037 &Ip6NvData->Policy\r
1038 );\r
1039 if (EFI_ERROR (Status)) {\r
1040 return Status;\r
1041 }\r
1042\r
1043 //\r
1044 // Set the duplicate address detection transmits count.\r
1045 //\r
1046 Status = Ip6Config->SetData (\r
1047 Ip6Config,\r
1048 Ip6ConfigDataTypeDupAddrDetectTransmits,\r
1049 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),\r
1050 &Ip6NvData->DadTransmitCount\r
1051 );\r
1052 if (EFI_ERROR (Status)) {\r
1053 return Status;\r
1054 }\r
1055\r
1056 //\r
1057 // Set the alternative interface ID\r
1058 //\r
1059 Status = Ip6Config->SetData (\r
1060 Ip6Config,\r
1061 Ip6ConfigDataTypeAltInterfaceId,\r
1062 sizeof (EFI_IP6_CONFIG_INTERFACE_ID),\r
1063 &Ip6NvData->InterfaceId\r
1064 );\r
1065 if (EFI_ERROR (Status)) {\r
1066 return Status;\r
1067 }\r
1068\r
130df890 1069 return EFI_SUCCESS;\r
1070}\r
1071\r
1072/**\r
1073 Convert IFR data into IP6 configuration data. The policy, configured\r
1074 manual address, gateway address, and DNS server address will be saved.\r
1075\r
1076 @param[in] IfrNvData The IFR NV data.\r
1077 @param[in, out] Instance The IP6 config instance data.\r
1078\r
1079 @retval EFI_SUCCESS The operation finished successfully.\r
1080 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1081 @retval Others Other errors as indicated.\r
1082\r
1083**/\r
1084EFI_STATUS\r
1085Ip6ConvertIfrNvDataToConfigNvDataAdvanced (\r
d1050b9d
MK
1086 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,\r
1087 IN OUT IP6_CONFIG_INSTANCE *Instance\r
130df890 1088 )\r
1089{\r
d1050b9d
MK
1090 IP6_CONFIG_NVDATA *Ip6NvData;\r
1091 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
1092 EFI_STATUS Status;\r
1093 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;\r
1094 EFI_IPv6_ADDRESS *Address;\r
1095 BOOLEAN IsAddressOk;\r
1096 EFI_EVENT SetAddressEvent;\r
1097 EFI_EVENT TimeoutEvent;\r
1098 UINTN DataSize;\r
130df890 1099\r
1100 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
1101 return EFI_INVALID_PARAMETER;\r
1102 }\r
a3bcde70 1103\r
130df890 1104 if (IfrNvData->Policy == IP6_POLICY_AUTO) {\r
a3bcde70
HT
1105 return EFI_SUCCESS;\r
1106 }\r
1107\r
130df890 1108 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
1109 Ip6NvData = &Instance->Ip6NvData;\r
1110 Ip6Config = &Instance->Ip6Config;\r
1111\r
1112 //\r
1113 // Update those fields which don't have INTERACTIVE attribute.\r
1114 //\r
1115 Ip6NvData->Policy = Ip6ConfigPolicyManual;\r
1116\r
1117 //\r
1118 // Set the configured policy.\r
1119 //\r
1120 Status = Ip6Config->SetData (\r
1121 Ip6Config,\r
1122 Ip6ConfigDataTypePolicy,\r
1123 sizeof (EFI_IP6_CONFIG_POLICY),\r
1124 &Ip6NvData->Policy\r
1125 );\r
1126 if (EFI_ERROR (Status)) {\r
1127 return Status;\r
1128 }\r
1129\r
a3bcde70
HT
1130 //\r
1131 // Create events & timers for asynchronous settings.\r
1132 //\r
1133 SetAddressEvent = NULL;\r
1134 TimeoutEvent = NULL;\r
1135 ManualAddress = NULL;\r
1136 Address = NULL;\r
1137\r
1138 Status = gBS->CreateEvent (\r
1139 EVT_NOTIFY_SIGNAL,\r
1140 TPL_NOTIFY,\r
1141 Ip6ConfigManualAddressNotify,\r
1142 &IsAddressOk,\r
1143 &SetAddressEvent\r
1144 );\r
1145 if (EFI_ERROR (Status)) {\r
1146 goto Exit;\r
1147 }\r
1148\r
1149 Status = gBS->CreateEvent (\r
1150 EVT_TIMER,\r
1151 TPL_CALLBACK,\r
1152 NULL,\r
1153 NULL,\r
1154 &TimeoutEvent\r
1155 );\r
1156 if (EFI_ERROR (Status)) {\r
1157 goto Exit;\r
1158 }\r
1159\r
1160 //\r
1161 // Set the manual address list. This is an asynchronous process.\r
1162 //\r
1163 if (!IsListEmpty (&Ip6NvData->ManualAddress) && (Ip6NvData->ManualAddressCount != 0)) {\r
1164 Status = Ip6BuildNvAddressInfo (\r
1165 Instance,\r
1166 Ip6ConfigNvHostAddress,\r
d1050b9d 1167 (VOID **)&ManualAddress,\r
a3bcde70
HT
1168 &DataSize\r
1169 );\r
1170 if (EFI_ERROR (Status)) {\r
1171 goto Exit;\r
1172 }\r
1173\r
1174 IsAddressOk = FALSE;\r
1175\r
1176 Status = Ip6Config->RegisterDataNotify (\r
1177 Ip6Config,\r
1178 Ip6ConfigDataTypeManualAddress,\r
1179 SetAddressEvent\r
1180 );\r
1181 if (EFI_ERROR (Status)) {\r
1182 goto Exit;\r
1183 }\r
1184\r
1185 Status = Ip6Config->SetData (\r
1186 Ip6Config,\r
1187 Ip6ConfigDataTypeManualAddress,\r
1188 DataSize,\r
d1050b9d 1189 (VOID *)ManualAddress\r
a3bcde70
HT
1190 );\r
1191 if (Status == EFI_NOT_READY) {\r
1192 gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);\r
1193 while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
1194 if (IsAddressOk) {\r
1195 Status = EFI_SUCCESS;\r
1196 }\r
d1050b9d 1197\r
a3bcde70
HT
1198 break;\r
1199 }\r
1200 }\r
1201\r
1202 Status = Ip6Config->UnregisterDataNotify (\r
1203 Ip6Config,\r
1204 Ip6ConfigDataTypeManualAddress,\r
1205 SetAddressEvent\r
1206 );\r
1207 if (EFI_ERROR (Status)) {\r
1208 goto Exit;\r
1209 }\r
1210 }\r
1211\r
1212 //\r
1213 // Set gateway address list.\r
1214 //\r
1215 if (!IsListEmpty (&Ip6NvData->GatewayAddress) && (Ip6NvData->GatewayAddressCount != 0)) {\r
1216 Status = Ip6BuildNvAddressInfo (\r
1217 Instance,\r
1218 Ip6ConfigNvGatewayAddress,\r
d1050b9d 1219 (VOID **)&Address,\r
a3bcde70
HT
1220 &DataSize\r
1221 );\r
1222 if (EFI_ERROR (Status)) {\r
1223 goto Exit;\r
1224 }\r
1225\r
1226 Status = Ip6Config->SetData (\r
1227 Ip6Config,\r
1228 Ip6ConfigDataTypeGateway,\r
1229 DataSize,\r
d1050b9d 1230 (VOID *)Address\r
a3bcde70
HT
1231 );\r
1232 if (EFI_ERROR (Status)) {\r
1233 goto Exit;\r
1234 }\r
1235\r
1236 FreePool (Address);\r
1237 Address = NULL;\r
1238 }\r
1239\r
1240 //\r
1241 // Set DNS server address list.\r
1242 //\r
1243 if (!IsListEmpty (&Ip6NvData->DnsAddress) && (Ip6NvData->DnsAddressCount != 0)) {\r
1244 Status = Ip6BuildNvAddressInfo (\r
1245 Instance,\r
1246 Ip6ConfigNvDnsAddress,\r
d1050b9d 1247 (VOID **)&Address,\r
a3bcde70
HT
1248 &DataSize\r
1249 );\r
1250 if (EFI_ERROR (Status)) {\r
1251 goto Exit;\r
1252 }\r
1253\r
1254 Status = Ip6Config->SetData (\r
1255 Ip6Config,\r
1256 Ip6ConfigDataTypeDnsServer,\r
1257 DataSize,\r
d1050b9d 1258 (VOID *)Address\r
a3bcde70
HT
1259 );\r
1260 if (EFI_ERROR (Status)) {\r
1261 goto Exit;\r
1262 }\r
1263 }\r
1264\r
1265 Status = EFI_SUCCESS;\r
1266\r
1267Exit:\r
1268 if (SetAddressEvent != NULL) {\r
1269 gBS->CloseEvent (SetAddressEvent);\r
1270 }\r
1271\r
1272 if (TimeoutEvent != NULL) {\r
1273 gBS->CloseEvent (TimeoutEvent);\r
1274 }\r
1275\r
1276 if (ManualAddress != NULL) {\r
1277 FreePool (ManualAddress);\r
1278 }\r
1279\r
1280 if (Address != NULL) {\r
1281 FreePool (Address);\r
1282 }\r
1283\r
1284 return Status;\r
1285}\r
1286\r
1287/**\r
1288 This function allows the caller to request the current\r
1289 configuration for one or more named elements. The resulting\r
1290 string is in <ConfigAltResp> format. Any and all alternative\r
1291 configuration strings shall also be appended to the end of the\r
1292 current configuration string. If they are, they must appear\r
1293 after the current configuration. They must contain the same\r
1294 routing (GUID, NAME, PATH) as the current configuration string.\r
1295 They must have an additional description indicating the type of\r
1296 alternative configuration the string represents,\r
1297 "ALTCFG=<StringToken>". That <StringToken> (when\r
1298 converted from Hex UNICODE to binary) is a reference to a\r
1299 string in the associated string pack.\r
1300\r
1301 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1302 @param[in] Request A null-terminated Unicode string in\r
1303 <ConfigRequest> format. Note that this\r
1304 includes the routing information as well as\r
1305 the configurable name / value pairs. It is\r
1306 invalid for this string to be in\r
1307 <MultiConfigRequest> format.\r
1308 @param[out] Progress On return, points to a character in the\r
1309 Request string. Points to the string's null\r
1310 terminator if request was successful. Points\r
1311 to the most recent "&" before the first\r
1312 failing name / value pair (or the beginning\r
1313 of the string if the failure is in the first\r
1314 name / value pair) if the request was not\r
1315 successful.\r
1316 @param[out] Results A null-terminated Unicode string in\r
1317 <ConfigAltResp> format which has all values\r
1318 filled in for the names in the Request string.\r
1319 String to be allocated by the called function.\r
1320\r
1321 @retval EFI_SUCCESS The Results string is filled with the\r
1322 values corresponding to all requested\r
1323 names.\r
1324 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
1325 parts of the results that must be\r
1326 stored awaiting possible future\r
1327 protocols.\r
1328 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
1329 for the Request parameter\r
1330 would result in this type of\r
1331 error. In this case, the\r
1332 Progress parameter would be\r
1333 set to NULL.\r
1334 @retval EFI_NOT_FOUND Routing data doesn't match any\r
1335 known driver. Progress set to the\r
1336 first character in the routing header.\r
1337 Note: There is no requirement that the\r
1338 driver validate the routing data. It\r
1339 must skip the <ConfigHdr> in order to\r
1340 process the names.\r
1341 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
1342 to most recent & before the\r
1343 error or the beginning of the\r
1344 string.\r
1345 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
1346 to the & before the name in\r
1347 question. Currently not implemented.\r
1348**/\r
1349EFI_STATUS\r
1350EFIAPI\r
1351Ip6FormExtractConfig (\r
d1050b9d
MK
1352 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1353 IN CONST EFI_STRING Request,\r
1354 OUT EFI_STRING *Progress,\r
1355 OUT EFI_STRING *Results\r
a3bcde70
HT
1356 )\r
1357{\r
d1050b9d
MK
1358 EFI_STATUS Status;\r
1359 IP6_FORM_CALLBACK_INFO *Private;\r
1360 IP6_CONFIG_INSTANCE *Ip6ConfigInstance;\r
1361 IP6_CONFIG_IFR_NVDATA *IfrNvData;\r
1362 EFI_STRING ConfigRequestHdr;\r
1363 EFI_STRING ConfigRequest;\r
1364 BOOLEAN AllocatedRequest;\r
1365 UINTN Size;\r
1366 UINTN BufferSize;\r
a3bcde70 1367\r
d1050b9d 1368 if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {\r
a3bcde70
HT
1369 return EFI_INVALID_PARAMETER;\r
1370 }\r
1371\r
1372 *Progress = Request;\r
1373 if ((Request != NULL) &&\r
d1050b9d
MK
1374 !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName))\r
1375 {\r
a3bcde70
HT
1376 return EFI_NOT_FOUND;\r
1377 }\r
1378\r
1379 ConfigRequestHdr = NULL;\r
1380 ConfigRequest = NULL;\r
1381 AllocatedRequest = FALSE;\r
1382 Size = 0;\r
1383\r
d1050b9d 1384 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
a3bcde70 1385 Ip6ConfigInstance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);\r
d1050b9d 1386 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
a3bcde70 1387\r
d1050b9d 1388 IfrNvData = (IP6_CONFIG_IFR_NVDATA *)AllocateZeroPool (BufferSize);\r
a3bcde70
HT
1389 if (IfrNvData == NULL) {\r
1390 return EFI_OUT_OF_RESOURCES;\r
1391 }\r
1392\r
1393 Status = Ip6ConvertConfigNvDataToIfrNvData (IfrNvData, Ip6ConfigInstance);\r
1394 if (EFI_ERROR (Status)) {\r
1395 goto Exit;\r
1396 }\r
1397\r
1398 ConfigRequest = Request;\r
1399 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
1400 //\r
1401 // Request has no request element, construct full request string.\r
1402 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
1403 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.\r
1404 //\r
1405 ConfigRequestHdr = HiiConstructConfigHdr (\r
9bdc6592 1406 &gIp6ConfigNvDataGuid,\r
a3bcde70
HT
1407 mIp6ConfigStorageName,\r
1408 Private->ChildHandle\r
1409 );\r
d1050b9d 1410 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
a3bcde70
HT
1411 ConfigRequest = AllocateZeroPool (Size);\r
1412 ASSERT (ConfigRequest != NULL);\r
1413 AllocatedRequest = TRUE;\r
1414 UnicodeSPrint (\r
1415 ConfigRequest,\r
1416 Size,\r
1417 L"%s&OFFSET=0&WIDTH=%016LX",\r
1418 ConfigRequestHdr,\r
d1050b9d 1419 (UINT64)BufferSize\r
a3bcde70
HT
1420 );\r
1421 FreePool (ConfigRequestHdr);\r
1422 }\r
1423\r
1424 //\r
1425 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
1426 //\r
1427 Status = gHiiConfigRouting->BlockToConfig (\r
1428 gHiiConfigRouting,\r
1429 ConfigRequest,\r
d1050b9d 1430 (UINT8 *)IfrNvData,\r
a3bcde70
HT
1431 BufferSize,\r
1432 Results,\r
1433 Progress\r
1434 );\r
1435\r
1436Exit:\r
1437 FreePool (IfrNvData);\r
1438 //\r
1439 // Free the allocated config request string.\r
1440 //\r
1441 if (AllocatedRequest) {\r
1442 FreePool (ConfigRequest);\r
1443 ConfigRequest = NULL;\r
1444 }\r
d1050b9d 1445\r
a3bcde70
HT
1446 //\r
1447 // Set Progress string to the original request string.\r
1448 //\r
1449 if (Request == NULL) {\r
1450 *Progress = NULL;\r
1451 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
1452 *Progress = Request + StrLen (Request);\r
1453 }\r
1454\r
1455 return Status;\r
1456}\r
1457\r
1458/**\r
1459 This function applies changes in a driver's configuration.\r
1460 Input is a Configuration, which has the routing data for this\r
1461 driver followed by name / value configuration pairs. The driver\r
1462 must apply those pairs to its configurable storage. If the\r
1463 driver's configuration is stored in a linear block of data\r
1464 and the driver's name / value pairs are in <BlockConfig>\r
1465 format, it may use the ConfigToBlock helper function (above) to\r
1466 simplify the job. Currently not implemented.\r
1467\r
1468 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1469 @param[in] Configuration A null-terminated Unicode string in\r
1470 <ConfigString> format.\r
1471 @param[out] Progress A pointer to a string filled in with the\r
1472 offset of the most recent '&' before the\r
1473 first failing name / value pair (or the\r
7de8045a 1474 beginning of the string if the failure\r
a3bcde70
HT
1475 is in the first name / value pair) or\r
1476 the terminating NULL if all was\r
1477 successful.\r
1478\r
1479 @retval EFI_SUCCESS The results have been distributed or are\r
1480 awaiting distribution.\r
1481 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
1482 parts of the results that must be\r
1483 stored awaiting possible future\r
1484 protocols.\r
1485 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
1486 Results parameter would result\r
1487 in this type of error.\r
1488 @retval EFI_NOT_FOUND Target for the specified routing data\r
1489 was not found.\r
1490**/\r
1491EFI_STATUS\r
1492EFIAPI\r
1493Ip6FormRouteConfig (\r
d1050b9d
MK
1494 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1495 IN CONST EFI_STRING Configuration,\r
1496 OUT EFI_STRING *Progress\r
a3bcde70
HT
1497 )\r
1498{\r
d1050b9d 1499 if ((This == NULL) || (Configuration == NULL) || (Progress == NULL)) {\r
a3bcde70
HT
1500 return EFI_INVALID_PARAMETER;\r
1501 }\r
1502\r
1503 //\r
1504 // Check routing data in <ConfigHdr>.\r
1505 // Note: if only one Storage is used, then this checking could be skipped.\r
1506 //\r
9bdc6592 1507 if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
a3bcde70
HT
1508 *Progress = Configuration;\r
1509 return EFI_NOT_FOUND;\r
1510 }\r
1511\r
1512 *Progress = Configuration + StrLen (Configuration);\r
1513\r
1514 return EFI_SUCCESS;\r
1515}\r
1516\r
130df890 1517/**\r
1518 Display host addresses, route table, DNS addresses and gateway addresses in\r
1519 "IPv6 Current Setting" page.\r
1520\r
1521 @param[in] Instance The IP6 config instance data.\r
1522\r
1523 @retval EFI_SUCCESS The operation finished successfully.\r
1524 @retval Others Other errors as indicated.\r
1525\r
1526**/\r
1527EFI_STATUS\r
1528Ip6GetCurrentSetting (\r
d1050b9d 1529 IN IP6_CONFIG_INSTANCE *Instance\r
130df890 1530 )\r
1531{\r
d1050b9d
MK
1532 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
1533 EFI_HII_HANDLE HiiHandle;\r
1534 EFI_IP6_CONFIG_INTERFACE_INFO *Data;\r
1535 UINTN DataSize;\r
1536 EFI_STATUS Status;\r
1537 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];\r
1538 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;\r
130df890 1539\r
1540 Ip6Config = &Instance->Ip6Config;\r
1541 HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
1542 Data = NULL;\r
1543\r
1544 //\r
1545 // Get current interface info.\r
1546 //\r
1547 Status = Ip6ConfigNvGetData (\r
1548 Ip6Config,\r
1549 Ip6ConfigDataTypeInterfaceInfo,\r
1550 &DataSize,\r
d1050b9d 1551 (VOID **)&Data\r
130df890 1552 );\r
1553 if (EFI_ERROR (Status)) {\r
1554 return Status;\r
1555 }\r
1556\r
1557 //\r
1558 // Generate dynamic text opcode for host address and draw it.\r
1559 //\r
d1050b9d 1560 IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *)Data;\r
130df890 1561 Status = Ip6ConvertAddressListToString (\r
1562 PortString,\r
1563 HiiHandle,\r
1564 Ip6ConfigNvHostAddress,\r
1565 IfInfo->AddressInfo,\r
1566 IfInfo->AddressInfoCount\r
1567 );\r
1568 if (EFI_ERROR (Status)) {\r
1569 FreePool (Data);\r
1570 return Status;\r
1571 }\r
1572\r
1573 //\r
1574 // Generate the dynamic text opcode for route table and draw it.\r
1575 //\r
1576 Status = Ip6ConvertAddressListToString (\r
1577 PortString,\r
1578 HiiHandle,\r
1579 Ip6ConfigNvRouteTable,\r
1580 IfInfo->RouteTable,\r
1581 IfInfo->RouteCount\r
1582 );\r
1583 if (EFI_ERROR (Status)) {\r
1584 FreePool (Data);\r
1585 return Status;\r
1586 }\r
1587\r
1588 //\r
1589 // Get DNS server list.\r
1590 //\r
1591 FreePool (Data);\r
1592 DataSize = 0;\r
d1050b9d
MK
1593 Data = NULL;\r
1594 Status = Ip6ConfigNvGetData (\r
1595 Ip6Config,\r
1596 Ip6ConfigDataTypeDnsServer,\r
1597 &DataSize,\r
1598 (VOID **)&Data\r
1599 );\r
130df890 1600 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
1601 if (Data != NULL) {\r
1602 FreePool (Data);\r
1603 }\r
d1050b9d 1604\r
130df890 1605 return Status;\r
1606 }\r
1607\r
1608 if (DataSize > 0) {\r
1609 //\r
1610 // Generate the dynamic text opcode for DNS server and draw it.\r
1611 //\r
1612 Status = Ip6ConvertAddressListToString (\r
1613 PortString,\r
1614 HiiHandle,\r
1615 Ip6ConfigNvDnsAddress,\r
1616 Data,\r
1617 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
1618 );\r
1619 if (EFI_ERROR (Status)) {\r
1620 FreePool (Data);\r
1621 return Status;\r
1622 }\r
1623 }\r
1624\r
1625 //\r
7de8045a 1626 // Get gateway address list.\r
130df890 1627 //\r
1628 if (Data != NULL) {\r
1629 FreePool (Data);\r
1630 }\r
1631\r
1632 DataSize = 0;\r
d1050b9d
MK
1633 Data = NULL;\r
1634 Status = Ip6ConfigNvGetData (\r
1635 Ip6Config,\r
1636 Ip6ConfigDataTypeGateway,\r
1637 &DataSize,\r
1638 (VOID **)&Data\r
1639 );\r
130df890 1640 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
1641 if (Data != NULL) {\r
1642 FreePool (Data);\r
1643 }\r
d1050b9d 1644\r
130df890 1645 return Status;\r
1646 }\r
1647\r
1648 if (DataSize > 0) {\r
1649 //\r
1650 // Generate the dynamic text opcode for gateway and draw it.\r
1651 //\r
1652 Status = Ip6ConvertAddressListToString (\r
1653 PortString,\r
1654 HiiHandle,\r
1655 Ip6ConfigNvGatewayAddress,\r
1656 Data,\r
1657 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
1658 );\r
1659 if (EFI_ERROR (Status)) {\r
1660 FreePool (Data);\r
1661 return Status;\r
1662 }\r
1663 }\r
1664\r
1665 if (Data != NULL) {\r
1666 FreePool (Data);\r
1667 }\r
1668\r
1669 return EFI_SUCCESS;\r
1670}\r
1671\r
a3bcde70
HT
1672/**\r
1673 This function is called to provide results data to the driver.\r
1674 This data consists of a unique key that is used to identify\r
1675 which data is either being passed back or being asked for.\r
1676\r
1677 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1678 @param[in] Action Specifies the type of action taken by the browser.\r
1679 @param[in] QuestionId A unique value which is sent to the original\r
1680 exporting driver so that it can identify the type\r
1681 of data to expect. The format of the data tends to\r
1682 vary based on the opcode that generated the callback.\r
1683 @param[in] Type The type of value for the question.\r
1684 @param[in] Value A pointer to the data being sent to the original\r
1685 exporting driver.\r
1686 @param[out] ActionRequest On return, points to the action requested by the\r
1687 callback function.\r
1688\r
1689 @retval EFI_SUCCESS The callback successfully handled the action.\r
1690 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
1691 variable and its data.\r
1692 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1693 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
1694 callback. Currently not implemented.\r
1695 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.\r
1696 @retval Others Other errors as indicated.\r
1697\r
1698**/\r
1699EFI_STATUS\r
1700EFIAPI\r
1701Ip6FormCallback (\r
d1050b9d
MK
1702 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1703 IN EFI_BROWSER_ACTION Action,\r
1704 IN EFI_QUESTION_ID QuestionId,\r
1705 IN UINT8 Type,\r
1706 IN EFI_IFR_TYPE_VALUE *Value,\r
1707 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
a3bcde70
HT
1708 )\r
1709{\r
d1050b9d
MK
1710 IP6_FORM_CALLBACK_INFO *Private;\r
1711 UINTN BufferSize;\r
1712 IP6_CONFIG_IFR_NVDATA *IfrNvData;\r
1713 EFI_STATUS Status;\r
1714 EFI_INPUT_KEY Key;\r
1715 IP6_CONFIG_INSTANCE *Instance;\r
1716 IP6_CONFIG_NVDATA *Ip6NvData;\r
a3bcde70
HT
1717\r
1718 if (This == NULL) {\r
1719 return EFI_INVALID_PARAMETER;\r
1720 }\r
1721\r
1722 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1723 Instance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1724 Ip6NvData = &Instance->Ip6NvData;\r
1725\r
d1050b9d 1726 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {\r
e0afa489 1727 return EFI_SUCCESS;\r
1728 }\r
1729\r
d1050b9d 1730 if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {\r
e0afa489 1731 return EFI_UNSUPPORTED;\r
1732 }\r
1733\r
1734 if ((Value == NULL) || (ActionRequest == NULL)) {\r
1735 return EFI_INVALID_PARAMETER;\r
1736 }\r
1737\r
1738 //\r
1739 // Retrieve uncommitted data from Browser\r
1740 //\r
1741\r
1742 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
d1050b9d 1743 IfrNvData = AllocateZeroPool (BufferSize);\r
e0afa489 1744 if (IfrNvData == NULL) {\r
1745 return EFI_OUT_OF_RESOURCES;\r
1746 }\r
1747\r
1748 Status = EFI_SUCCESS;\r
1749\r
d1050b9d 1750 HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData);\r
e0afa489 1751\r
639a76d1
ED
1752 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
1753 switch (QuestionId) {\r
d1050b9d
MK
1754 case KEY_GET_CURRENT_SETTING:\r
1755 Status = Ip6GetCurrentSetting (Instance);\r
1756 break;\r
639a76d1 1757\r
d1050b9d
MK
1758 default:\r
1759 break;\r
2d4df339 1760 }\r
639a76d1
ED
1761 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
1762 switch (QuestionId) {\r
d1050b9d
MK
1763 case KEY_SAVE_CONFIG_CHANGES:\r
1764 Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance);\r
1765 if (EFI_ERROR (Status)) {\r
1766 break;\r
1767 }\r
130df890 1768\r
d1050b9d 1769 Status = Ip6GetCurrentSetting (Instance);\r
130df890 1770\r
d1050b9d
MK
1771 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1772 break;\r
a3bcde70 1773\r
d1050b9d
MK
1774 case KEY_IGNORE_CONFIG_CHANGES:\r
1775 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);\r
1776 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);\r
1777 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);\r
0b2a54e2 1778\r
d1050b9d
MK
1779 Ip6NvData->ManualAddressCount = 0;\r
1780 Ip6NvData->GatewayAddressCount = 0;\r
1781 Ip6NvData->DnsAddressCount = 0;\r
0b2a54e2 1782\r
d1050b9d
MK
1783 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1784 break;\r
1785\r
1786 case KEY_SAVE_CHANGES:\r
1787 Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance);\r
1788 if (EFI_ERROR (Status)) {\r
1789 break;\r
1790 }\r
a3bcde70 1791\r
d1050b9d 1792 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
639a76d1 1793 break;\r
f75a7f56 1794\r
d1050b9d
MK
1795 case KEY_INTERFACE_ID:\r
1796 Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
1797 if (EFI_ERROR (Status)) {\r
1798 CreatePopUp (\r
1799 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1800 &Key,\r
1801 L"Invalid Interface ID!",\r
1802 NULL\r
1803 );\r
1804 }\r
f75a7f56 1805\r
d1050b9d 1806 break;\r
f75a7f56 1807\r
d1050b9d
MK
1808 case KEY_MANUAL_ADDRESS:\r
1809 Status = Ip6ParseAddressListFromString (\r
1810 IfrNvData->ManualAddress,\r
1811 &Ip6NvData->ManualAddress,\r
1812 &Ip6NvData->ManualAddressCount\r
1813 );\r
1814 if (EFI_ERROR (Status)) {\r
1815 CreatePopUp (\r
1816 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1817 &Key,\r
1818 L"Invalid Host Addresses!",\r
1819 NULL\r
1820 );\r
1821 }\r
f75a7f56 1822\r
d1050b9d 1823 break;\r
f75a7f56 1824\r
d1050b9d
MK
1825 case KEY_GATEWAY_ADDRESS:\r
1826 Status = Ip6ParseAddressListFromString (\r
1827 IfrNvData->GatewayAddress,\r
1828 &Ip6NvData->GatewayAddress,\r
1829 &Ip6NvData->GatewayAddressCount\r
1830 );\r
1831 if (EFI_ERROR (Status)) {\r
1832 CreatePopUp (\r
1833 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1834 &Key,\r
1835 L"Invalid Gateway Addresses!",\r
1836 NULL\r
1837 );\r
1838 }\r
f75a7f56 1839\r
d1050b9d 1840 break;\r
f75a7f56 1841\r
d1050b9d
MK
1842 case KEY_DNS_ADDRESS:\r
1843 Status = Ip6ParseAddressListFromString (\r
1844 IfrNvData->DnsAddress,\r
1845 &Ip6NvData->DnsAddress,\r
1846 &Ip6NvData->DnsAddressCount\r
1847 );\r
1848 if (EFI_ERROR (Status)) {\r
1849 CreatePopUp (\r
1850 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1851 &Key,\r
1852 L"Invalid DNS Addresses!",\r
1853 NULL\r
1854 );\r
1855 }\r
f75a7f56 1856\r
d1050b9d 1857 break;\r
a3bcde70 1858\r
d1050b9d
MK
1859 default:\r
1860 break;\r
639a76d1 1861 }\r
e0afa489 1862 }\r
a3bcde70 1863\r
e0afa489 1864 if (!EFI_ERROR (Status)) {\r
1865 //\r
1866 // Pass changed uncommitted data back to Form Browser.\r
1867 //\r
1868 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
d1050b9d 1869 HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData, NULL);\r
a3bcde70
HT
1870 }\r
1871\r
e0afa489 1872 FreePool (IfrNvData);\r
1873 return Status;\r
a3bcde70
HT
1874}\r
1875\r
1876/**\r
1877 Install HII Config Access protocol for network device and allocate resources.\r
1878\r
1879 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.\r
1880\r
1881 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
1882 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1883 @retval Others Other errors as indicated.\r
1884\r
1885**/\r
1886EFI_STATUS\r
1887Ip6ConfigFormInit (\r
d1050b9d 1888 IN OUT IP6_CONFIG_INSTANCE *Instance\r
a3bcde70
HT
1889 )\r
1890{\r
d1050b9d
MK
1891 EFI_STATUS Status;\r
1892 IP6_SERVICE *IpSb;\r
1893 IP6_FORM_CALLBACK_INFO *CallbackInfo;\r
1894 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
1895 VENDOR_DEVICE_PATH VendorDeviceNode;\r
1896 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
1897 CHAR16 *MacString;\r
1898 CHAR16 MenuString[128];\r
1899 CHAR16 PortString[128];\r
1900 CHAR16 *OldMenuString;\r
1901 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
a3bcde70
HT
1902\r
1903 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
1904 ASSERT (IpSb != NULL);\r
1905\r
1906 Status = gBS->HandleProtocol (\r
1907 IpSb->Controller,\r
1908 &gEfiDevicePathProtocolGuid,\r
d1050b9d 1909 (VOID **)&ParentDevicePath\r
a3bcde70
HT
1910 );\r
1911 if (EFI_ERROR (Status)) {\r
1912 return Status;\r
1913 }\r
1914\r
d1050b9d 1915 CallbackInfo = &Instance->CallbackInfo;\r
a3bcde70
HT
1916 CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE;\r
1917\r
1918 //\r
1919 // Construct device path node for EFI HII Config Access protocol,\r
1920 // which consists of controller physical device path and one hardware\r
1921 // vendor guid node.\r
1922 //\r
1923 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
1924 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
1925 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
1926\r
9bdc6592 1927 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);\r
a3bcde70
HT
1928\r
1929 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
1930 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
1931 ParentDevicePath,\r
d1050b9d 1932 (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode\r
a3bcde70
HT
1933 );\r
1934 if (CallbackInfo->HiiVendorDevicePath == NULL) {\r
1935 Status = EFI_OUT_OF_RESOURCES;\r
1936 goto Error;\r
1937 }\r
1938\r
1939 ConfigAccess = &CallbackInfo->HiiConfigAccess;\r
1940 ConfigAccess->ExtractConfig = Ip6FormExtractConfig;\r
1941 ConfigAccess->RouteConfig = Ip6FormRouteConfig;\r
1942 ConfigAccess->Callback = Ip6FormCallback;\r
1943\r
1944 //\r
1945 // Install Device Path Protocol and Config Access protocol on new handle\r
1946 //\r
1947 Status = gBS->InstallMultipleProtocolInterfaces (\r
1948 &CallbackInfo->ChildHandle,\r
1949 &gEfiDevicePathProtocolGuid,\r
1950 CallbackInfo->HiiVendorDevicePath,\r
1951 &gEfiHiiConfigAccessProtocolGuid,\r
1952 ConfigAccess,\r
1953 NULL\r
1954 );\r
1955 if (!EFI_ERROR (Status)) {\r
1956 //\r
1957 // Open the Parent Handle for the child\r
1958 //\r
1959 Status = gBS->OpenProtocol (\r
1960 IpSb->Controller,\r
1961 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
d1050b9d 1962 (VOID **)&MnpSb,\r
a3bcde70
HT
1963 IpSb->Image,\r
1964 CallbackInfo->ChildHandle,\r
1965 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1966 );\r
1967 }\r
1968\r
1969 if (EFI_ERROR (Status)) {\r
1970 goto Error;\r
1971 }\r
1972\r
1973 //\r
1974 // Publish our HII data\r
1975 //\r
1976 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
9bdc6592 1977 &gIp6ConfigNvDataGuid,\r
a3bcde70
HT
1978 CallbackInfo->ChildHandle,\r
1979 Ip6DxeStrings,\r
1980 Ip6ConfigBin,\r
1981 NULL\r
1982 );\r
1983 if (CallbackInfo->RegisteredHandle == NULL) {\r
1984 Status = EFI_OUT_OF_RESOURCES;\r
1985 goto Error;\r
1986 }\r
1987\r
1988 //\r
969ebd26 1989 // Append MAC string in the menu help string and tile help string\r
a3bcde70
HT
1990 //\r
1991 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);\r
1992 if (!EFI_ERROR (Status)) {\r
1993 OldMenuString = HiiGetString (\r
1994 CallbackInfo->RegisteredHandle,\r
e07404fe 1995 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),\r
d1050b9d
MK
1996 NULL\r
1997 )\r
1998 ;\r
a3bcde70
HT
1999 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
2000 HiiSetString (\r
2001 CallbackInfo->RegisteredHandle,\r
e07404fe 2002 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),\r
a3bcde70
HT
2003 MenuString,\r
2004 NULL\r
2005 );\r
2006 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
2007 HiiSetString (\r
2008 CallbackInfo->RegisteredHandle,\r
e07404fe 2009 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP),\r
a3bcde70
HT
2010 PortString,\r
2011 NULL\r
2012 );\r
2013\r
2014 FreePool (MacString);\r
2015 FreePool (OldMenuString);\r
2016\r
2017 InitializeListHead (&Instance->Ip6NvData.ManualAddress);\r
2018 InitializeListHead (&Instance->Ip6NvData.GatewayAddress);\r
2019 InitializeListHead (&Instance->Ip6NvData.DnsAddress);\r
2020\r
2021 return EFI_SUCCESS;\r
2022 }\r
2023\r
2024Error:\r
2025 Ip6ConfigFormUnload (Instance);\r
2026 return Status;\r
2027}\r
2028\r
2029/**\r
2030 Uninstall the HII Config Access protocol for network devices and free up the resources.\r
2031\r
2032 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.\r
2033\r
2034**/\r
2035VOID\r
2036Ip6ConfigFormUnload (\r
d1050b9d 2037 IN OUT IP6_CONFIG_INSTANCE *Instance\r
a3bcde70
HT
2038 )\r
2039{\r
d1050b9d
MK
2040 IP6_SERVICE *IpSb;\r
2041 IP6_FORM_CALLBACK_INFO *CallbackInfo;\r
2042 IP6_CONFIG_NVDATA *Ip6NvData;\r
a3bcde70
HT
2043\r
2044 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
2045 ASSERT (IpSb != NULL);\r
2046\r
2047 CallbackInfo = &Instance->CallbackInfo;\r
2048\r
2049 if (CallbackInfo->ChildHandle != NULL) {\r
a3bcde70
HT
2050 //\r
2051 // Close the child handle\r
2052 //\r
2053 gBS->CloseProtocol (\r
2054 IpSb->Controller,\r
2055 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
2056 IpSb->Image,\r
2057 CallbackInfo->ChildHandle\r
2058 );\r
2059 //\r
2060 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
2061 //\r
2062 gBS->UninstallMultipleProtocolInterfaces (\r
2063 CallbackInfo->ChildHandle,\r
2064 &gEfiDevicePathProtocolGuid,\r
2065 CallbackInfo->HiiVendorDevicePath,\r
2066 &gEfiHiiConfigAccessProtocolGuid,\r
2067 &CallbackInfo->HiiConfigAccess,\r
2068 NULL\r
2069 );\r
2070 }\r
2071\r
2072 if (CallbackInfo->HiiVendorDevicePath != NULL) {\r
2073 FreePool (CallbackInfo->HiiVendorDevicePath);\r
2074 }\r
2075\r
2076 if (CallbackInfo->RegisteredHandle != NULL) {\r
2077 //\r
2078 // Remove HII package list\r
2079 //\r
2080 HiiRemovePackages (CallbackInfo->RegisteredHandle);\r
2081 }\r
2082\r
2083 Ip6NvData = &Instance->Ip6NvData;\r
2084\r
2085 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);\r
2086 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);\r
2087 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);\r
2088\r
2089 Ip6NvData->ManualAddressCount = 0;\r
2090 Ip6NvData->GatewayAddressCount = 0;\r
2091 Ip6NvData->DnsAddressCount = 0;\r
2092}\r