2 Helper functions for configuring or getting the parameters relating to Ip4.
4 Copyright (c) 2009 - 2011, 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"
19 Calculate the prefix length of the IPv4 subnet mask.
21 @param[in] SubnetMask The IPv4 subnet mask.
23 @return The prefix length of the subnet mask.
24 @retval 0 Other errors as indicated.
27 GetSubnetMaskPrefixLength (
28 IN EFI_IPv4_ADDRESS
*SubnetMask
35 // The SubnetMask is in network byte order.
37 ReverseMask
= SwapBytes32 (*(UINT32
*)&SubnetMask
[0]);
42 ReverseMask
= ~ReverseMask
;
44 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
50 while (ReverseMask
!= 0) {
51 ReverseMask
= ReverseMask
>> 1;
55 return (UINT8
) (32 - Len
);
59 Convert the decimal dotted IPv4 address into the binary IPv4 address.
61 @param[in] Str The UNICODE string.
62 @param[out] Ip The storage to return the IPv4 address.
64 @retval EFI_SUCCESS The binary IP address is returned in Ip.
65 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
70 OUT EFI_IPv4_ADDRESS
*Ip
78 while (*Str
!= L
'\0') {
81 return EFI_INVALID_PARAMETER
;
85 while ((*Str
>= L
'0') && (*Str
<= L
'9')) {
86 Number
= Number
* 10 + (*Str
- L
'0');
91 return EFI_INVALID_PARAMETER
;
94 Ip
->Addr
[Index
] = (UINT8
) Number
;
96 if ((*Str
!= L
'\0') && (*Str
!= L
'.')) {
98 // The current character should be either the NULL terminator or
101 return EFI_INVALID_PARAMETER
;
106 // Skip the delimiter.
115 return EFI_INVALID_PARAMETER
;
122 Convert the IPv4 address into a dotted string.
124 @param[in] Ip The IPv4 address.
125 @param[out] Str The dotted IP string.
129 IN EFI_IPv4_ADDRESS
*Ip
,
133 UnicodeSPrint (Str
, 2 * IP4_STR_MAX_SIZE
, L
"%d.%d.%d.%d", Ip
->Addr
[0], Ip
->Addr
[1], Ip
->Addr
[2], Ip
->Addr
[3]);
138 Convert the network configuration data into the IFR data.
140 @param[in] Ip4ConfigInstance The IP4Config instance
141 @param[out] IfrFormNvData The IFR nv data.
144 Ip4ConfigConvertDeviceConfigDataToIfrNvData (
145 IN IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
,
146 OUT IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
149 NIC_IP4_CONFIG_INFO
*NicConfig
;
151 NicConfig
= EfiNicIp4ConfigGetInfo (Ip4ConfigInstance
);
152 if (NicConfig
!= NULL
) {
153 IfrFormNvData
->Configure
= 1;
154 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
= TRUE
;
155 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
) {
156 IfrFormNvData
->DhcpEnable
= 1;
157 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
= TRUE
;
159 IfrFormNvData
->DhcpEnable
= 0;
160 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.StationAddress
, IfrFormNvData
->StationAddress
);
161 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.SubnetMask
, IfrFormNvData
->SubnetMask
);
162 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.RouteTable
[1].GatewayAddress
, IfrFormNvData
->GatewayAddress
);
164 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
= FALSE
;
165 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, &NicConfig
->Ip4Info
.StationAddress
, sizeof (EFI_IPv4_ADDRESS
));
166 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, &NicConfig
->Ip4Info
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
167 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, &NicConfig
->Ip4Info
.RouteTable
[1].GatewayAddress
, sizeof (EFI_IPv4_ADDRESS
));
170 FreePool (NicConfig
);
172 IfrFormNvData
->Configure
= 0;
173 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
= FALSE
;
178 Convert the IFR data into the network configuration data and set the IP
179 configure parameters for the NIC.
181 @param[in] IfrFormNvData The IFR NV data.
182 @param[in, out] Ip4ConfigInstance The IP4Config instance.
184 @retval EFI_SUCCESS The configure parameter for this NIC was
186 @retval EFI_ALREADY_STARTED There is a pending auto configuration.
187 @retval EFI_NOT_FOUND No auto configure parameter is found.
191 Ip4ConfigConvertIfrNvDataToDeviceConfigData (
192 IN IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
,
193 IN OUT IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
197 EFI_IP_ADDRESS HostIp
;
198 EFI_IP_ADDRESS SubnetMask
;
199 EFI_IP_ADDRESS Gateway
;
201 NIC_IP4_CONFIG_INFO
*NicInfo
;
204 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
, sizeof (IP4_SETTING_INFO
));
206 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
= IfrFormNvData
->Configure
;
207 Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
= IfrFormNvData
->DhcpEnable
;
208 Ip4StrToIp (IfrFormNvData
->StationAddress
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
);
209 Ip4StrToIp (IfrFormNvData
->SubnetMask
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
);
210 Ip4StrToIp (IfrFormNvData
->GatewayAddress
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
);
212 if (!Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Configured
) {
214 // Clear the variable
216 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
, sizeof (IP4_SETTING_INFO
));
218 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NULL
, TRUE
);
219 if (Status
== EFI_NOT_FOUND
) {
226 NicInfo
= AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO
) + 2 * sizeof (EFI_IP4_ROUTE_TABLE
));
227 ASSERT (NicInfo
!= NULL
);
229 NicInfo
->Ip4Info
.RouteTable
= (EFI_IP4_ROUTE_TABLE
*) (NicInfo
+ 1);
231 if (!Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.DhcpEnabled
) {
232 CopyMem (&HostIp
.v4
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, sizeof (HostIp
.v4
));
233 CopyMem (&SubnetMask
.v4
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, sizeof (SubnetMask
.v4
));
234 CopyMem (&Gateway
.v4
, &Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, sizeof (Gateway
.v4
));
236 if (!NetIp4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
237 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
238 return EFI_INVALID_PARAMETER
;
240 if (EFI_IP4_EQUAL (&SubnetMask
, &mZeroIp4Addr
)) {
241 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
242 return EFI_INVALID_PARAMETER
;
245 if ((Gateway
.Addr
[0] != 0)) {
246 if (SubnetMask
.Addr
[0] == 0) {
247 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Gateway address is set but subnet mask is zero.", NULL
);
248 return EFI_INVALID_PARAMETER
;
250 } else if (!IP4_NET_EQUAL (HostIp
.Addr
[0], Gateway
.Addr
[0], SubnetMask
.Addr
[0])) {
251 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Local IP and Gateway are not in the same subnet.", NULL
);
252 return EFI_INVALID_PARAMETER
; }
255 NicInfo
->Source
= IP4_CONFIG_SOURCE_STATIC
;
256 NicInfo
->Ip4Info
.RouteTableSize
= 2;
258 CopyMem (&NicInfo
->Ip4Info
.StationAddress
, &HostIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
259 CopyMem (&NicInfo
->Ip4Info
.SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
261 Ip
.Addr
[0] = HostIp
.Addr
[0] & SubnetMask
.Addr
[0];
263 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[0].SubnetAddress
, &Ip
.v4
, sizeof (EFI_IPv4_ADDRESS
));
264 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[0].SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
265 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[1].GatewayAddress
, &Gateway
.v4
, sizeof (EFI_IPv4_ADDRESS
));
268 NicInfo
->Source
= IP4_CONFIG_SOURCE_DHCP
;
269 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
270 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
271 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, sizeof (EFI_IPv4_ADDRESS
));
274 NicInfo
->Perment
= TRUE
;
275 CopyMem (&NicInfo
->NicAddr
, &Ip4ConfigInstance
->NicAddr
, sizeof (NIC_ADDR
));
277 return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NicInfo
, TRUE
);
281 This function allows the caller to request the current
282 configuration for one or more named elements. The resulting
283 string is in <ConfigAltResp> format. Any and all alternative
284 configuration strings shall also be appended to the end of the
285 current configuration string. If they are, they must appear
286 after the current configuration. They must contain the same
287 routing (GUID, NAME, PATH) as the current configuration string.
288 They must have an additional description indicating the type of
289 alternative configuration the string represents,
290 "ALTCFG=<StringToken>". That <StringToken> (when
291 converted from Hex UNICODE to binary) is a reference to a
292 string in the associated string pack.
294 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
295 @param[in] Request A null-terminated Unicode string in
296 <ConfigRequest> format. Note that this
297 includes the routing information as well as
298 the configurable name / value pairs. It is
299 invalid for this string to be in
300 <MultiConfigRequest> format.
301 @param[out] Progress On return, points to a character in the
302 Request string. Points to the string's null
303 terminator if request was successful. Points
304 to the most recent "&" before the first
305 failing name / value pair (or the beginning
306 of the string if the failure is in the first
307 name / value pair) if the request was not
309 @param[out] Results A null-terminated Unicode string in
310 <ConfigAltResp> format which has all values
311 filled in for the names in the Request string.
312 String to be allocated by the called function.
314 @retval EFI_SUCCESS The Results string is filled with the
315 values corresponding to all requested
317 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
318 parts of the results that must be
319 stored awaiting possible future
321 @retval EFI_NOT_FOUND Routing data doesn't match any
322 known driver. Progress set to the
323 first character in the routing header.
324 Note: There is no requirement that the
325 driver validate the routing data. It
326 must skip the <ConfigHdr> in order to
328 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
329 to most recent & before the
330 error or the beginning of the
332 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
333 to the & before the name in
334 question.Currently not implemented.
338 Ip4DeviceExtractConfig (
339 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
340 IN CONST EFI_STRING Request
,
341 OUT EFI_STRING
*Progress
,
342 OUT EFI_STRING
*Results
346 NIC_IP4_CONFIG_INFO
*IfrDeviceNvData
;
347 NIC_IP4_CONFIG_INFO
*NicConfig
;
348 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
349 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
350 EFI_STRING ConfigRequestHdr
;
351 EFI_STRING ConfigRequest
;
352 EFI_STRING DeviceResult
;
353 EFI_STRING FormResult
;
355 BOOLEAN AllocatedRequest
;
359 if (Progress
== NULL
|| Results
== NULL
) {
360 return EFI_INVALID_PARAMETER
;
367 ConfigRequest
= NULL
;
368 Status
= EFI_SUCCESS
;
369 AllocatedRequest
= FALSE
;
370 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This
);
373 // Check Request data in <ConfigHdr>.
375 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
376 IfrDeviceNvData
= AllocateZeroPool (NIC_ITEM_CONFIG_SIZE
);
377 if (IfrDeviceNvData
== NULL
) {
378 return EFI_OUT_OF_RESOURCES
;
381 NicConfig
= EfiNicIp4ConfigGetInfo (Ip4ConfigInstance
);
382 if (NicConfig
== NULL
) {
383 return EFI_NOT_FOUND
;
385 CopyMem (IfrDeviceNvData
, NicConfig
, SIZEOF_NIC_IP4_CONFIG_INFO (NicConfig
));
386 FreePool (NicConfig
);
388 ConfigRequest
= Request
;
389 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
391 // Request has no request element, construct full request string.
392 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
393 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
395 ConfigRequestHdr
= HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, Ip4ConfigInstance
->ChildHandle
);
396 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
397 ConfigRequest
= AllocateZeroPool (Size
);
398 ASSERT (ConfigRequest
!= NULL
);
399 AllocatedRequest
= TRUE
;
400 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
401 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
402 FreePool (ConfigRequestHdr
);
406 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
408 Status
= gHiiConfigRouting
->BlockToConfig (
411 (UINT8
*) IfrDeviceNvData
,
412 NIC_ITEM_CONFIG_SIZE
,
417 FreePool (IfrDeviceNvData
);
419 // Free the allocated config request string.
421 if (AllocatedRequest
) {
422 FreePool (ConfigRequest
);
423 ConfigRequest
= NULL
;
426 if (EFI_ERROR (Status
)) {
431 if ((Request
== NULL
) || HiiIsConfigHdrMatch (Request
, &gNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
433 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
434 if (IfrFormNvData
== NULL
) {
435 return EFI_OUT_OF_RESOURCES
;
438 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance
, IfrFormNvData
);
440 ConfigRequest
= Request
;
441 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
443 // Request has no request element, construct full request string.
444 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
445 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
447 ConfigRequestHdr
= HiiConstructConfigHdr (&gNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, Ip4ConfigInstance
->ChildHandle
);
448 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
449 ConfigRequest
= AllocateZeroPool (Size
);
450 ASSERT (ConfigRequest
!= NULL
);
451 AllocatedRequest
= TRUE
;
452 BufferSize
= sizeof (IP4_CONFIG_IFR_NVDATA
);
453 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
454 FreePool (ConfigRequestHdr
);
458 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
460 Status
= gHiiConfigRouting
->BlockToConfig (
463 (UINT8
*) IfrFormNvData
,
464 sizeof (IP4_CONFIG_IFR_NVDATA
),
469 FreePool (IfrFormNvData
);
471 // Free the allocated config request string.
473 if (AllocatedRequest
) {
474 FreePool (ConfigRequest
);
475 ConfigRequest
= NULL
;
478 if (EFI_ERROR (Status
)) {
483 if (Request
== NULL
) {
484 Size
= StrLen (DeviceResult
);
486 Size
= Size
+ StrLen (FormResult
) + 1;
487 *Results
= AllocateZeroPool (Size
* sizeof (CHAR16
));
488 ASSERT (*Results
!= NULL
);
489 StrPointer
= *Results
;
490 StrCpy (StrPointer
, DeviceResult
);
491 StrPointer
= StrPointer
+ StrLen (StrPointer
);
493 StrCpy (StrPointer
+ 1, FormResult
);
494 FreePool (DeviceResult
);
495 FreePool (FormResult
);
496 } else if (HiiIsConfigHdrMatch (Request
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
497 *Results
= DeviceResult
;
498 } else if (HiiIsConfigHdrMatch (Request
, &gNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
499 *Results
= FormResult
;
501 return EFI_NOT_FOUND
;
506 // Set Progress string to the original request string.
508 if (Request
== NULL
) {
510 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
511 *Progress
= Request
+ StrLen (Request
);
518 This function applies changes in a driver's configuration.
519 Input is a Configuration, which has the routing data for this
520 driver followed by name / value configuration pairs. The driver
521 must apply those pairs to its configurable storage. If the
522 driver's configuration is stored in a linear block of data
523 and the driver's name / value pairs are in <BlockConfig>
524 format, it may use the ConfigToBlock helper function (above) to
525 simplify the job. Currently not implemented.
527 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
528 @param[in] Configuration A null-terminated Unicode string in
529 <ConfigString> format.
530 @param[out] Progress A pointer to a string filled in with the
531 offset of the most recent '&' before the
532 first failing name / value pair (or the
533 beginn ing of the string if the failure
534 is in the first name / value pair) or
535 the terminating NULL if all was
538 @retval EFI_SUCCESS The results have been distributed or are
539 awaiting distribution.
540 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
541 parts of the results that must be
542 stored awaiting possible future
544 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
545 Results parameter would result
546 in this type of error.
547 @retval EFI_NOT_FOUND Target for the specified routing data
552 Ip4DeviceRouteConfig (
553 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
554 IN CONST EFI_STRING Configuration
,
555 OUT EFI_STRING
*Progress
560 NIC_IP4_CONFIG_INFO
*IfrDeviceNvData
;
561 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
562 NIC_IP4_CONFIG_INFO
*NicInfo
;
563 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
564 EFI_MAC_ADDRESS ZeroMac
;
566 if (Configuration
== NULL
|| Progress
== NULL
) {
567 return EFI_INVALID_PARAMETER
;
571 // Reclaim Ip4Config variable
573 Ip4ConfigReclaimVariable ();
575 *Progress
= Configuration
;
577 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This
);
580 // Check Routing data in <ConfigHdr>.
582 if (HiiIsConfigHdrMatch (Configuration
, &gNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
584 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
586 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
587 if (IfrFormNvData
== NULL
) {
588 return EFI_OUT_OF_RESOURCES
;
591 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
592 Status
= gHiiConfigRouting
->ConfigToBlock (
595 (UINT8
*) IfrFormNvData
,
599 if (!EFI_ERROR (Status
)) {
600 Status
= Ip4ConfigConvertIfrNvDataToDeviceConfigData (IfrFormNvData
, Ip4ConfigInstance
);
603 FreePool (IfrFormNvData
);
605 } else if (HiiIsConfigHdrMatch (Configuration
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
607 IfrDeviceNvData
= AllocateZeroPool (NIC_ITEM_CONFIG_SIZE
);
608 if (IfrDeviceNvData
== NULL
) {
609 return EFI_OUT_OF_RESOURCES
;
612 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
613 Status
= gHiiConfigRouting
->ConfigToBlock (
616 (UINT8
*) IfrDeviceNvData
,
620 if (!EFI_ERROR (Status
)) {
621 ZeroMem (&ZeroMac
, sizeof (EFI_MAC_ADDRESS
));
622 if (CompareMem (&IfrDeviceNvData
->NicAddr
.MacAddr
, &ZeroMac
, IfrDeviceNvData
->NicAddr
.Len
) != 0) {
623 BufferSize
= SIZEOF_NIC_IP4_CONFIG_INFO (IfrDeviceNvData
);
624 NicInfo
= AllocateCopyPool (BufferSize
, IfrDeviceNvData
);
625 if (NicInfo
== NULL
) {
626 return EFI_OUT_OF_RESOURCES
;
628 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NicInfo
, TRUE
);
631 ZeroMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
, sizeof (IP4_SETTING_INFO
));
632 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NULL
, TRUE
);
636 FreePool (IfrDeviceNvData
);
640 return EFI_NOT_FOUND
;
648 This function is called to provide results data to the driver.
649 This data consists of a unique key that is used to identify
650 which data is either being passed back or being asked for.
652 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
653 @param[in] Action Specifies the type of action taken by the browser.
654 @param[in] QuestionId A unique value which is sent to the original
655 exporting driver so that it can identify the type
656 of data to expect. The format of the data tends to
657 vary based on the opcode that enerated the callback.
658 @param[in] Type The type of value for the question.
659 @param[in] Value A pointer to the data being sent to the original
661 @param[out] ActionRequest On return, points to the action requested by the
664 @retval EFI_SUCCESS The callback successfully handled the action.
665 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
666 variable and its data.
667 @retval EFI_DEVICE_ERROR The variable could not be saved.
668 @retval EFI_UNSUPPORTED The specified Action is not supported by the
669 callback.Currently not implemented.
670 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
671 @retval Others Other errors as indicated.
676 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
677 IN EFI_BROWSER_ACTION Action
,
678 IN EFI_QUESTION_ID QuestionId
,
680 IN EFI_IFR_TYPE_VALUE
*Value
,
681 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
684 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
685 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
686 EFI_IP_ADDRESS HostIp
;
687 EFI_IP_ADDRESS SubnetMask
;
688 EFI_IP_ADDRESS Gateway
;
692 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
693 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This
);
695 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
696 if (IfrFormNvData
== NULL
) {
697 return EFI_OUT_OF_RESOURCES
;
701 // Retrive uncommitted data from Browser
703 if (!HiiGetBrowserData (&gNicIp4ConfigNvDataGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, sizeof (IP4_CONFIG_IFR_NVDATA
), (UINT8
*) IfrFormNvData
)) {
704 FreePool (IfrFormNvData
);
705 return EFI_NOT_FOUND
;
708 Status
= EFI_SUCCESS
;
710 switch (QuestionId
) {
712 Status
= Ip4StrToIp (IfrFormNvData
->StationAddress
, &HostIp
.v4
);
713 if (EFI_ERROR (Status
) || !NetIp4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
714 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
715 Status
= EFI_INVALID_PARAMETER
;
717 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
722 case KEY_SUBNET_MASK
:
723 Status
= Ip4StrToIp (IfrFormNvData
->SubnetMask
, &SubnetMask
.v4
);
724 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
725 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Subnet Mask!", NULL
);
726 Status
= EFI_INVALID_PARAMETER
;
728 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
734 Status
= Ip4StrToIp (IfrFormNvData
->GatewayAddress
, &Gateway
.v4
);
735 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
736 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
737 Status
= EFI_INVALID_PARAMETER
;
739 CopyMem (&Ip4ConfigInstance
->Ip4ConfigCallbackInfo
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
744 case KEY_SAVE_CHANGES
:
745 Status
= Ip4ConfigConvertIfrNvDataToDeviceConfigData (IfrFormNvData
, Ip4ConfigInstance
);
746 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
753 FreePool (IfrFormNvData
);
759 // All other action return unsupported.
761 return EFI_UNSUPPORTED
;
765 Install HII Config Access protocol for network device and allocate resource.
767 @param[in] Instance The IP4 Config instance.
769 @retval EFI_SUCCESS The HII Config Access protocol is installed.
770 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
771 @retval Others Other errors as indicated.
774 Ip4ConfigDeviceInit (
775 IN IP4_CONFIG_INSTANCE
*Instance
779 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
780 VENDOR_DEVICE_PATH VendorDeviceNode
;
781 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
783 CHAR16 MenuString
[128];
784 CHAR16 PortString
[128];
785 CHAR16
*OldMenuString
;
787 ConfigAccess
= &Instance
->HiiConfigAccessProtocol
;
788 ConfigAccess
->ExtractConfig
= Ip4DeviceExtractConfig
;
789 ConfigAccess
->RouteConfig
= Ip4DeviceRouteConfig
;
790 ConfigAccess
->Callback
= Ip4FormCallback
;
793 // Construct device path node for EFI HII Config Access protocol,
794 // which consists of controller physical device path and one hardware
797 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
798 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
799 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
801 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiNicIp4ConfigVariableGuid
);
803 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
804 Instance
->HiiVendorDevicePath
= AppendDevicePathNode (
805 Instance
->ParentDevicePath
,
806 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
809 Instance
->ChildHandle
= NULL
;
811 // Install Device Path Protocol and Config Access protocol on new handle
813 Status
= gBS
->InstallMultipleProtocolInterfaces (
814 &Instance
->ChildHandle
,
815 &gEfiDevicePathProtocolGuid
,
816 Instance
->HiiVendorDevicePath
,
817 &gEfiHiiConfigAccessProtocolGuid
,
821 if (!EFI_ERROR (Status
)) {
823 // Open the Parent Handle for the child
825 Status
= gBS
->OpenProtocol (
826 Instance
->Controller
,
827 &gEfiManagedNetworkServiceBindingProtocolGuid
,
830 Instance
->ChildHandle
,
831 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
835 ASSERT_EFI_ERROR (Status
);
838 // Publish our HII data
840 Instance
->RegisteredHandle
= HiiAddPackages (
841 &gNicIp4ConfigNvDataGuid
,
842 Instance
->ChildHandle
,
847 if (Instance
->RegisteredHandle
== NULL
) {
848 return EFI_OUT_OF_RESOURCES
;
852 // Append MAC string in the menu help string and tile help string
854 Status
= NetLibGetMacString (Instance
->Controller
, Instance
->Image
, &MacString
);
855 if (!EFI_ERROR (Status
)) {
856 OldMenuString
= HiiGetString (Instance
->RegisteredHandle
, STRING_TOKEN (STR_IP4_CONFIG_FORM_HELP
), NULL
);
857 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
858 HiiSetString (Instance
->RegisteredHandle
, STRING_TOKEN (STR_IP4_CONFIG_FORM_HELP
), MenuString
, NULL
);
860 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
861 HiiSetString (Instance
->RegisteredHandle
, STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP
), PortString
, NULL
);
862 FreePool (MacString
);
869 Uninstall HII Config Access protocol for network device and free resource.
871 @param[in] Instance The IP4 Config instance.
873 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.
874 @retval Others Other errors as indicated.
877 Ip4ConfigDeviceUnload (
878 IN IP4_CONFIG_INSTANCE
*Instance
882 // Remove HII package list
884 HiiRemovePackages (Instance
->RegisteredHandle
);
887 // Close the child handle
890 Instance
->Controller
,
891 &gEfiManagedNetworkServiceBindingProtocolGuid
,
893 Instance
->ChildHandle
897 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
899 gBS
->UninstallMultipleProtocolInterfaces (
900 Instance
->ChildHandle
,
901 &gEfiDevicePathProtocolGuid
,
902 Instance
->HiiVendorDevicePath
,
903 &gEfiHiiConfigAccessProtocolGuid
,
904 &Instance
->HiiConfigAccessProtocol
,