]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c
Minor code enhancement.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4ConfigNv.c
CommitLineData
63886849 1/** @file\r
2 Helper functions for configuring or getting the parameters relating to Ip4.\r
3\r
4Copyright (c) 2009, Intel Corporation.<BR>\r
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
8http://opensource.org/licenses/bsd-license.php\r
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
13**/\r
14\r
15#include "Ip4ConfigNv.h"\r
16\r
d80ea739 17EFI_GUID mNicIp4ConfigNvDataGuid = EFI_NIC_IP4_CONFIG_NVDATA_GUID;\r
63886849 18\r
63886849 19\r
20/**\r
21 Calculate the prefix length of the IPv4 subnet mask.\r
22\r
23 @param[in] SubnetMask The IPv4 subnet mask.\r
24\r
25 @return The prefix length of the subnet mask.\r
26 @retval 0 Other errors as indicated.\r
27**/\r
28UINT8\r
29GetSubnetMaskPrefixLength (\r
30 IN EFI_IPv4_ADDRESS *SubnetMask\r
31 )\r
32{\r
33 UINT8 Len;\r
34 UINT32 ReverseMask;\r
35\r
36 //\r
37 // The SubnetMask is in network byte order.\r
38 //\r
39 ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);\r
40\r
41 //\r
42 // Reverse it.\r
43 //\r
44 ReverseMask = ~ReverseMask;\r
45\r
46 if ((ReverseMask & (ReverseMask + 1)) != 0) {\r
47 return 0;\r
48 }\r
49\r
50 Len = 0;\r
51\r
52 while (ReverseMask != 0) {\r
53 ReverseMask = ReverseMask >> 1;\r
54 Len++;\r
55 }\r
56\r
57 return (UINT8) (32 - Len);\r
58}\r
59\r
60/**\r
61 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
62\r
63 @param[in] Str The UNICODE string.\r
64 @param[out] Ip The storage to return the ASCII string.\r
65\r
66 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
67 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
68**/\r
69EFI_STATUS\r
70Ip4AsciiStrToIp (\r
71 IN CHAR8 *Str,\r
72 OUT EFI_IPv4_ADDRESS *Ip\r
73 )\r
74{\r
75 UINTN Index;\r
76 UINTN Number;\r
77\r
78 Index = 0;\r
79\r
80 while (*Str != 0) {\r
81\r
82 if (Index > 3) {\r
83 return EFI_INVALID_PARAMETER;\r
84 }\r
85\r
86 Number = 0;\r
87 while (NET_IS_DIGIT (*Str)) {\r
88 Number = Number * 10 + (*Str - '0');\r
89 Str++;\r
90 }\r
91\r
92 if (Number > 0xFF) {\r
93 return EFI_INVALID_PARAMETER;\r
94 }\r
95\r
96 Ip->Addr[Index] = (UINT8) Number;\r
97\r
98 if ((*Str != '\0') && (*Str != '.')) {\r
99 //\r
100 // The current character should be either the NULL terminator or\r
101 // the dot delimiter.\r
102 //\r
103 return EFI_INVALID_PARAMETER;\r
104 }\r
105\r
106 if (*Str == '.') {\r
107 //\r
108 // Skip the delimiter.\r
109 //\r
110 Str++;\r
111 }\r
112\r
113 Index++;\r
114 }\r
115\r
116 if (Index != 4) {\r
117 return EFI_INVALID_PARAMETER;\r
118 }\r
119\r
120 return EFI_SUCCESS;\r
121}\r
122\r
123/**\r
124 Convert the IPv4 address into a dotted string.\r
125\r
126 @param[in] Ip The IPv4 address.\r
127 @param[out] Str The dotted IP string.\r
128**/\r
129VOID\r
130Ip4ConfigIpToStr (\r
131 IN EFI_IPv4_ADDRESS *Ip,\r
132 OUT CHAR16 *Str\r
133 )\r
134{\r
135 UnicodeSPrint (Str, 2 * IP4_STR_MAX_SIZE, L"%d.%d.%d.%d", Ip->Addr[0], Ip->Addr[1], Ip->Addr[2], Ip->Addr[3]);\r
136}\r
137\r
138\r
139/**\r
140 Convert the network configuration data into the IFR data.\r
141\r
f6b7393c 142 @param[in] Ip4ConfigInstance The IP4Config instance\r
143 @param[out] IfrFormNvData The IFR nv data.\r
63886849 144**/\r
145VOID\r
146Ip4ConfigConvertDeviceConfigDataToIfrNvData (\r
147 IN IP4_CONFIG_INSTANCE *Ip4ConfigInstance,\r
148 OUT IP4_CONFIG_IFR_NVDATA *IfrFormNvData\r
149 )\r
150{\r
151 EFI_STATUS Status;\r
152 NIC_IP4_CONFIG_INFO *NicConfig;\r
153 UINTN ConfigLen;\r
154\r
155 IfrFormNvData->DhcpEnable = 1;\r
156\r
157 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
158 NicConfig = AllocateZeroPool (ConfigLen);\r
159 ASSERT (NicConfig != NULL);\r
160 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, NicConfig);\r
161 if (!EFI_ERROR (Status)) {\r
162 if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
163 IfrFormNvData->DhcpEnable = 1;\r
164 } else {\r
165 IfrFormNvData->DhcpEnable = 0;\r
166 Ip4ConfigIpToStr (&NicConfig->Ip4Info.StationAddress, IfrFormNvData->StationAddress);\r
167 Ip4ConfigIpToStr (&NicConfig->Ip4Info.SubnetMask, IfrFormNvData->SubnetMask);\r
168 Ip4ConfigIpToStr (&NicConfig->Ip4Info.RouteTable[1].GatewayAddress, IfrFormNvData->GatewayAddress);\r
169 }\r
170 }\r
171 FreePool (NicConfig);\r
172}\r
173\r
174/**\r
d80ea739 175 Convert the IFR data into the network configuration data and set the IP\r
176 configure parameters for the NIC.\r
177\r
178 @param[in] IfrFormNvData The IFR nv data.\r
179 @param[in, out] Ip4ConfigInstance The IP4Config instance.\r
180 \r
181 @retval EFI_SUCCESS The configure parameter for this NIC was \r
182 set successfully.\r
183 @retval EFI_ALREADY_STARTED There is a pending auto configuration.\r
184 @retval EFI_NOT_FOUND No auto configure parameter is found.\r
185 \r
63886849 186**/\r
d80ea739 187EFI_STATUS\r
188Ip4ConfigConvertIfrNvDataToDeviceConfigData (\r
189 IN IP4_CONFIG_IFR_NVDATA *IfrFormNvData,\r
190 IN OUT IP4_CONFIG_INSTANCE *Ip4ConfigInstance\r
63886849 191 )\r
192{\r
d80ea739 193 EFI_IP_ADDRESS HostIp;\r
194 EFI_IP_ADDRESS SubnetMask;\r
195 EFI_IP_ADDRESS Gateway;\r
196 EFI_INPUT_KEY Key;\r
197 NIC_IP4_CONFIG_INFO *NicInfo;\r
198 EFI_IP_ADDRESS Ip;\r
63886849 199\r
d80ea739 200 NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE));\r
201 ASSERT (NicInfo != NULL);\r
63886849 202\r
d80ea739 203 NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1);\r
204\r
205 if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.Enabled) {\r
206 CopyMem (&HostIp.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (HostIp.v4));\r
207 CopyMem (&SubnetMask.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (SubnetMask.v4));\r
208 CopyMem (&Gateway.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (Gateway.v4));\r
209\r
210 if ((Gateway.Addr[0] != 0)) {\r
211 if (SubnetMask.Addr[0] == 0) {\r
212 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
213 return EFI_INVALID_PARAMETER;\r
214\r
215 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
216 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
217 return EFI_INVALID_PARAMETER; }\r
63886849 218 }\r
219\r
d80ea739 220 NicInfo->Source = IP4_CONFIG_SOURCE_STATIC;\r
221 NicInfo->Ip4Info.RouteTableSize = 2;\r
222\r
223 CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
224 CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
225\r
226 Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0];\r
227\r
228 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));\r
229 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
230 CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
231 } else {\r
232 NicInfo->Source = IP4_CONFIG_SOURCE_DHCP;\r
63886849 233 }\r
234\r
d80ea739 235 NicInfo->Perment = TRUE;\r
236 CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR));\r
237\r
238 return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
63886849 239}\r
240\r
241/**\r
242 This function allows the caller to request the current\r
243 configuration for one or more named elements. The resulting\r
244 string is in <ConfigAltResp> format. Any and all alternative\r
245 configuration strings shall also be appended to the end of the\r
246 current configuration string. If they are, they must appear\r
247 after the current configuration. They must contain the same\r
248 routing (GUID, NAME, PATH) as the current configuration string.\r
249 They must have an additional description indicating the type of\r
250 alternative configuration the string represents,\r
251 "ALTCFG=<StringToken>". That <StringToken> (when\r
252 converted from Hex UNICODE to binary) is a reference to a\r
253 string in the associated string pack.\r
254\r
255 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
256 @param[in] Request A null-terminated Unicode string in\r
257 <ConfigRequest> format. Note that this\r
258 includes the routing information as well as\r
259 the configurable name / value pairs. It is\r
260 invalid for this string to be in\r
261 <MultiConfigRequest> format.\r
262 @param[out] Progress On return, points to a character in the\r
263 Request string. Points to the string's null\r
264 terminator if request was successful. Points\r
265 to the most recent "&" before the first\r
266 failing name / value pair (or the beginning\r
267 of the string if the failure is in the first\r
268 name / value pair) if the request was not\r
269 successful.\r
270 @param[out] Results A null-terminated Unicode string in\r
271 <ConfigAltResp> format which has all values\r
272 filled in for the names in the Request string.\r
273 String to be allocated by the called function.\r
274\r
275 @retval EFI_SUCCESS The Results string is filled with the\r
276 values corresponding to all requested\r
277 names.\r
278 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
279 parts of the results that must be\r
280 stored awaiting possible future\r
281 protocols.\r
282 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
283 for the Request parameter\r
284 would result in this type of\r
285 error. In this case, the\r
286 Progress parameter would be\r
287 set to NULL.\r
288 @retval EFI_NOT_FOUND Routing data doesn't match any\r
289 known driver. Progress set to the\r
290 first character in the routing header.\r
291 Note: There is no requirement that the\r
292 driver validate the routing data. It\r
293 must skip the <ConfigHdr> in order to\r
294 process the names.\r
295 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
296 to most recent & before the\r
297 error or the beginning of the\r
298 string.\r
299 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
300 to the & before the name in\r
301 question.Currently not implemented.\r
302**/\r
303EFI_STATUS\r
304EFIAPI\r
305Ip4DeviceExtractConfig (\r
306 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
307 IN CONST EFI_STRING Request,\r
308 OUT EFI_STRING *Progress,\r
309 OUT EFI_STRING *Results\r
310 )\r
311{\r
312 EFI_STATUS Status;\r
313 UINTN ConfigLen;\r
314 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
63886849 315 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
d80ea739 316 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
63886849 317\r
d80ea739 318 if (Request == NULL || Progress == NULL || Results == NULL) {\r
63886849 319 return EFI_INVALID_PARAMETER;\r
320 }\r
321\r
322 *Progress = Request;\r
323\r
d80ea739 324 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
325\r
391a0724 326 //\r
327 // Check Request data in <ConfigHdr>.\r
328 //\r
d80ea739 329 if (HiiIsConfigHdrMatch (Request, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
330 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
331 if (IfrDeviceNvData == NULL) {\r
332 return EFI_OUT_OF_RESOURCES;\r
333 }\r
391a0724 334\r
d80ea739 335 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
336 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, IfrDeviceNvData);\r
337 if (EFI_ERROR (Status)) {\r
338 FreePool (IfrDeviceNvData);\r
339 return EFI_NOT_FOUND;\r
340 }\r
341 \r
342 //\r
343 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
344 //\r
345 Status = gHiiConfigRouting->BlockToConfig (\r
346 gHiiConfigRouting,\r
347 Request,\r
348 (UINT8 *) IfrDeviceNvData,\r
349 NIC_ITEM_CONFIG_SIZE,\r
350 Results,\r
351 Progress\r
352 );\r
353 \r
354 FreePool (IfrDeviceNvData);\r
63886849 355\r
d80ea739 356 } else if (HiiIsConfigHdrMatch (Request, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
63886849 357\r
d80ea739 358 IfrFormNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
359 if (IfrFormNvData == NULL) {\r
360 return EFI_OUT_OF_RESOURCES;\r
361 }\r
362 \r
363 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance, IfrFormNvData);\r
364 \r
365 //\r
366 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
367 //\r
368 Status = gHiiConfigRouting->BlockToConfig (\r
369 gHiiConfigRouting,\r
370 Request,\r
371 (UINT8 *) IfrFormNvData,\r
372 sizeof (IP4_CONFIG_IFR_NVDATA),\r
373 Results,\r
374 Progress\r
375 );\r
376 \r
377 FreePool (IfrFormNvData);\r
378\r
379 } else {\r
63886849 380 return EFI_NOT_FOUND;\r
381 }\r
382\r
63886849 383\r
384 return Status;\r
385}\r
386\r
387/**\r
388 This function applies changes in a driver's configuration.\r
389 Input is a Configuration, which has the routing data for this\r
390 driver followed by name / value configuration pairs. The driver\r
391 must apply those pairs to its configurable storage. If the\r
392 driver's configuration is stored in a linear block of data\r
393 and the driver's name / value pairs are in <BlockConfig>\r
394 format, it may use the ConfigToBlock helper function (above) to\r
395 simplify the job. Currently not implemented.\r
396\r
397 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
398 @param[in] Configuration A null-terminated Unicode string in\r
399 <ConfigString> format.\r
400 @param[out] Progress A pointer to a string filled in with the\r
401 offset of the most recent '&' before the\r
402 first failing name / value pair (or the\r
403 beginn ing of the string if the failure\r
404 is in the first name / value pair) or\r
405 the terminating NULL if all was\r
406 successful.\r
407\r
408 @retval EFI_SUCCESS The results have been distributed or are\r
409 awaiting distribution.\r
410 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
411 parts of the results that must be\r
412 stored awaiting possible future\r
413 protocols.\r
414 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
415 Results parameter would result\r
416 in this type of error.\r
417 @retval EFI_NOT_FOUND Target for the specified routing data\r
418 was not found.\r
419**/\r
420EFI_STATUS\r
421EFIAPI\r
422Ip4DeviceRouteConfig (\r
423 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
424 IN CONST EFI_STRING Configuration,\r
425 OUT EFI_STRING *Progress\r
426 )\r
427{\r
428 EFI_STATUS Status;\r
429 UINTN BufferSize;\r
430 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
d80ea739 431 IP4_CONFIG_IFR_NVDATA *IfrFormNvData; \r
391a0724 432 NIC_IP4_CONFIG_INFO *NicInfo;\r
63886849 433 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
434 EFI_MAC_ADDRESS ZeroMac;\r
435\r
d80ea739 436 if (Configuration == NULL || Progress == NULL) {\r
63886849 437 return EFI_INVALID_PARAMETER;\r
438 }\r
439\r
440 *Progress = Configuration;\r
441\r
d80ea739 442 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
63886849 443\r
444 //\r
d80ea739 445 // Check Routing data in <ConfigHdr>.\r
63886849 446 //\r
d80ea739 447 if (HiiIsConfigHdrMatch (Configuration, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
448 //\r
449 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
450 //\r
451 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
452 if (IfrFormNvData == NULL) {\r
453 return EFI_OUT_OF_RESOURCES;\r
63886849 454 }\r
63886849 455\r
d80ea739 456 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
457 Status = gHiiConfigRouting->ConfigToBlock (\r
458 gHiiConfigRouting,\r
459 Configuration,\r
460 (UINT8 *) IfrFormNvData,\r
461 &BufferSize,\r
462 Progress\r
463 );\r
464 if (!EFI_ERROR (Status)) {\r
465 Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (IfrFormNvData, Ip4ConfigInstance);\r
466 }\r
467 \r
468 FreePool (IfrFormNvData);\r
63886849 469\r
d80ea739 470 } else if (HiiIsConfigHdrMatch (Configuration, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
63886849 471\r
d80ea739 472 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
473 if (IfrDeviceNvData == NULL) {\r
474 return EFI_OUT_OF_RESOURCES;\r
475 }\r
63886849 476\r
d80ea739 477 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
478 Status = gHiiConfigRouting->ConfigToBlock (\r
479 gHiiConfigRouting,\r
480 Configuration,\r
481 (UINT8 *) IfrDeviceNvData,\r
482 &BufferSize,\r
483 Progress\r
484 );\r
485 if (!EFI_ERROR (Status)) {\r
486 ZeroMem (&ZeroMac, sizeof (EFI_MAC_ADDRESS));\r
487 if (CompareMem (&IfrDeviceNvData->NicAddr.MacAddr, &ZeroMac, IfrDeviceNvData->NicAddr.Len) != 0) {\r
488 BufferSize = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * IfrDeviceNvData->Ip4Info.RouteTableSize;\r
489 NicInfo = AllocateCopyPool (BufferSize, IfrDeviceNvData); \r
490 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
491 } else {\r
492 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
493 }\r
494 }\r
63886849 495\r
d80ea739 496 FreePool (IfrDeviceNvData);\r
63886849 497\r
d80ea739 498 } else {\r
ae79d2f9 499\r
ae79d2f9
LG
500 return EFI_NOT_FOUND;\r
501 }\r
d80ea739 502 \r
503 return Status;\r
ae79d2f9 504\r
63886849 505}\r
506\r
507/**\r
508 This function is called to provide results data to the driver.\r
509 This data consists of a unique key that is used to identify\r
510 which data is either being passed back or being asked for.\r
511\r
512 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
513 @param[in] Action Specifies the type of action taken by the browser.\r
514 @param[in] QuestionId A unique value which is sent to the original\r
515 exporting driver so that it can identify the type\r
516 of data to expect. The format of the data tends to\r
517 vary based on the opcode that enerated the callback.\r
518 @param[in] Type The type of value for the question.\r
519 @param[in] Value A pointer to the data being sent to the original\r
520 exporting driver.\r
521 @param[out] ActionRequest On return, points to the action requested by the\r
522 callback function.\r
523\r
524 @retval EFI_SUCCESS The callback successfully handled the action.\r
525 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
526 variable and its data.\r
527 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
528 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
529 callback.Currently not implemented.\r
530 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
531 @retval Others Other errors as indicated.\r
532**/\r
533EFI_STATUS\r
534EFIAPI\r
535Ip4FormCallback (\r
536 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
537 IN EFI_BROWSER_ACTION Action,\r
538 IN EFI_QUESTION_ID QuestionId,\r
539 IN UINT8 Type,\r
540 IN EFI_IFR_TYPE_VALUE *Value,\r
541 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
542 )\r
543{\r
544 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
63886849 545 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
63886849 546 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
63886849 547 EFI_IP_ADDRESS HostIp;\r
548 EFI_IP_ADDRESS SubnetMask;\r
549 EFI_IP_ADDRESS Gateway;\r
550 EFI_STATUS Status;\r
551 EFI_INPUT_KEY Key;\r
63886849 552\r
d80ea739 553 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
63886849 554\r
555 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
556 if (IfrFormNvData == NULL) {\r
557 return EFI_OUT_OF_RESOURCES;\r
558 }\r
559\r
560 //\r
561 // Retrive uncommitted data from Browser\r
562 //\r
d80ea739 563 if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {\r
63886849 564 FreePool (IfrFormNvData);\r
565 return EFI_NOT_FOUND;\r
566 }\r
567\r
568 Status = EFI_SUCCESS;\r
569\r
570 switch (QuestionId) {\r
571\r
572 case KEY_DHCP_ENABLE:\r
573 if (IfrFormNvData->DhcpEnable == 0) {\r
d80ea739 574 Ip4ConfigInstance->Ip4ConfigCallbackInfo.Enabled = FALSE;\r
63886849 575 } else {\r
d80ea739 576 Ip4ConfigInstance->Ip4ConfigCallbackInfo.Enabled = TRUE;\r
63886849 577 }\r
578\r
579 break;\r
580\r
581 case KEY_LOCAL_IP:\r
582 UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String);\r
583 Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4);\r
f6b7393c 584 if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
63886849 585 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
586 Status = EFI_INVALID_PARAMETER;\r
587 } else {\r
d80ea739 588 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
63886849 589 }\r
590\r
591 break;\r
592\r
593 case KEY_SUBNET_MASK:\r
594 UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String);\r
595 Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4);\r
596 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
597 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL);\r
598 Status = EFI_INVALID_PARAMETER;\r
599 } else {\r
d80ea739 600 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
63886849 601 }\r
602\r
603 break;\r
604\r
605 case KEY_GATE_WAY:\r
606 UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String);\r
607 Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4);\r
f6b7393c 608 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
63886849 609 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
610 Status = EFI_INVALID_PARAMETER;\r
611 } else {\r
d80ea739 612 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
63886849 613 }\r
614\r
615 break;\r
616\r
617 case KEY_SAVE_CHANGES:\r
d80ea739 618 Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (IfrFormNvData, Ip4ConfigInstance);\r
619 \r
63886849 620 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
d80ea739 621\r
63886849 622 break;\r
623\r
624 default:\r
d80ea739 625 \r
63886849 626 break;\r
627 }\r
628\r
629 if (!EFI_ERROR (Status)) {\r
63886849 630 //\r
631 // Pass changed uncommitted data back to Form Browser\r
632 //\r
633 HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL);\r
634 }\r
635\r
636 FreePool (IfrFormNvData);\r
d80ea739 637\r
63886849 638 return Status;\r
639}\r
640\r
641/**\r
642 Install HII Config Access protocol for network device and allocate resource.\r
643\r
644 @param[in] Instance The IP4 Config instance.\r
645\r
646 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
647 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
648 @retval Others Other errors as indicated.\r
649**/\r
650EFI_STATUS\r
651Ip4ConfigDeviceInit (\r
d80ea739 652 IN IP4_CONFIG_INSTANCE *Instance\r
63886849 653 )\r
654{\r
d80ea739 655 EFI_STATUS Status;\r
656 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
657 VENDOR_DEVICE_PATH VendorDeviceNode;\r
658 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
659 CHAR16 *MacString;\r
660 CHAR16 MenuString[128];\r
661 CHAR16 PortString[128];\r
662 CHAR16 *OldMenuString;\r
63886849 663\r
d80ea739 664 ConfigAccess = &Instance->HiiConfigAccessProtocol;\r
665 ConfigAccess->ExtractConfig = Ip4DeviceExtractConfig;\r
666 ConfigAccess->RouteConfig = Ip4DeviceRouteConfig;\r
667 ConfigAccess->Callback = Ip4FormCallback;\r
63886849 668\r
d80ea739 669 //\r
670 // Construct device path node for EFI HII Config Access protocol,\r
671 // which consists of controller physical device path and one hardware\r
672 // vendor guid node.\r
673 //\r
674 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
675 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
676 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
63886849 677\r
d80ea739 678 CopyGuid (&VendorDeviceNode.Guid, &gEfiNicIp4ConfigVariableGuid);\r
63886849 679\r
d80ea739 680 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
681 Instance->HiiVendorDevicePath = AppendDevicePathNode (\r
682 Instance->ParentDevicePath,\r
683 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode\r
684 );\r
63886849 685\r
d80ea739 686 Instance->ChildHandle = NULL;\r
63886849 687 //\r
d80ea739 688 // Install Device Path Protocol and Config Access protocol on new handle\r
63886849 689 //\r
690 Status = gBS->InstallMultipleProtocolInterfaces (\r
d80ea739 691 &Instance->ChildHandle,\r
692 &gEfiDevicePathProtocolGuid,\r
693 Instance->HiiVendorDevicePath, \r
63886849 694 &gEfiHiiConfigAccessProtocolGuid,\r
d80ea739 695 ConfigAccess,\r
63886849 696 NULL\r
697 );\r
d80ea739 698 if (!EFI_ERROR (Status)) {\r
699 //\r
700 // Open the Parent Handle for the child\r
701 //\r
702 Status = gBS->OpenProtocol (\r
703 Instance->Controller,\r
704 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
705 (VOID **) &MnpSb,\r
706 Instance->Image,\r
707 Instance->ChildHandle, \r
708 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
709 );\r
710 }\r
711\r
63886849 712 ASSERT_EFI_ERROR (Status);\r
d80ea739 713 \r
714 //\r
715 // Publish our HII data\r
716 //\r
717 Instance->RegisteredHandle = HiiAddPackages (\r
718 &mNicIp4ConfigNvDataGuid,\r
719 Instance->ChildHandle,\r
720 Ip4ConfigDxeStrings,\r
721 Ip4ConfigDxeBin,\r
722 NULL\r
723 );\r
724 if (Instance->RegisteredHandle == NULL) {\r
725 return EFI_OUT_OF_RESOURCES;\r
726 }\r
727\r
728 //\r
729 // Append MAC string in the menu string and tile string\r
730 //\r
731 Status = NetLibGetMacString (Instance->Controller, Instance->Image, &MacString);\r
732 if (!EFI_ERROR (Status)) {\r
733 OldMenuString = HiiGetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_CONFIG_FORM_TITLE), NULL);\r
734 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
735 HiiSetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_CONFIG_FORM_TITLE), MenuString, NULL);\r
736 \r
737 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
738 HiiSetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_DEVICE_FORM_TITLE), PortString, NULL);\r
739 FreePool (MacString);\r
740 }\r
63886849 741\r
742 return Status;\r
743}\r
744\r
745/**\r
746 Uninstall HII Config Access protocol for network device and free resource.\r
747\r
748 @param[in] Instance The IP4 Config instance.\r
749\r
750 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.\r
751 @retval Others Other errors as indicated.\r
752**/\r
753EFI_STATUS\r
754Ip4ConfigDeviceUnload (\r
755 IN IP4_CONFIG_INSTANCE *Instance\r
756 )\r
757{\r
63886849 758 //\r
d80ea739 759 // Remove HII package list\r
63886849 760 //\r
d80ea739 761 HiiRemovePackages (Instance->RegisteredHandle);\r
63886849 762\r
763 //\r
d80ea739 764 // Close the child handle\r
63886849 765 //\r
d80ea739 766 gBS->CloseProtocol (\r
767 Instance->Controller,\r
768 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
769 Instance->Image,\r
770 Instance->ChildHandle\r
771 );\r
63886849 772\r
773 //\r
774 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
775 //\r
776 gBS->UninstallMultipleProtocolInterfaces (\r
d80ea739 777 Instance->ChildHandle,\r
63886849 778 &gEfiDevicePathProtocolGuid,\r
d80ea739 779 Instance->HiiVendorDevicePath, \r
63886849 780 &gEfiHiiConfigAccessProtocolGuid,\r
d80ea739 781 &Instance->HiiConfigAccessProtocol,\r
63886849 782 NULL\r
783 );\r
784\r
63886849 785 return EFI_SUCCESS;\r
786}\r