2 Helper functions for configuring or getting the parameters relating to Ip4.
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "Ip4ConfigNv.h"
16 #include "NicIp4Variable.h"
18 EFI_GUID mNicIp4ConfigNvDataGuid
= EFI_NIC_IP4_CONFIG_NVDATA_GUID
;
22 Calculate the prefix length of the IPv4 subnet mask.
24 @param[in] SubnetMask The IPv4 subnet mask.
26 @return The prefix length of the subnet mask.
27 @retval 0 Other errors as indicated.
30 GetSubnetMaskPrefixLength (
31 IN EFI_IPv4_ADDRESS
*SubnetMask
38 // The SubnetMask is in network byte order.
40 ReverseMask
= SwapBytes32 (*(UINT32
*)&SubnetMask
[0]);
45 ReverseMask
= ~ReverseMask
;
47 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
53 while (ReverseMask
!= 0) {
54 ReverseMask
= ReverseMask
>> 1;
58 return (UINT8
) (32 - Len
);
62 Convert the decimal dotted IPv4 address into the binary IPv4 address.
64 @param[in] Str The UNICODE string.
65 @param[out] Ip The storage to return the IPv4 address.
67 @retval EFI_SUCCESS The binary IP address is returned in Ip.
68 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
73 OUT EFI_IPv4_ADDRESS
*Ip
81 while (*Str
!= L
'\0') {
84 return EFI_INVALID_PARAMETER
;
88 while ((*Str
>= L
'0') && (*Str
<= L
'9')) {
89 Number
= Number
* 10 + (*Str
- L
'0');
94 return EFI_INVALID_PARAMETER
;
97 Ip
->Addr
[Index
] = (UINT8
) Number
;
99 if ((*Str
!= L
'\0') && (*Str
!= L
'.')) {
101 // The current character should be either the NULL terminator or
102 // the dot delimiter.
104 return EFI_INVALID_PARAMETER
;
109 // Skip the delimiter.
118 return EFI_INVALID_PARAMETER
;
125 Convert the IPv4 address into a dotted string.
127 @param[in] Ip The IPv4 address.
128 @param[out] Str The dotted IP string.
132 IN EFI_IPv4_ADDRESS
*Ip
,
136 UnicodeSPrint (Str
, 2 * IP4_STR_MAX_SIZE
, L
"%d.%d.%d.%d", Ip
->Addr
[0], Ip
->Addr
[1], Ip
->Addr
[2], Ip
->Addr
[3]);
141 Convert the network configuration data into the IFR data.
143 @param[in] Ip4ConfigInstance The IP4Config instance
144 @param[out] IfrFormNvData The IFR nv data.
147 Ip4ConfigConvertDeviceConfigDataToIfrNvData (
148 IN IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
,
149 OUT IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
152 NIC_IP4_CONFIG_INFO
*NicConfig
;
154 NicConfig
= EfiNicIp4ConfigGetInfo (Ip4ConfigInstance
);
155 if (NicConfig
!= NULL
) {
156 IfrFormNvData
->Configure
= 1;
157 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
= TRUE
;
158 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
) {
159 IfrFormNvData
->DhcpEnable
= 1;
160 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
= TRUE
;
162 IfrFormNvData
->DhcpEnable
= 0;
163 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.StationAddress
, IfrFormNvData
->StationAddress
);
164 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.SubnetMask
, IfrFormNvData
->SubnetMask
);
165 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.RouteTable
[1].GatewayAddress
, IfrFormNvData
->GatewayAddress
);
167 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
= FALSE
;
168 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, &NicConfig
->Ip4Info
.StationAddress
, sizeof (EFI_IPv4_ADDRESS
));
169 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, &NicConfig
->Ip4Info
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
170 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, &NicConfig
->Ip4Info
.RouteTable
[1].GatewayAddress
, sizeof (EFI_IPv4_ADDRESS
));
173 FreePool (NicConfig
);
175 IfrFormNvData
->Configure
= 0;
176 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
= FALSE
;
181 Convert the IFR data into the network configuration data and set the IP
182 configure parameters for the NIC.
184 @param[in] IfrFormNvData The IFR NV data.
185 @param[in, out] Ip4ConfigInstance The IP4Config instance.
187 @retval EFI_SUCCESS The configure parameter for this NIC was
189 @retval EFI_ALREADY_STARTED There is a pending auto configuration.
190 @retval EFI_NOT_FOUND No auto configure parameter is found.
194 Ip4ConfigConvertIfrNvDataToDeviceConfigData (
195 IN IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
,
196 IN OUT IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
200 EFI_IP_ADDRESS HostIp
;
201 EFI_IP_ADDRESS SubnetMask
;
202 EFI_IP_ADDRESS Gateway
;
204 NIC_IP4_CONFIG_INFO
*NicInfo
;
207 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
, sizeof (IP4_SETTING_INFO
));
209 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
= IfrFormNvData
->Configure
;
210 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
= IfrFormNvData
->DhcpEnable
;
211 Ip4StrToIp (IfrFormNvData
->StationAddress
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
);
212 Ip4StrToIp (IfrFormNvData
->SubnetMask
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
);
213 Ip4StrToIp (IfrFormNvData
->GatewayAddress
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
);
215 if (!Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
) {
217 // Clear the variable
219 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
, sizeof (IP4_SETTING_INFO
));
221 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NULL
, TRUE
);
222 if (Status
== EFI_NOT_FOUND
) {
229 NicInfo
= AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO
) + 2 * sizeof (EFI_IP4_ROUTE_TABLE
));
230 ASSERT (NicInfo
!= NULL
);
232 NicInfo
->Ip4Info
.RouteTable
= (EFI_IP4_ROUTE_TABLE
*) (NicInfo
+ 1);
234 if (!Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
) {
235 CopyMem (&HostIp
.v4
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, sizeof (HostIp
.v4
));
236 CopyMem (&SubnetMask
.v4
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, sizeof (SubnetMask
.v4
));
237 CopyMem (&Gateway
.v4
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, sizeof (Gateway
.v4
));
239 if (!NetIp4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
240 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
241 return EFI_INVALID_PARAMETER
;
243 if (EFI_IP4_EQUAL (&SubnetMask
, &mZeroIp4Addr
)) {
244 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
245 return EFI_INVALID_PARAMETER
;
248 if ((Gateway
.Addr
[0] != 0)) {
249 if (SubnetMask
.Addr
[0] == 0) {
250 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Gateway address is set but subnet mask is zero.", NULL
);
251 return EFI_INVALID_PARAMETER
;
253 } else if (!IP4_NET_EQUAL (HostIp
.Addr
[0], Gateway
.Addr
[0], SubnetMask
.Addr
[0])) {
254 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Local IP and Gateway are not in the same subnet.", NULL
);
255 return EFI_INVALID_PARAMETER
; }
258 NicInfo
->Source
= IP4_CONFIG_SOURCE_STATIC
;
259 NicInfo
->Ip4Info
.RouteTableSize
= 2;
261 CopyMem (&NicInfo
->Ip4Info
.StationAddress
, &HostIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
262 CopyMem (&NicInfo
->Ip4Info
.SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
264 Ip
.Addr
[0] = HostIp
.Addr
[0] & SubnetMask
.Addr
[0];
266 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[0].SubnetAddress
, &Ip
.v4
, sizeof (EFI_IPv4_ADDRESS
));
267 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[0].SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
268 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[1].GatewayAddress
, &Gateway
.v4
, sizeof (EFI_IPv4_ADDRESS
));
271 NicInfo
->Source
= IP4_CONFIG_SOURCE_DHCP
;
272 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
273 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
274 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, sizeof (EFI_IPv4_ADDRESS
));
277 NicInfo
->Perment
= TRUE
;
278 CopyMem (&NicInfo
->NicAddr
, &Ip4ConfigInstance
->NicAddr
, sizeof (NIC_ADDR
));
280 return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NicInfo
, TRUE
);
284 This function allows the caller to request the current
285 configuration for one or more named elements. The resulting
286 string is in <ConfigAltResp> format. Any and all alternative
287 configuration strings shall also be appended to the end of the
288 current configuration string. If they are, they must appear
289 after the current configuration. They must contain the same
290 routing (GUID, NAME, PATH) as the current configuration string.
291 They must have an additional description indicating the type of
292 alternative configuration the string represents,
293 "ALTCFG=<StringToken>". That <StringToken> (when
294 converted from Hex UNICODE to binary) is a reference to a
295 string in the associated string pack.
297 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
298 @param[in] Request A null-terminated Unicode string in
299 <ConfigRequest> format. Note that this
300 includes the routing information as well as
301 the configurable name / value pairs. It is
302 invalid for this string to be in
303 <MultiConfigRequest> format.
304 @param[out] Progress On return, points to a character in the
305 Request string. Points to the string's null
306 terminator if request was successful. Points
307 to the most recent "&" before the first
308 failing name / value pair (or the beginning
309 of the string if the failure is in the first
310 name / value pair) if the request was not
312 @param[out] Results A null-terminated Unicode string in
313 <ConfigAltResp> format which has all values
314 filled in for the names in the Request string.
315 String to be allocated by the called function.
317 @retval EFI_SUCCESS The Results string is filled with the
318 values corresponding to all requested
320 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
321 parts of the results that must be
322 stored awaiting possible future
324 @retval EFI_NOT_FOUND Routing data doesn't match any
325 known driver. Progress set to the
326 first character in the routing header.
327 Note: There is no requirement that the
328 driver validate the routing data. It
329 must skip the <ConfigHdr> in order to
331 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
332 to most recent & before the
333 error or the beginning of the
335 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
336 to the & before the name in
337 question.Currently not implemented.
341 Ip4DeviceExtractConfig (
342 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
343 IN CONST EFI_STRING Request
,
344 OUT EFI_STRING
*Progress
,
345 OUT EFI_STRING
*Results
349 NIC_IP4_CONFIG_INFO
*IfrDeviceNvData
;
350 NIC_IP4_CONFIG_INFO
*NicConfig
;
351 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
352 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
353 EFI_STRING ConfigRequestHdr
;
354 EFI_STRING ConfigRequest
;
355 EFI_STRING DeviceResult
;
356 EFI_STRING FormResult
;
358 BOOLEAN AllocatedRequest
;
362 if (Progress
== NULL
|| Results
== NULL
) {
363 return EFI_INVALID_PARAMETER
;
370 ConfigRequest
= NULL
;
371 Status
= EFI_SUCCESS
;
372 AllocatedRequest
= FALSE
;
373 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This
);
376 // Check Request data in <ConfigHdr>.
378 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
379 IfrDeviceNvData
= AllocateZeroPool (NIC_ITEM_CONFIG_SIZE
);
380 if (IfrDeviceNvData
== NULL
) {
381 return EFI_OUT_OF_RESOURCES
;
384 NicConfig
= EfiNicIp4ConfigGetInfo (Ip4ConfigInstance
);
385 if (NicConfig
== NULL
) {
386 return EFI_NOT_FOUND
;
388 CopyMem (IfrDeviceNvData
, NicConfig
, SIZEOF_NIC_IP4_CONFIG_INFO (NicConfig
));
389 FreePool (NicConfig
);
391 ConfigRequest
= Request
;
392 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
394 // Request has no request element, construct full request string.
395 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
396 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
398 ConfigRequestHdr
= HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, Ip4ConfigInstance
->ChildHandle
);
399 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
400 ConfigRequest
= AllocateZeroPool (Size
);
401 ASSERT (ConfigRequest
!= NULL
);
402 AllocatedRequest
= TRUE
;
403 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
404 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
405 FreePool (ConfigRequestHdr
);
409 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
411 Status
= gHiiConfigRouting
->BlockToConfig (
414 (UINT8
*) IfrDeviceNvData
,
415 NIC_ITEM_CONFIG_SIZE
,
420 FreePool (IfrDeviceNvData
);
422 // Free the allocated config request string.
424 if (AllocatedRequest
) {
425 FreePool (ConfigRequest
);
426 ConfigRequest
= NULL
;
429 if (EFI_ERROR (Status
)) {
434 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &mNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
436 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
437 if (IfrFormNvData
== NULL
) {
438 return EFI_OUT_OF_RESOURCES
;
441 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance
, IfrFormNvData
);
443 ConfigRequest
= Request
;
444 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
446 // Request has no request element, construct full request string.
447 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
448 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
450 ConfigRequestHdr
= HiiConstructConfigHdr (&mNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, Ip4ConfigInstance
->ChildHandle
);
451 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
452 ConfigRequest
= AllocateZeroPool (Size
);
453 ASSERT (ConfigRequest
!= NULL
);
454 AllocatedRequest
= TRUE
;
455 BufferSize
= sizeof (IP4_CONFIG_IFR_NVDATA
);
456 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
457 FreePool (ConfigRequestHdr
);
461 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
463 Status
= gHiiConfigRouting
->BlockToConfig (
466 (UINT8
*) IfrFormNvData
,
467 sizeof (IP4_CONFIG_IFR_NVDATA
),
472 FreePool (IfrFormNvData
);
474 // Free the allocated config request string.
476 if (AllocatedRequest
) {
477 FreePool (ConfigRequest
);
478 ConfigRequest
= NULL
;
481 if (EFI_ERROR (Status
)) {
486 if (Request
== NULL
) {
487 Size
= StrLen (DeviceResult
);
489 Size
= Size
+ StrLen (FormResult
) + 1;
490 *Results
= AllocateZeroPool (Size
* sizeof (CHAR16
));
491 ASSERT (*Results
!= NULL
);
492 StrPointer
= *Results
;
493 StrCpy (StrPointer
, DeviceResult
);
494 StrPointer
= StrPointer
+ StrLen (StrPointer
);
496 StrCpy (StrPointer
+ 1, FormResult
);
497 FreePool (DeviceResult
);
498 FreePool (FormResult
);
499 } else if (HiiIsConfigHdrMatch (Request
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
500 *Results
= DeviceResult
;
501 } else if (HiiIsConfigHdrMatch (Request
, &mNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
502 *Results
= FormResult
;
504 return EFI_NOT_FOUND
;
509 // Set Progress string to the original request string.
511 if (Request
== NULL
) {
513 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
514 *Progress
= Request
+ StrLen (Request
);
521 This function applies changes in a driver's configuration.
522 Input is a Configuration, which has the routing data for this
523 driver followed by name / value configuration pairs. The driver
524 must apply those pairs to its configurable storage. If the
525 driver's configuration is stored in a linear block of data
526 and the driver's name / value pairs are in <BlockConfig>
527 format, it may use the ConfigToBlock helper function (above) to
528 simplify the job. Currently not implemented.
530 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
531 @param[in] Configuration A null-terminated Unicode string in
532 <ConfigString> format.
533 @param[out] Progress A pointer to a string filled in with the
534 offset of the most recent '&' before the
535 first failing name / value pair (or the
536 beginn ing of the string if the failure
537 is in the first name / value pair) or
538 the terminating NULL if all was
541 @retval EFI_SUCCESS The results have been distributed or are
542 awaiting distribution.
543 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
544 parts of the results that must be
545 stored awaiting possible future
547 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
548 Results parameter would result
549 in this type of error.
550 @retval EFI_NOT_FOUND Target for the specified routing data
555 Ip4DeviceRouteConfig (
556 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
557 IN CONST EFI_STRING Configuration
,
558 OUT EFI_STRING
*Progress
563 NIC_IP4_CONFIG_INFO
*IfrDeviceNvData
;
564 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
565 NIC_IP4_CONFIG_INFO
*NicInfo
;
566 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
567 EFI_MAC_ADDRESS ZeroMac
;
569 if (Configuration
== NULL
|| Progress
== NULL
) {
570 return EFI_INVALID_PARAMETER
;
574 // Reclaim Ip4Config variable
576 Ip4ConfigReclaimVariable ();
578 *Progress
= Configuration
;
580 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This
);
583 // Check Routing data in <ConfigHdr>.
585 if (HiiIsConfigHdrMatch (Configuration
, &mNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
587 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
589 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
590 if (IfrFormNvData
== NULL
) {
591 return EFI_OUT_OF_RESOURCES
;
594 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
595 Status
= gHiiConfigRouting
->ConfigToBlock (
598 (UINT8
*) IfrFormNvData
,
602 if (!EFI_ERROR (Status
)) {
603 Status
= Ip4ConfigConvertIfrNvDataToDeviceConfigData (IfrFormNvData
, Ip4ConfigInstance
);
606 FreePool (IfrFormNvData
);
608 } else if (HiiIsConfigHdrMatch (Configuration
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
610 IfrDeviceNvData
= AllocateZeroPool (NIC_ITEM_CONFIG_SIZE
);
611 if (IfrDeviceNvData
== NULL
) {
612 return EFI_OUT_OF_RESOURCES
;
615 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
616 Status
= gHiiConfigRouting
->ConfigToBlock (
619 (UINT8
*) IfrDeviceNvData
,
623 if (!EFI_ERROR (Status
)) {
624 ZeroMem (&ZeroMac
, sizeof (EFI_MAC_ADDRESS
));
625 if (CompareMem (&IfrDeviceNvData
->NicAddr
.MacAddr
, &ZeroMac
, IfrDeviceNvData
->NicAddr
.Len
) != 0) {
626 BufferSize
= SIZEOF_NIC_IP4_CONFIG_INFO (IfrDeviceNvData
);
627 NicInfo
= AllocateCopyPool (BufferSize
, IfrDeviceNvData
);
628 if (NicInfo
== NULL
) {
629 return EFI_OUT_OF_RESOURCES
;
631 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NicInfo
, TRUE
);
634 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
, sizeof (IP4_SETTING_INFO
));
635 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NULL
, TRUE
);
639 FreePool (IfrDeviceNvData
);
643 return EFI_NOT_FOUND
;
651 This function is called to provide results data to the driver.
652 This data consists of a unique key that is used to identify
653 which data is either being passed back or being asked for.
655 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
656 @param[in] Action Specifies the type of action taken by the browser.
657 @param[in] QuestionId A unique value which is sent to the original
658 exporting driver so that it can identify the type
659 of data to expect. The format of the data tends to
660 vary based on the opcode that enerated the callback.
661 @param[in] Type The type of value for the question.
662 @param[in] Value A pointer to the data being sent to the original
664 @param[out] ActionRequest On return, points to the action requested by the
667 @retval EFI_SUCCESS The callback successfully handled the action.
668 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
669 variable and its data.
670 @retval EFI_DEVICE_ERROR The variable could not be saved.
671 @retval EFI_UNSUPPORTED The specified Action is not supported by the
672 callback.Currently not implemented.
673 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
674 @retval Others Other errors as indicated.
679 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
680 IN EFI_BROWSER_ACTION Action
,
681 IN EFI_QUESTION_ID QuestionId
,
683 IN EFI_IFR_TYPE_VALUE
*Value
,
684 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
687 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
688 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
689 EFI_IP_ADDRESS HostIp
;
690 EFI_IP_ADDRESS SubnetMask
;
691 EFI_IP_ADDRESS Gateway
;
695 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)) {
697 // Do nothing for UEFI OPEN/CLOSE Action
702 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This
);
704 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
705 if (IfrFormNvData
== NULL
) {
706 return EFI_OUT_OF_RESOURCES
;
710 // Retrive uncommitted data from Browser
712 if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, sizeof (IP4_CONFIG_IFR_NVDATA
), (UINT8
*) IfrFormNvData
)) {
713 FreePool (IfrFormNvData
);
714 return EFI_NOT_FOUND
;
717 Status
= EFI_SUCCESS
;
719 switch (QuestionId
) {
721 Status
= Ip4StrToIp (IfrFormNvData
->StationAddress
, &HostIp
.v4
);
722 if (EFI_ERROR (Status
) || !NetIp4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
723 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
724 Status
= EFI_INVALID_PARAMETER
;
726 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
731 case KEY_SUBNET_MASK
:
732 Status
= Ip4StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
733 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
734 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
735 Status
= EFI_INVALID_PARAMETER
;
737 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
743 Status
= Ip4StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
744 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
745 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
746 Status
= EFI_INVALID_PARAMETER
;
748 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
753 case KEY_SAVE_CHANGES
:
754 Status
= Ip4ConfigConvertIfrNvDataToDeviceConfigData (IfrFormNvData
, Ip4ConfigInstance
);
755 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
762 FreePool (IfrFormNvData
);
768 Install HII Config Access protocol for network device and allocate resource.
770 @param[in] Instance The IP4 Config instance.
772 @retval EFI_SUCCESS The HII Config Access protocol is installed.
773 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
774 @retval Others Other errors as indicated.
777 Ip4ConfigDeviceInit (
778 IN IP4_CONFIG_INSTANCE
*Instance
782 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
783 VENDOR_DEVICE_PATH VendorDeviceNode
;
784 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
786 CHAR16 MenuString
[128];
787 CHAR16 PortString
[128];
788 CHAR16
*OldMenuString
;
790 ConfigAccess
= &Instance
->HiiConfigAccessProtocol
;
791 ConfigAccess
->ExtractConfig
= Ip4DeviceExtractConfig
;
792 ConfigAccess
->RouteConfig
= Ip4DeviceRouteConfig
;
793 ConfigAccess
->Callback
= Ip4FormCallback
;
796 // Construct device path node for EFI HII Config Access protocol,
797 // which consists of controller physical device path and one hardware
800 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
801 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
802 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
804 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiNicIp4ConfigVariableGuid
);
806 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
807 Instance
->HiiVendorDevicePath
= AppendDevicePathNode (
808 Instance
->ParentDevicePath
,
809 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
812 Instance
->ChildHandle
= NULL
;
814 // Install Device Path Protocol and Config Access protocol on new handle
816 Status
= gBS
->InstallMultipleProtocolInterfaces (
817 &Instance
->ChildHandle
,
818 &gEfiDevicePathProtocolGuid
,
819 Instance
->HiiVendorDevicePath
,
820 &gEfiHiiConfigAccessProtocolGuid
,
824 if (!EFI_ERROR (Status
)) {
826 // Open the Parent Handle for the child
828 Status
= gBS
->OpenProtocol (
829 Instance
->Controller
,
830 &gEfiManagedNetworkServiceBindingProtocolGuid
,
833 Instance
->ChildHandle
,
834 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
838 ASSERT_EFI_ERROR (Status
);
841 // Publish our HII data
843 Instance
->RegisteredHandle
= HiiAddPackages (
844 &mNicIp4ConfigNvDataGuid
,
845 Instance
->ChildHandle
,
850 if (Instance
->RegisteredHandle
== NULL
) {
851 return EFI_OUT_OF_RESOURCES
;
855 // Append MAC string in the menu string and tile string
857 Status
= NetLibGetMacString (Instance
->Controller
, Instance
->Image
, &MacString
);
858 if (!EFI_ERROR (Status
)) {
859 OldMenuString
= HiiGetString (Instance
->RegisteredHandle
, STRING_TOKEN (STR_IP4_CONFIG_FORM_HELP
), NULL
);
860 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
861 HiiSetString (Instance
->RegisteredHandle
, STRING_TOKEN (STR_IP4_CONFIG_FORM_HELP
), MenuString
, NULL
);
863 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
864 HiiSetString (Instance
->RegisteredHandle
, STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP
), PortString
, NULL
);
865 FreePool (MacString
);
872 Uninstall HII Config Access protocol for network device and free resource.
874 @param[in] Instance The IP4 Config instance.
876 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.
877 @retval Others Other errors as indicated.
880 Ip4ConfigDeviceUnload (
881 IN IP4_CONFIG_INSTANCE
*Instance
885 // Remove HII package list
887 HiiRemovePackages (Instance
->RegisteredHandle
);
890 // Close the child handle
893 Instance
->Controller
,
894 &gEfiManagedNetworkServiceBindingProtocolGuid
,
896 Instance
->ChildHandle
900 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
902 gBS
->UninstallMultipleProtocolInterfaces (
903 Instance
->ChildHandle
,
904 &gEfiDevicePathProtocolGuid
,
905 Instance
->HiiVendorDevicePath
,
906 &gEfiHiiConfigAccessProtocolGuid
,
907 &Instance
->HiiConfigAccessProtocol
,