]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c
Libraries and utilities for instrumenting regions of code and measuring their perform...
[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
c22b6cdf 4Copyright (c) 2009 - 2010, Intel Corporation.<BR>\r
63886849 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
63886849 155 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
156 NicConfig = AllocateZeroPool (ConfigLen);\r
157 ASSERT (NicConfig != NULL);\r
158 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, NicConfig);\r
159 if (!EFI_ERROR (Status)) {\r
c22b6cdf 160 IfrFormNvData->Configure = 1;\r
63886849 161 if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
162 IfrFormNvData->DhcpEnable = 1;\r
163 } else {\r
164 IfrFormNvData->DhcpEnable = 0;\r
165 Ip4ConfigIpToStr (&NicConfig->Ip4Info.StationAddress, IfrFormNvData->StationAddress);\r
166 Ip4ConfigIpToStr (&NicConfig->Ip4Info.SubnetMask, IfrFormNvData->SubnetMask);\r
167 Ip4ConfigIpToStr (&NicConfig->Ip4Info.RouteTable[1].GatewayAddress, IfrFormNvData->GatewayAddress);\r
168 }\r
c22b6cdf 169 } else {\r
170 IfrFormNvData->Configure = 0;\r
63886849 171 }\r
c22b6cdf 172\r
63886849 173 FreePool (NicConfig);\r
174}\r
175\r
176/**\r
d80ea739 177 Convert the IFR data into the network configuration data and set the IP\r
178 configure parameters for the NIC.\r
179\r
d80ea739 180 @param[in, out] Ip4ConfigInstance The IP4Config instance.\r
c22b6cdf 181\r
182 @retval EFI_SUCCESS The configure parameter for this NIC was\r
d80ea739 183 set successfully.\r
184 @retval EFI_ALREADY_STARTED There is a pending auto configuration.\r
185 @retval EFI_NOT_FOUND No auto configure parameter is found.\r
c22b6cdf 186\r
63886849 187**/\r
d80ea739 188EFI_STATUS\r
189Ip4ConfigConvertIfrNvDataToDeviceConfigData (\r
d80ea739 190 IN OUT IP4_CONFIG_INSTANCE *Ip4ConfigInstance\r
63886849 191 )\r
192{\r
c22b6cdf 193 EFI_STATUS Status;\r
d80ea739 194 EFI_IP_ADDRESS HostIp;\r
195 EFI_IP_ADDRESS SubnetMask;\r
196 EFI_IP_ADDRESS Gateway;\r
197 EFI_INPUT_KEY Key;\r
198 NIC_IP4_CONFIG_INFO *NicInfo;\r
199 EFI_IP_ADDRESS Ip;\r
63886849 200\r
c22b6cdf 201 if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured) {\r
202 //\r
203 // Clear the variable\r
204 //\r
205 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo, sizeof (IP4_SETTING_INFO));\r
206\r
207 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
208 if (Status == EFI_NOT_FOUND) {\r
209 return EFI_SUCCESS;\r
210 }\r
211\r
212 return Status;\r
213 }\r
214\r
d80ea739 215 NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE));\r
216 ASSERT (NicInfo != NULL);\r
63886849 217\r
d80ea739 218 NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1);\r
219\r
c22b6cdf 220 if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled) {\r
d80ea739 221 CopyMem (&HostIp.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (HostIp.v4));\r
222 CopyMem (&SubnetMask.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (SubnetMask.v4));\r
223 CopyMem (&Gateway.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (Gateway.v4));\r
224\r
c22b6cdf 225 if (!NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
226 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
227 return EFI_INVALID_PARAMETER;\r
228 }\r
229 if (EFI_IP4_EQUAL (&SubnetMask, &mZeroIp4Addr)) {\r
230 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);\r
231 return EFI_INVALID_PARAMETER;\r
232 }\r
233\r
d80ea739 234 if ((Gateway.Addr[0] != 0)) {\r
235 if (SubnetMask.Addr[0] == 0) {\r
236 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
237 return EFI_INVALID_PARAMETER;\r
238\r
239 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
240 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
241 return EFI_INVALID_PARAMETER; }\r
63886849 242 }\r
243\r
d80ea739 244 NicInfo->Source = IP4_CONFIG_SOURCE_STATIC;\r
245 NicInfo->Ip4Info.RouteTableSize = 2;\r
246\r
247 CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
248 CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
249\r
250 Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0];\r
251\r
252 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));\r
253 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
254 CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
c22b6cdf 255\r
d80ea739 256 } else {\r
257 NicInfo->Source = IP4_CONFIG_SOURCE_DHCP;\r
c22b6cdf 258 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
259 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
260 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (EFI_IPv4_ADDRESS));\r
63886849 261 }\r
262\r
d80ea739 263 NicInfo->Perment = TRUE;\r
264 CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR));\r
265\r
266 return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
63886849 267}\r
268\r
269/**\r
270 This function allows the caller to request the current\r
271 configuration for one or more named elements. The resulting\r
272 string is in <ConfigAltResp> format. Any and all alternative\r
273 configuration strings shall also be appended to the end of the\r
274 current configuration string. If they are, they must appear\r
275 after the current configuration. They must contain the same\r
276 routing (GUID, NAME, PATH) as the current configuration string.\r
277 They must have an additional description indicating the type of\r
278 alternative configuration the string represents,\r
279 "ALTCFG=<StringToken>". That <StringToken> (when\r
280 converted from Hex UNICODE to binary) is a reference to a\r
281 string in the associated string pack.\r
282\r
283 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
284 @param[in] Request A null-terminated Unicode string in\r
285 <ConfigRequest> format. Note that this\r
286 includes the routing information as well as\r
287 the configurable name / value pairs. It is\r
288 invalid for this string to be in\r
289 <MultiConfigRequest> format.\r
290 @param[out] Progress On return, points to a character in the\r
291 Request string. Points to the string's null\r
292 terminator if request was successful. Points\r
293 to the most recent "&" before the first\r
294 failing name / value pair (or the beginning\r
295 of the string if the failure is in the first\r
296 name / value pair) if the request was not\r
297 successful.\r
298 @param[out] Results A null-terminated Unicode string in\r
299 <ConfigAltResp> format which has all values\r
300 filled in for the names in the Request string.\r
301 String to be allocated by the called function.\r
302\r
303 @retval EFI_SUCCESS The Results string is filled with the\r
304 values corresponding to all requested\r
305 names.\r
306 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
307 parts of the results that must be\r
308 stored awaiting possible future\r
309 protocols.\r
63886849 310 @retval EFI_NOT_FOUND Routing data doesn't match any\r
311 known driver. Progress set to the\r
312 first character in the routing header.\r
313 Note: There is no requirement that the\r
314 driver validate the routing data. It\r
315 must skip the <ConfigHdr> in order to\r
316 process the names.\r
317 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
318 to most recent & before the\r
319 error or the beginning of the\r
320 string.\r
321 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
322 to the & before the name in\r
323 question.Currently not implemented.\r
324**/\r
325EFI_STATUS\r
326EFIAPI\r
327Ip4DeviceExtractConfig (\r
328 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
329 IN CONST EFI_STRING Request,\r
330 OUT EFI_STRING *Progress,\r
331 OUT EFI_STRING *Results\r
332 )\r
333{\r
334 EFI_STATUS Status;\r
335 UINTN ConfigLen;\r
336 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
63886849 337 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
d80ea739 338 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
59aefb7e
LG
339 EFI_STRING ConfigRequestHdr;\r
340 EFI_STRING ConfigRequest;\r
341 EFI_STRING DeviceResult;\r
342 EFI_STRING FormResult;\r
343 CHAR16 *StrPointer;\r
344 BOOLEAN AllocatedRequest;\r
345 UINTN Size;\r
346 UINTN BufferSize;\r
347\r
348 if (Progress == NULL || Results == NULL) {\r
63886849 349 return EFI_INVALID_PARAMETER;\r
350 }\r
351\r
59aefb7e
LG
352 *Progress = Request;\r
353 Size = 0;\r
354 DeviceResult = NULL;\r
355 FormResult = NULL;\r
356 ConfigRequest = NULL;\r
357 Status = EFI_SUCCESS;\r
358 AllocatedRequest = FALSE;\r
d80ea739 359 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
360\r
391a0724 361 //\r
362 // Check Request data in <ConfigHdr>.\r
363 //\r
59aefb7e 364 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
d80ea739 365 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
366 if (IfrDeviceNvData == NULL) {\r
367 return EFI_OUT_OF_RESOURCES;\r
368 }\r
391a0724 369\r
d80ea739 370 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
371 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, IfrDeviceNvData);\r
372 if (EFI_ERROR (Status)) {\r
373 FreePool (IfrDeviceNvData);\r
374 return EFI_NOT_FOUND;\r
375 }\r
c22b6cdf 376\r
59aefb7e
LG
377 ConfigRequest = Request;\r
378 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
379 //\r
380 // Request has no request element, construct full request string.\r
381 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
382 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
383 //\r
384 ConfigRequestHdr = HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, Ip4ConfigInstance->ChildHandle);\r
385 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
386 ConfigRequest = AllocateZeroPool (Size);\r
387 ASSERT (ConfigRequest != NULL);\r
388 AllocatedRequest = TRUE;\r
389 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
390 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
391 FreePool (ConfigRequestHdr);\r
392 }\r
393\r
d80ea739 394 //\r
395 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
396 //\r
397 Status = gHiiConfigRouting->BlockToConfig (\r
398 gHiiConfigRouting,\r
59aefb7e 399 ConfigRequest,\r
d80ea739 400 (UINT8 *) IfrDeviceNvData,\r
401 NIC_ITEM_CONFIG_SIZE,\r
59aefb7e 402 &DeviceResult,\r
d80ea739 403 Progress\r
404 );\r
c22b6cdf 405\r
d80ea739 406 FreePool (IfrDeviceNvData);\r
59aefb7e
LG
407 //\r
408 // Free the allocated config request string.\r
409 //\r
410 if (AllocatedRequest) {\r
411 FreePool (ConfigRequest);\r
412 ConfigRequest = NULL;\r
413 }\r
63886849 414\r
59aefb7e
LG
415 if (EFI_ERROR (Status)) {\r
416 goto Failure;\r
417 }\r
418 } \r
419 \r
420 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
63886849 421\r
d80ea739 422 IfrFormNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
423 if (IfrFormNvData == NULL) {\r
424 return EFI_OUT_OF_RESOURCES;\r
425 }\r
c22b6cdf 426\r
d80ea739 427 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance, IfrFormNvData);\r
c22b6cdf 428\r
59aefb7e
LG
429 ConfigRequest = Request;\r
430 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
431 //\r
432 // Request has no request element, construct full request string.\r
433 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
434 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
435 //\r
436 ConfigRequestHdr = HiiConstructConfigHdr (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, Ip4ConfigInstance->ChildHandle);\r
437 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
438 ConfigRequest = AllocateZeroPool (Size);\r
439 ASSERT (ConfigRequest != NULL);\r
440 AllocatedRequest = TRUE;\r
441 BufferSize = sizeof (IP4_CONFIG_IFR_NVDATA);\r
442 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
443 FreePool (ConfigRequestHdr);\r
444 }\r
445 \r
d80ea739 446 //\r
447 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
448 //\r
449 Status = gHiiConfigRouting->BlockToConfig (\r
450 gHiiConfigRouting,\r
59aefb7e 451 ConfigRequest,\r
d80ea739 452 (UINT8 *) IfrFormNvData,\r
453 sizeof (IP4_CONFIG_IFR_NVDATA),\r
59aefb7e 454 &FormResult,\r
d80ea739 455 Progress\r
456 );\r
c22b6cdf 457\r
d80ea739 458 FreePool (IfrFormNvData);\r
59aefb7e
LG
459 //\r
460 // Free the allocated config request string.\r
461 //\r
462 if (AllocatedRequest) {\r
463 FreePool (ConfigRequest);\r
464 ConfigRequest = NULL;\r
465 }\r
466\r
467 if (EFI_ERROR (Status)) {\r
468 goto Failure;\r
469 }\r
470 }\r
d80ea739 471\r
59aefb7e
LG
472 if (Request == NULL) {\r
473 Size = StrLen (DeviceResult);\r
474 Size = Size + 1;\r
475 Size = Size + StrLen (FormResult) + 1;\r
476 *Results = AllocateZeroPool (Size * sizeof (CHAR16));\r
477 ASSERT (*Results != NULL);\r
478 StrPointer = *Results;\r
479 StrCpy (StrPointer, DeviceResult);\r
480 StrPointer = StrPointer + StrLen (StrPointer);\r
481 *StrPointer = L'&';\r
482 StrCpy (StrPointer + 1, FormResult);\r
483 FreePool (DeviceResult);\r
484 FreePool (FormResult);\r
b26fc8d8 485 } else if (HiiIsConfigHdrMatch (Request, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
59aefb7e 486 *Results = DeviceResult;\r
b26fc8d8 487 } else if (HiiIsConfigHdrMatch (Request, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
59aefb7e 488 *Results = FormResult;\r
d80ea739 489 } else {\r
63886849 490 return EFI_NOT_FOUND;\r
491 }\r
492\r
59aefb7e
LG
493Failure:\r
494 //\r
495 // Set Progress string to the original request string.\r
496 //\r
497 if (Request == NULL) {\r
498 *Progress = NULL;\r
499 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
500 *Progress = Request + StrLen (Request);\r
501 }\r
502 \r
63886849 503 return Status;\r
504}\r
505\r
506/**\r
507 This function applies changes in a driver's configuration.\r
508 Input is a Configuration, which has the routing data for this\r
509 driver followed by name / value configuration pairs. The driver\r
510 must apply those pairs to its configurable storage. If the\r
511 driver's configuration is stored in a linear block of data\r
512 and the driver's name / value pairs are in <BlockConfig>\r
513 format, it may use the ConfigToBlock helper function (above) to\r
514 simplify the job. Currently not implemented.\r
515\r
516 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
517 @param[in] Configuration A null-terminated Unicode string in\r
518 <ConfigString> format.\r
519 @param[out] Progress A pointer to a string filled in with the\r
520 offset of the most recent '&' before the\r
521 first failing name / value pair (or the\r
522 beginn ing of the string if the failure\r
523 is in the first name / value pair) or\r
524 the terminating NULL if all was\r
525 successful.\r
526\r
527 @retval EFI_SUCCESS The results have been distributed or are\r
528 awaiting distribution.\r
529 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
530 parts of the results that must be\r
531 stored awaiting possible future\r
532 protocols.\r
533 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
534 Results parameter would result\r
535 in this type of error.\r
536 @retval EFI_NOT_FOUND Target for the specified routing data\r
537 was not found.\r
538**/\r
539EFI_STATUS\r
540EFIAPI\r
541Ip4DeviceRouteConfig (\r
542 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
543 IN CONST EFI_STRING Configuration,\r
544 OUT EFI_STRING *Progress\r
545 )\r
546{\r
547 EFI_STATUS Status;\r
548 UINTN BufferSize;\r
549 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
c22b6cdf 550 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
391a0724 551 NIC_IP4_CONFIG_INFO *NicInfo;\r
63886849 552 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
553 EFI_MAC_ADDRESS ZeroMac;\r
554\r
d80ea739 555 if (Configuration == NULL || Progress == NULL) {\r
63886849 556 return EFI_INVALID_PARAMETER;\r
557 }\r
558\r
559 *Progress = Configuration;\r
560\r
d80ea739 561 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
63886849 562\r
563 //\r
d80ea739 564 // Check Routing data in <ConfigHdr>.\r
63886849 565 //\r
d80ea739 566 if (HiiIsConfigHdrMatch (Configuration, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
567 //\r
568 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
569 //\r
570 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
571 if (IfrFormNvData == NULL) {\r
572 return EFI_OUT_OF_RESOURCES;\r
63886849 573 }\r
63886849 574\r
d80ea739 575 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
576 Status = gHiiConfigRouting->ConfigToBlock (\r
577 gHiiConfigRouting,\r
578 Configuration,\r
579 (UINT8 *) IfrFormNvData,\r
580 &BufferSize,\r
581 Progress\r
582 );\r
583 if (!EFI_ERROR (Status)) {\r
c22b6cdf 584 Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance);\r
d80ea739 585 }\r
c22b6cdf 586\r
d80ea739 587 FreePool (IfrFormNvData);\r
63886849 588\r
d80ea739 589 } else if (HiiIsConfigHdrMatch (Configuration, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
63886849 590\r
d80ea739 591 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
592 if (IfrDeviceNvData == NULL) {\r
593 return EFI_OUT_OF_RESOURCES;\r
594 }\r
63886849 595\r
d80ea739 596 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
597 Status = gHiiConfigRouting->ConfigToBlock (\r
598 gHiiConfigRouting,\r
599 Configuration,\r
600 (UINT8 *) IfrDeviceNvData,\r
601 &BufferSize,\r
602 Progress\r
603 );\r
604 if (!EFI_ERROR (Status)) {\r
605 ZeroMem (&ZeroMac, sizeof (EFI_MAC_ADDRESS));\r
606 if (CompareMem (&IfrDeviceNvData->NicAddr.MacAddr, &ZeroMac, IfrDeviceNvData->NicAddr.Len) != 0) {\r
607 BufferSize = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * IfrDeviceNvData->Ip4Info.RouteTableSize;\r
c22b6cdf 608 NicInfo = AllocateCopyPool (BufferSize, IfrDeviceNvData);\r
d80ea739 609 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
610 } else {\r
c22b6cdf 611 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo, sizeof (IP4_SETTING_INFO));\r
d80ea739 612 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
613 }\r
614 }\r
63886849 615\r
d80ea739 616 FreePool (IfrDeviceNvData);\r
63886849 617\r
d80ea739 618 } else {\r
ae79d2f9 619\r
ae79d2f9
LG
620 return EFI_NOT_FOUND;\r
621 }\r
c22b6cdf 622\r
d80ea739 623 return Status;\r
ae79d2f9 624\r
63886849 625}\r
626\r
627/**\r
628 This function is called to provide results data to the driver.\r
629 This data consists of a unique key that is used to identify\r
630 which data is either being passed back or being asked for.\r
631\r
632 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
633 @param[in] Action Specifies the type of action taken by the browser.\r
634 @param[in] QuestionId A unique value which is sent to the original\r
635 exporting driver so that it can identify the type\r
636 of data to expect. The format of the data tends to\r
637 vary based on the opcode that enerated the callback.\r
638 @param[in] Type The type of value for the question.\r
639 @param[in] Value A pointer to the data being sent to the original\r
640 exporting driver.\r
641 @param[out] ActionRequest On return, points to the action requested by the\r
642 callback function.\r
643\r
644 @retval EFI_SUCCESS The callback successfully handled the action.\r
645 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
646 variable and its data.\r
647 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
648 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
649 callback.Currently not implemented.\r
650 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
651 @retval Others Other errors as indicated.\r
652**/\r
653EFI_STATUS\r
654EFIAPI\r
655Ip4FormCallback (\r
656 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
657 IN EFI_BROWSER_ACTION Action,\r
658 IN EFI_QUESTION_ID QuestionId,\r
659 IN UINT8 Type,\r
660 IN EFI_IFR_TYPE_VALUE *Value,\r
661 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
662 )\r
663{\r
664 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
63886849 665 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
63886849 666 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
63886849 667 EFI_IP_ADDRESS HostIp;\r
668 EFI_IP_ADDRESS SubnetMask;\r
669 EFI_IP_ADDRESS Gateway;\r
670 EFI_STATUS Status;\r
671 EFI_INPUT_KEY Key;\r
63886849 672\r
d80ea739 673 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
63886849 674\r
675 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
676 if (IfrFormNvData == NULL) {\r
677 return EFI_OUT_OF_RESOURCES;\r
678 }\r
679\r
680 //\r
681 // Retrive uncommitted data from Browser\r
682 //\r
d80ea739 683 if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {\r
63886849 684 FreePool (IfrFormNvData);\r
685 return EFI_NOT_FOUND;\r
686 }\r
687\r
688 Status = EFI_SUCCESS;\r
689\r
690 switch (QuestionId) {\r
691\r
c22b6cdf 692 case KEY_ENABLE:\r
693 if (IfrFormNvData->Configure == 0) {\r
694 Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = FALSE;\r
695 } else {\r
696 Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = TRUE;\r
697 }\r
698 break;\r
699\r
63886849 700 case KEY_DHCP_ENABLE:\r
701 if (IfrFormNvData->DhcpEnable == 0) {\r
c22b6cdf 702 Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = FALSE;\r
63886849 703 } else {\r
c22b6cdf 704 Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = TRUE;\r
63886849 705 }\r
706\r
707 break;\r
708\r
709 case KEY_LOCAL_IP:\r
710 UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String);\r
711 Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4);\r
f6b7393c 712 if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
63886849 713 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
714 Status = EFI_INVALID_PARAMETER;\r
715 } else {\r
d80ea739 716 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
63886849 717 }\r
718\r
719 break;\r
720\r
721 case KEY_SUBNET_MASK:\r
722 UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String);\r
723 Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4);\r
724 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
725 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL);\r
726 Status = EFI_INVALID_PARAMETER;\r
727 } else {\r
d80ea739 728 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
63886849 729 }\r
730\r
731 break;\r
732\r
733 case KEY_GATE_WAY:\r
734 UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String);\r
735 Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4);\r
f6b7393c 736 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
63886849 737 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
738 Status = EFI_INVALID_PARAMETER;\r
739 } else {\r
d80ea739 740 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
63886849 741 }\r
742\r
743 break;\r
744\r
745 case KEY_SAVE_CHANGES:\r
c22b6cdf 746\r
747 Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance);\r
748\r
63886849 749 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
d80ea739 750\r
63886849 751 break;\r
752\r
753 default:\r
c22b6cdf 754\r
63886849 755 break;\r
756 }\r
757\r
758 if (!EFI_ERROR (Status)) {\r
63886849 759 //\r
760 // Pass changed uncommitted data back to Form Browser\r
761 //\r
762 HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL);\r
763 }\r
764\r
765 FreePool (IfrFormNvData);\r
d80ea739 766\r
63886849 767 return Status;\r
768}\r
769\r
770/**\r
771 Install HII Config Access protocol for network device and allocate resource.\r
772\r
773 @param[in] Instance The IP4 Config instance.\r
774\r
775 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
776 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
777 @retval Others Other errors as indicated.\r
778**/\r
779EFI_STATUS\r
780Ip4ConfigDeviceInit (\r
d80ea739 781 IN IP4_CONFIG_INSTANCE *Instance\r
63886849 782 )\r
783{\r
d80ea739 784 EFI_STATUS Status;\r
785 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
786 VENDOR_DEVICE_PATH VendorDeviceNode;\r
787 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
788 CHAR16 *MacString;\r
789 CHAR16 MenuString[128];\r
790 CHAR16 PortString[128];\r
791 CHAR16 *OldMenuString;\r
63886849 792\r
d80ea739 793 ConfigAccess = &Instance->HiiConfigAccessProtocol;\r
794 ConfigAccess->ExtractConfig = Ip4DeviceExtractConfig;\r
795 ConfigAccess->RouteConfig = Ip4DeviceRouteConfig;\r
796 ConfigAccess->Callback = Ip4FormCallback;\r
63886849 797\r
d80ea739 798 //\r
799 // Construct device path node for EFI HII Config Access protocol,\r
800 // which consists of controller physical device path and one hardware\r
801 // vendor guid node.\r
802 //\r
803 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
804 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
805 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
63886849 806\r
d80ea739 807 CopyGuid (&VendorDeviceNode.Guid, &gEfiNicIp4ConfigVariableGuid);\r
63886849 808\r
d80ea739 809 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
810 Instance->HiiVendorDevicePath = AppendDevicePathNode (\r
811 Instance->ParentDevicePath,\r
812 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode\r
813 );\r
63886849 814\r
d80ea739 815 Instance->ChildHandle = NULL;\r
63886849 816 //\r
d80ea739 817 // Install Device Path Protocol and Config Access protocol on new handle\r
63886849 818 //\r
819 Status = gBS->InstallMultipleProtocolInterfaces (\r
d80ea739 820 &Instance->ChildHandle,\r
821 &gEfiDevicePathProtocolGuid,\r
c22b6cdf 822 Instance->HiiVendorDevicePath,\r
63886849 823 &gEfiHiiConfigAccessProtocolGuid,\r
d80ea739 824 ConfigAccess,\r
63886849 825 NULL\r
826 );\r
d80ea739 827 if (!EFI_ERROR (Status)) {\r
828 //\r
829 // Open the Parent Handle for the child\r
830 //\r
831 Status = gBS->OpenProtocol (\r
832 Instance->Controller,\r
833 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
834 (VOID **) &MnpSb,\r
835 Instance->Image,\r
c22b6cdf 836 Instance->ChildHandle,\r
d80ea739 837 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
838 );\r
839 }\r
840\r
63886849 841 ASSERT_EFI_ERROR (Status);\r
c22b6cdf 842\r
d80ea739 843 //\r
844 // Publish our HII data\r
845 //\r
846 Instance->RegisteredHandle = HiiAddPackages (\r
847 &mNicIp4ConfigNvDataGuid,\r
848 Instance->ChildHandle,\r
849 Ip4ConfigDxeStrings,\r
850 Ip4ConfigDxeBin,\r
851 NULL\r
852 );\r
853 if (Instance->RegisteredHandle == NULL) {\r
854 return EFI_OUT_OF_RESOURCES;\r
855 }\r
856\r
857 //\r
858 // Append MAC string in the menu string and tile string\r
859 //\r
860 Status = NetLibGetMacString (Instance->Controller, Instance->Image, &MacString);\r
861 if (!EFI_ERROR (Status)) {\r
862 OldMenuString = HiiGetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_CONFIG_FORM_TITLE), NULL);\r
863 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
864 HiiSetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_CONFIG_FORM_TITLE), MenuString, NULL);\r
c22b6cdf 865\r
d80ea739 866 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
867 HiiSetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_DEVICE_FORM_TITLE), PortString, NULL);\r
868 FreePool (MacString);\r
869 }\r
63886849 870\r
871 return Status;\r
872}\r
873\r
874/**\r
875 Uninstall HII Config Access protocol for network device and free resource.\r
876\r
877 @param[in] Instance The IP4 Config instance.\r
878\r
879 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.\r
880 @retval Others Other errors as indicated.\r
881**/\r
882EFI_STATUS\r
883Ip4ConfigDeviceUnload (\r
884 IN IP4_CONFIG_INSTANCE *Instance\r
885 )\r
886{\r
63886849 887 //\r
d80ea739 888 // Remove HII package list\r
63886849 889 //\r
d80ea739 890 HiiRemovePackages (Instance->RegisteredHandle);\r
63886849 891\r
892 //\r
d80ea739 893 // Close the child handle\r
63886849 894 //\r
d80ea739 895 gBS->CloseProtocol (\r
896 Instance->Controller,\r
897 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
898 Instance->Image,\r
899 Instance->ChildHandle\r
900 );\r
63886849 901\r
902 //\r
903 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
904 //\r
905 gBS->UninstallMultipleProtocolInterfaces (\r
d80ea739 906 Instance->ChildHandle,\r
63886849 907 &gEfiDevicePathProtocolGuid,\r
c22b6cdf 908 Instance->HiiVendorDevicePath,\r
63886849 909 &gEfiHiiConfigAccessProtocolGuid,\r
d80ea739 910 &Instance->HiiConfigAccessProtocol,\r
63886849 911 NULL\r
912 );\r
913\r
63886849 914 return EFI_SUCCESS;\r
915}\r