2 Helper functions for configuring or getting the parameters relating to Ip4.
4 Copyright (c) 2009, Intel Corporation.<BR>
5 All rights reserved. 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"
17 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 Ip4HexString
[] = "0123456789ABCDEFabcdef";
19 UINTN mNumberOfIp4Devices
= 0;
21 IP4_FORM_CALLBACK_INFO
*mCallbackInfo
= NULL
;
23 LIST_ENTRY mIp4ConfigFormList
= {
28 HII_VENDOR_DEVICE_PATH mIp4ConifgHiiVendorDevicePath
= {
34 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
35 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
39 // {6D3FD906-42B9-4220-9E63-9D8C972D58EE}
41 { 0x6d3fd906, 0x42b9, 0x4220, { 0x9e, 0x63, 0x9d, 0x8c, 0x97, 0x2d, 0x58, 0xee } }
45 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
47 (UINT8
) (END_DEVICE_PATH_LENGTH
),
48 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
54 Convert the mac address into a hexadecimal encoded "-" seperated string.
56 @param[in] Mac The mac address.
57 @param[in] Len Length in bytes of the mac address.
58 @param[out] Str The storage to return the mac string.
63 IN EFI_MAC_ADDRESS
*Mac
,
70 for (Index
= 0; Index
< Len
; Index
++) {
71 Str
[3 * Index
] = (CHAR16
) Ip4HexString
[(Mac
->Addr
[Index
] >> 4) & 0x0F];
72 Str
[3 * Index
+ 1] = (CHAR16
) Ip4HexString
[Mac
->Addr
[Index
] & 0x0F];
73 Str
[3 * Index
+ 2] = L
'-';
76 Str
[3 * Index
- 1] = L
'\0';
80 Calculate the prefix length of the IPv4 subnet mask.
82 @param[in] SubnetMask The IPv4 subnet mask.
84 @return The prefix length of the subnet mask.
85 @retval 0 Other errors as indicated.
88 GetSubnetMaskPrefixLength (
89 IN EFI_IPv4_ADDRESS
*SubnetMask
96 // The SubnetMask is in network byte order.
98 ReverseMask
= (SubnetMask
->Addr
[0] << 24) | (SubnetMask
->Addr
[1] << 16) | (SubnetMask
->Addr
[2] << 8) | (SubnetMask
->Addr
[3]);
103 ReverseMask
= ~ReverseMask
;
105 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
111 while (ReverseMask
!= 0) {
112 ReverseMask
= ReverseMask
>> 1;
116 return (UINT8
) (32 - Len
);
120 Convert the decimal dotted IPv4 address into the binary IPv4 address.
122 @param[in] Str The UNICODE string.
123 @param[out] Ip The storage to return the ASCII string.
125 @retval EFI_SUCCESS The binary IP address is returned in Ip.
126 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
131 OUT EFI_IPv4_ADDRESS
*Ip
142 return EFI_INVALID_PARAMETER
;
146 while (NET_IS_DIGIT (*Str
)) {
147 Number
= Number
* 10 + (*Str
- '0');
152 return EFI_INVALID_PARAMETER
;
155 Ip
->Addr
[Index
] = (UINT8
) Number
;
157 if ((*Str
!= '\0') && (*Str
!= '.')) {
159 // The current character should be either the NULL terminator or
160 // the dot delimiter.
162 return EFI_INVALID_PARAMETER
;
167 // Skip the delimiter.
176 return EFI_INVALID_PARAMETER
;
183 Convert the IPv4 address into a dotted string.
185 @param[in] Ip The IPv4 address.
186 @param[out] Str The dotted IP string.
190 IN EFI_IPv4_ADDRESS
*Ip
,
194 UnicodeSPrint (Str
, 2 * IP4_STR_MAX_SIZE
, L
"%d.%d.%d.%d", Ip
->Addr
[0], Ip
->Addr
[1], Ip
->Addr
[2], Ip
->Addr
[3]);
199 Convert the network configuration data into the IFR data.
201 @param[in] ConfigFormEntry The IP4 configuration form entry.
202 @param[out] IfrNvData The IFR nv data.
205 Ip4ConfigConvertDeviceConfigDataToIfrNvData (
206 IN IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
,
207 OUT IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
211 NIC_IP4_CONFIG_INFO
*NicConfig
;
214 IfrFormNvData
->DhcpEnable
= 1;
216 ConfigLen
= sizeof (NIC_IP4_CONFIG_INFO
) + sizeof (EFI_IP4_ROUTE_TABLE
) * 2;
217 NicConfig
= AllocateZeroPool (ConfigLen
);
218 ASSERT (NicConfig
!= NULL
);
219 Status
= EfiNicIp4ConfigGetInfo (Ip4ConfigInstance
, &ConfigLen
, NicConfig
);
220 if (!EFI_ERROR (Status
)) {
221 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
) {
222 IfrFormNvData
->DhcpEnable
= 1;
224 IfrFormNvData
->DhcpEnable
= 0;
225 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.StationAddress
, IfrFormNvData
->StationAddress
);
226 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.SubnetMask
, IfrFormNvData
->SubnetMask
);
227 Ip4ConfigIpToStr (&NicConfig
->Ip4Info
.RouteTable
[1].GatewayAddress
, IfrFormNvData
->GatewayAddress
);
230 FreePool (NicConfig
);
234 Get the IP4 configuration form entry by the index of the goto opcode actived.
236 @param[in] Index The 0-based index of the goto opcode actived.
238 @return The IP4 configuration form entry found.
240 IP4CONFIG_FORM_ENTRY
*
241 Ip4GetConfigFormEntryByIndex (
247 IP4CONFIG_FORM_ENTRY
*ConfigFormEntry
;
250 ConfigFormEntry
= NULL
;
252 NET_LIST_FOR_EACH (Entry
, &mIp4ConfigFormList
) {
253 if (CurrentIndex
== Index
) {
254 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, IP4CONFIG_FORM_ENTRY
, Link
);
261 return ConfigFormEntry
;
265 This function allows the caller to request the current
266 configuration for one or more named elements. The resulting
267 string is in <ConfigAltResp> format. Any and all alternative
268 configuration strings shall also be appended to the end of the
269 current configuration string. If they are, they must appear
270 after the current configuration. They must contain the same
271 routing (GUID, NAME, PATH) as the current configuration string.
272 They must have an additional description indicating the type of
273 alternative configuration the string represents,
274 "ALTCFG=<StringToken>". That <StringToken> (when
275 converted from Hex UNICODE to binary) is a reference to a
276 string in the associated string pack.
278 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
279 @param[in] Request A null-terminated Unicode string in
280 <ConfigRequest> format. Note that this
281 includes the routing information as well as
282 the configurable name / value pairs. It is
283 invalid for this string to be in
284 <MultiConfigRequest> format.
285 @param[out] Progress On return, points to a character in the
286 Request string. Points to the string's null
287 terminator if request was successful. Points
288 to the most recent "&" before the first
289 failing name / value pair (or the beginning
290 of the string if the failure is in the first
291 name / value pair) if the request was not
293 @param[out] Results A null-terminated Unicode string in
294 <ConfigAltResp> format which has all values
295 filled in for the names in the Request string.
296 String to be allocated by the called function.
298 @retval EFI_SUCCESS The Results string is filled with the
299 values corresponding to all requested
301 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
302 parts of the results that must be
303 stored awaiting possible future
305 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
306 for the Request parameter
307 would result in this type of
308 error. In this case, the
309 Progress parameter would be
311 @retval EFI_NOT_FOUND Routing data doesn't match any
312 known driver. Progress set to the
313 first character in the routing header.
314 Note: There is no requirement that the
315 driver validate the routing data. It
316 must skip the <ConfigHdr> in order to
318 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
319 to most recent & before the
320 error or the beginning of the
322 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
323 to the & before the name in
324 question.Currently not implemented.
328 Ip4DeviceExtractConfig (
329 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
330 IN CONST EFI_STRING Request
,
331 OUT EFI_STRING
*Progress
,
332 OUT EFI_STRING
*Results
337 NIC_IP4_CONFIG_INFO
*IfrDeviceNvData
;
338 IP4_FORM_CALLBACK_INFO
*Private
;
339 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
340 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
342 if (Request
== NULL
) {
343 return EFI_INVALID_PARAMETER
;
349 // Check Request data in <ConfigHdr>.
351 if (!HiiIsConfigHdrMatch (Request
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
352 return EFI_NOT_FOUND
;
355 Private
= IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
356 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_IP4FORM_CALLBACK_INFO (Private
);
358 IfrDeviceNvData
= AllocateZeroPool (NIC_ITEM_CONFIG_SIZE
);
359 if (IfrDeviceNvData
== NULL
) {
360 return EFI_OUT_OF_RESOURCES
;
363 Status
= EfiNicIp4ConfigGetInfo (Ip4ConfigInstance
, &ConfigLen
, IfrDeviceNvData
);
364 if (EFI_ERROR (Status
)) {
365 FreePool (IfrDeviceNvData
);
366 return EFI_NOT_FOUND
;
370 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
372 HiiConfigRouting
= Private
->ConfigRouting
;
373 Status
= HiiConfigRouting
->BlockToConfig (
376 (UINT8
*) IfrDeviceNvData
,
377 NIC_ITEM_CONFIG_SIZE
,
382 FreePool (IfrDeviceNvData
);
388 This function applies changes in a driver's configuration.
389 Input is a Configuration, which has the routing data for this
390 driver followed by name / value configuration pairs. The driver
391 must apply those pairs to its configurable storage. If the
392 driver's configuration is stored in a linear block of data
393 and the driver's name / value pairs are in <BlockConfig>
394 format, it may use the ConfigToBlock helper function (above) to
395 simplify the job. Currently not implemented.
397 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
398 @param[in] Configuration A null-terminated Unicode string in
399 <ConfigString> format.
400 @param[out] Progress A pointer to a string filled in with the
401 offset of the most recent '&' before the
402 first failing name / value pair (or the
403 beginn ing of the string if the failure
404 is in the first name / value pair) or
405 the terminating NULL if all was
408 @retval EFI_SUCCESS The results have been distributed or are
409 awaiting distribution.
410 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
411 parts of the results that must be
412 stored awaiting possible future
414 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
415 Results parameter would result
416 in this type of error.
417 @retval EFI_NOT_FOUND Target for the specified routing data
422 Ip4DeviceRouteConfig (
423 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
424 IN CONST EFI_STRING Configuration
,
425 OUT EFI_STRING
*Progress
430 NIC_IP4_CONFIG_INFO
*IfrDeviceNvData
;
431 NIC_IP4_CONFIG_INFO
*NicInfo
;
432 IP4_FORM_CALLBACK_INFO
*Private
;
433 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
434 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
435 EFI_MAC_ADDRESS ZeroMac
;
437 if (Configuration
== NULL
) {
438 return EFI_INVALID_PARAMETER
;
441 *Progress
= Configuration
;
444 // Check Routing data in <ConfigHdr>.
446 if (!HiiIsConfigHdrMatch (Configuration
, &gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
)) {
447 return EFI_NOT_FOUND
;
450 Private
= IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
451 Ip4ConfigInstance
= IP4_CONFIG_INSTANCE_FROM_IP4FORM_CALLBACK_INFO (Private
);
453 IfrDeviceNvData
= AllocateZeroPool (NIC_ITEM_CONFIG_SIZE
);
454 if (IfrDeviceNvData
== NULL
) {
455 return EFI_OUT_OF_RESOURCES
;
459 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
461 HiiConfigRouting
= Private
->ConfigRouting
;
462 BufferSize
= NIC_ITEM_CONFIG_SIZE
;
463 Status
= HiiConfigRouting
->ConfigToBlock (
466 (UINT8
*) IfrDeviceNvData
,
470 if (!EFI_ERROR (Status
)) {
471 ZeroMem (&ZeroMac
, sizeof (EFI_MAC_ADDRESS
));
472 if (CompareMem (&IfrDeviceNvData
->NicAddr
.MacAddr
, &ZeroMac
, IfrDeviceNvData
->NicAddr
.Len
) != 0) {
473 BufferSize
= sizeof (NIC_IP4_CONFIG_INFO
) + sizeof (EFI_IP4_ROUTE_TABLE
) * IfrDeviceNvData
->Ip4Info
.RouteTableSize
;
474 NicInfo
= AllocateCopyPool (BufferSize
, IfrDeviceNvData
);
475 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NicInfo
, TRUE
);
477 Status
= EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NULL
, TRUE
);
481 FreePool (IfrDeviceNvData
);
487 This function allows the caller to request the current
488 configuration for one or more named elements. The resulting
489 string is in <ConfigAltResp> format. Any and all alternative
490 configuration strings shall also be appended to the end of the
491 current configuration string. If they are, they must appear
492 after the current configuration. They must contain the same
493 routing (GUID, NAME, PATH) as the current configuration string.
494 They must have an additional description indicating the type of
495 alternative configuration the string represents,
496 "ALTCFG=<StringToken>". That <StringToken> (when
497 converted from Hex UNICODE to binary) is a reference to a
498 string in the associated string pack.
500 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
501 @param[in] Request A null-terminated Unicode string in
502 <ConfigRequest> format. Note that this
503 includes the routing information as well as
504 the configurable name / value pairs. It is
505 invalid for this string to be in
506 <MultiConfigRequest> format.
507 @param[out] Progress On return, points to a character in the
508 Request string. Points to the string's null
509 terminator if request was successful. Points
510 to the most recent "&" before the first
511 failing name / value pair (or the beginning
512 of the string if the failure is in the first
513 name / value pair) if the request was not
515 @param[out] Results A null-terminated Unicode string in
516 <ConfigAltResp> format which has all values
517 filled in for the names in the Request string.
518 String to be allocated by the called function.
520 @retval EFI_SUCCESS The Results string is filled with the
521 values corresponding to all requested
523 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
524 parts of the results that must be
525 stored awaiting possible future
527 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
528 for the Request parameter
529 would result in this type of
530 error. In this case, the
531 Progress parameter would be
533 @retval EFI_NOT_FOUND Routing data doesn't match any
534 known driver. Progress set to the
535 first character in the routing header.
536 Note: There is no requirement that the
537 driver validate the routing data. It
538 must skip the <ConfigHdr> in order to
540 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
541 to most recent & before the
542 error or the beginning of the
544 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
545 to the & before the name in
546 question.Currently not implemented.
550 Ip4FormExtractConfig (
551 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
552 IN CONST EFI_STRING Request
,
553 OUT EFI_STRING
*Progress
,
554 OUT EFI_STRING
*Results
558 return EFI_NOT_FOUND
;
562 This function applies changes in a driver's configuration.
563 Input is a Configuration, which has the routing data for this
564 driver followed by name / value configuration pairs. The driver
565 must apply those pairs to its configurable storage. If the
566 driver's configuration is stored in a linear block of data
567 and the driver's name / value pairs are in <BlockConfig>
568 format, it may use the ConfigToBlock helper function (above) to
569 simplify the job. Currently not implemented.
571 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
572 @param[in] Configuration A null-terminated Unicode string in
573 <ConfigString> format.
574 @param[out] Progress A pointer to a string filled in with the
575 offset of the most recent '&' before the
576 first failing name / value pair (or the
577 beginn ing of the string if the failure
578 is in the first name / value pair) or
579 the terminating NULL if all was
582 @retval EFI_SUCCESS The results have been distributed or are
583 awaiting distribution.
584 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
585 parts of the results that must be
586 stored awaiting possible future
588 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
589 Results parameter would result
590 in this type of error.
591 @retval EFI_NOT_FOUND Target for the specified routing data
597 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
598 IN CONST EFI_STRING Configuration
,
599 OUT EFI_STRING
*Progress
602 return EFI_NOT_FOUND
;
606 This function is called to provide results data to the driver.
607 This data consists of a unique key that is used to identify
608 which data is either being passed back or being asked for.
610 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
611 @param[in] Action Specifies the type of action taken by the browser.
612 @param[in] QuestionId A unique value which is sent to the original
613 exporting driver so that it can identify the type
614 of data to expect. The format of the data tends to
615 vary based on the opcode that enerated the callback.
616 @param[in] Type The type of value for the question.
617 @param[in] Value A pointer to the data being sent to the original
619 @param[out] ActionRequest On return, points to the action requested by the
622 @retval EFI_SUCCESS The callback successfully handled the action.
623 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
624 variable and its data.
625 @retval EFI_DEVICE_ERROR The variable could not be saved.
626 @retval EFI_UNSUPPORTED The specified Action is not supported by the
627 callback.Currently not implemented.
628 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
629 @retval Others Other errors as indicated.
634 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
635 IN EFI_BROWSER_ACTION Action
,
636 IN EFI_QUESTION_ID QuestionId
,
638 IN EFI_IFR_TYPE_VALUE
*Value
,
639 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
642 IP4_CONFIG_INSTANCE
*Ip4ConfigInstance
;
643 IP4_FORM_CALLBACK_INFO
*Private
;
644 CHAR8 Ip4String
[IP4_STR_MAX_SIZE
];
645 CHAR16 PortString
[128];
646 EFI_STRING_ID DeviceFormTitleToken
;
647 IP4_CONFIG_IFR_NVDATA
*IfrFormNvData
;
648 IP4CONFIG_FORM_ENTRY
*ConfigFormEntry
;
649 EFI_IP_ADDRESS HostIp
;
650 EFI_IP_ADDRESS SubnetMask
;
651 EFI_IP_ADDRESS Gateway
;
654 NIC_IP4_CONFIG_INFO
*NicInfo
;
657 ConfigFormEntry
= NULL
;
659 Private
= IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
661 IfrFormNvData
= AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA
));
662 if (IfrFormNvData
== NULL
) {
663 return EFI_OUT_OF_RESOURCES
;
667 // Retrive uncommitted data from Browser
669 if (!HiiGetBrowserData (&gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, sizeof (IP4_CONFIG_IFR_NVDATA
), (UINT8
*) IfrFormNvData
)) {
670 FreePool (IfrFormNvData
);
671 return EFI_NOT_FOUND
;
674 Status
= EFI_SUCCESS
;
676 switch (QuestionId
) {
678 case KEY_DHCP_ENABLE
:
679 if (IfrFormNvData
->DhcpEnable
== 0) {
680 Private
->Current
->SessionConfigData
.Enabled
= FALSE
;
682 Private
->Current
->SessionConfigData
.Enabled
= TRUE
;
688 UnicodeStrToAsciiStr (IfrFormNvData
->StationAddress
, Ip4String
);
689 Status
= Ip4AsciiStrToIp (Ip4String
, &HostIp
.v4
);
690 if (EFI_ERROR (Status
) || !Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
691 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid IP address!", NULL
);
692 Status
= EFI_INVALID_PARAMETER
;
694 CopyMem (&Private
->Current
->SessionConfigData
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
699 case KEY_SUBNET_MASK
:
700 UnicodeStrToAsciiStr (IfrFormNvData
->SubnetMask
, Ip4String
);
701 Status
= Ip4AsciiStrToIp (Ip4String
, &SubnetMask
.v4
);
702 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
703 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid SubnetMask!", NULL
);
704 Status
= EFI_INVALID_PARAMETER
;
706 CopyMem (&Private
->Current
->SessionConfigData
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
712 UnicodeStrToAsciiStr (IfrFormNvData
->GatewayAddress
, Ip4String
);
713 Status
= Ip4AsciiStrToIp (Ip4String
, &Gateway
.v4
);
714 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !Ip4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
715 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Invalid Gateway!", NULL
);
716 Status
= EFI_INVALID_PARAMETER
;
718 CopyMem (&Private
->Current
->SessionConfigData
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
723 case KEY_SAVE_CHANGES
:
724 Ip4ConfigInstance
= Private
->Current
->Ip4ConfigInstance
;
725 NicInfo
= AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO
) + 2 * sizeof (EFI_IP4_ROUTE_TABLE
));
726 NicInfo
->Ip4Info
.RouteTable
= (EFI_IP4_ROUTE_TABLE
*) (NicInfo
+ 1);
728 if (!Private
->Current
->SessionConfigData
.Enabled
) {
729 CopyMem (&HostIp
.v4
, &Private
->Current
->SessionConfigData
.LocalIp
, sizeof (HostIp
.v4
));
730 CopyMem (&SubnetMask
.v4
, &Private
->Current
->SessionConfigData
.SubnetMask
, sizeof (SubnetMask
.v4
));
731 CopyMem (&Gateway
.v4
, &Private
->Current
->SessionConfigData
.Gateway
, sizeof (Gateway
.v4
));
733 if ((Gateway
.Addr
[0] != 0)) {
734 if (SubnetMask
.Addr
[0] == 0) {
735 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Gateway address is set but subnet mask is zero.", NULL
);
736 Status
= EFI_INVALID_PARAMETER
;
738 } else if (!IP4_NET_EQUAL (HostIp
.Addr
[0], Gateway
.Addr
[0], SubnetMask
.Addr
[0])) {
739 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Local IP and Gateway are not in the same subnet.", NULL
);
740 Status
= EFI_INVALID_PARAMETER
;
745 NicInfo
->Source
= IP4_CONFIG_SOURCE_STATIC
;
746 NicInfo
->Ip4Info
.RouteTableSize
= 2;
748 CopyMem (&NicInfo
->Ip4Info
.StationAddress
, &HostIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
749 CopyMem (&NicInfo
->Ip4Info
.SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
751 Ip
.Addr
[0] = HostIp
.Addr
[0] & SubnetMask
.Addr
[0];
753 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[0].SubnetAddress
, &Ip
.v4
, sizeof (EFI_IPv4_ADDRESS
));
754 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[0].SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
755 CopyMem (&NicInfo
->Ip4Info
.RouteTable
[1].GatewayAddress
, &Gateway
.v4
, sizeof (EFI_IPv4_ADDRESS
));
757 NicInfo
->Source
= IP4_CONFIG_SOURCE_DHCP
;
760 NicInfo
->Perment
= TRUE
;
761 CopyMem (&NicInfo
->NicAddr
, &Ip4ConfigInstance
->NicAddr
, sizeof (NIC_ADDR
));
763 EfiNicIp4ConfigSetInfo (Ip4ConfigInstance
, NicInfo
, TRUE
);
765 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
769 if ((QuestionId
>= KEY_DEVICE_ENTRY_BASE
) && (QuestionId
< (mNumberOfIp4Devices
+ KEY_DEVICE_ENTRY_BASE
))) {
771 // In case goto the device configuration form, update the device form title.
773 ConfigFormEntry
= Ip4GetConfigFormEntryByIndex ((UINT32
) (QuestionId
- KEY_DEVICE_ENTRY_BASE
));
774 ASSERT (ConfigFormEntry
!= NULL
);
776 Ip4ConfigInstance
= ConfigFormEntry
->Ip4ConfigInstance
;
778 UnicodeSPrint (PortString
, (UINTN
) 128, L
"Port %s", ConfigFormEntry
->MacString
);
779 DeviceFormTitleToken
= (EFI_STRING_ID
) STR_IP4_DEVICE_FORM_TITLE
;
780 HiiSetString (Private
->RegisteredHandle
, DeviceFormTitleToken
, PortString
, NULL
);
782 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance
, IfrFormNvData
);
784 Private
->Current
= ConfigFormEntry
;
790 if (!EFI_ERROR (Status
)) {
793 // Pass changed uncommitted data back to Form Browser
795 HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, sizeof (IP4_CONFIG_IFR_NVDATA
), (UINT8
*) IfrFormNvData
, NULL
);
798 FreePool (IfrFormNvData
);
803 Install HII Config Access protocol for network device and allocate resource.
805 @param[in] Instance The IP4 Config instance.
807 @retval EFI_SUCCESS The HII Config Access protocol is installed.
808 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
809 @retval Others Other errors as indicated.
812 Ip4ConfigDeviceInit (
813 IN IP4_CONFIG_INSTANCE
*Instance
817 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
818 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
820 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**)&HiiDatabase
);
821 if (EFI_ERROR (Status
)) {
825 CallbackInfo
= &Instance
->Ip4FormCallbackInfo
;
827 CallbackInfo
->Signature
= IP4CONFIG_FORM_CALLBACK_INFO_SIGNATURE
;
828 CallbackInfo
->HiiDatabase
= HiiDatabase
;
830 CallbackInfo
->ConfigAccess
.ExtractConfig
= Ip4DeviceExtractConfig
;
831 CallbackInfo
->ConfigAccess
.RouteConfig
= Ip4DeviceRouteConfig
;
832 CallbackInfo
->ConfigAccess
.Callback
= NULL
;
834 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**)&CallbackInfo
->ConfigRouting
);
835 if (EFI_ERROR (Status
)) {
839 CallbackInfo
->DriverHandle
= Instance
->Controller
;
841 // Install Device Path Protocol and Config Access protocol to driver handle
843 Status
= gBS
->InstallMultipleProtocolInterfaces (
844 &CallbackInfo
->DriverHandle
,
845 &gEfiHiiConfigAccessProtocolGuid
,
846 &CallbackInfo
->ConfigAccess
,
849 ASSERT_EFI_ERROR (Status
);
855 Uninstall HII Config Access protocol for network device and free resource.
857 @param[in] Instance The IP4 Config instance.
859 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.
860 @retval Others Other errors as indicated.
863 Ip4ConfigDeviceUnload (
864 IN IP4_CONFIG_INSTANCE
*Instance
867 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
869 CallbackInfo
= &Instance
->Ip4FormCallbackInfo
;
871 Ip4ConfigUpdateForm (Instance
, FALSE
);
874 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
876 gBS
->UninstallMultipleProtocolInterfaces (
877 CallbackInfo
->DriverHandle
,
878 &gEfiHiiConfigAccessProtocolGuid
,
879 &CallbackInfo
->ConfigAccess
,
887 Unload the network configuration form, this includes: delete all the network
888 device configuration entries, uninstall the form callback protocol and
889 free the resources used.
891 @retval EFI_SUCCESS The network configuration form is unloaded.
894 Ip4ConfigFormUnload (
898 IP4CONFIG_FORM_ENTRY
*ConfigFormEntry
;
900 while (!IsListEmpty (&mIp4ConfigFormList
)) {
902 // Uninstall the device forms as the network driver instance may fail to
903 // control the controller but still install the device configuration form.
904 // In such case, upon driver unloading, the driver instance's driverbinding.
905 // stop () won't be called, so we have to take this chance here to uninstall
908 ConfigFormEntry
= NET_LIST_USER_STRUCT (mIp4ConfigFormList
.ForwardLink
, IP4CONFIG_FORM_ENTRY
, Link
);
909 Ip4ConfigUpdateForm (ConfigFormEntry
->Ip4ConfigInstance
, FALSE
);
913 // Remove HII package list
915 mCallbackInfo
->HiiDatabase
->RemovePackageList (
916 mCallbackInfo
->HiiDatabase
,
917 mCallbackInfo
->RegisteredHandle
921 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
923 gBS
->UninstallMultipleProtocolInterfaces (
924 mCallbackInfo
->DriverHandle
,
925 &gEfiDevicePathProtocolGuid
,
926 &mIp4ConifgHiiVendorDevicePath
,
927 &gEfiHiiConfigAccessProtocolGuid
,
928 &mCallbackInfo
->ConfigAccess
,
932 FreePool (mCallbackInfo
);
938 Updates the network configuration form to add/delete an entry for the network
939 device specified by the Instance.
941 @param[in] Instance The IP4 Config instance.
942 @param[in] AddForm Whether to add or delete a form entry.
944 @retval EFI_SUCCESS The network configuration form is updated.
945 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
946 @retval Others Other errors as indicated.
949 Ip4ConfigUpdateForm (
950 IN IP4_CONFIG_INSTANCE
*Instance
,
955 IP4CONFIG_FORM_ENTRY
*ConfigFormEntry
;
956 BOOLEAN EntryExisted
;
958 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
959 CHAR16 PortString
[128];
961 VOID
*StartOpCodeHandle
;
962 VOID
*EndOpCodeHandle
;
963 EFI_IFR_GUID_LABEL
*StartLabel
;
964 EFI_IFR_GUID_LABEL
*EndLabel
;
966 ConfigFormEntry
= NULL
;
967 EntryExisted
= FALSE
;
969 NET_LIST_FOR_EACH (Entry
, &mIp4ConfigFormList
) {
970 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, IP4CONFIG_FORM_ENTRY
, Link
);
972 if (ConfigFormEntry
->Controller
== Instance
->Controller
) {
985 ConfigFormEntry
= (IP4CONFIG_FORM_ENTRY
*) AllocateZeroPool (sizeof (IP4CONFIG_FORM_ENTRY
));
986 if (ConfigFormEntry
== NULL
) {
987 return EFI_OUT_OF_RESOURCES
;
990 ConfigFormEntry
->Ip4ConfigInstance
= Instance
;
991 InitializeListHead (&ConfigFormEntry
->Link
);
992 ConfigFormEntry
->Controller
= Instance
->Controller
;
995 // Get the simple network protocol and convert the MAC address into
996 // the formatted string.
998 Status
= gBS
->HandleProtocol (
999 Instance
->Controller
,
1000 &gEfiSimpleNetworkProtocolGuid
,
1003 ASSERT (Status
== EFI_SUCCESS
);
1005 Ip4MacAddrToStr (&Snp
->Mode
->PermanentAddress
, Snp
->Mode
->HwAddressSize
, ConfigFormEntry
->MacString
);
1008 // Compose the Port string and create a new EFI_STRING_ID.
1010 UnicodeSPrint (PortString
, 128, L
"%s %s", Instance
->NicName
, ConfigFormEntry
->MacString
);
1011 ConfigFormEntry
->PortTitleToken
= HiiSetString (mCallbackInfo
->RegisteredHandle
, 0, PortString
, NULL
);
1014 // Compose the help string of this port and create a new EFI_STRING_ID.
1016 UnicodeSPrint (PortString
, 128, L
"Set the network parameters on eth%d %s", 0, ConfigFormEntry
->MacString
);
1017 ConfigFormEntry
->PortTitleHelpToken
= HiiSetString (mCallbackInfo
->RegisteredHandle
, 0, PortString
, NULL
);
1019 InsertTailList (&mIp4ConfigFormList
, &ConfigFormEntry
->Link
);
1020 mNumberOfIp4Devices
++;
1023 ASSERT (EntryExisted
);
1025 mNumberOfIp4Devices
--;
1026 RemoveEntryList (&ConfigFormEntry
->Link
);
1027 gBS
->FreePool (ConfigFormEntry
);
1031 // Init OpCode Handle
1033 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1034 ASSERT (StartOpCodeHandle
!= NULL
);
1036 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1037 ASSERT (EndOpCodeHandle
!= NULL
);
1040 // Create Hii Extend Label OpCode as the start opcode
1042 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1043 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1044 StartLabel
->Number
= DEVICE_ENTRY_LABEL
;
1047 // Create Hii Extend Label OpCode as the end opcode
1049 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1050 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1051 EndLabel
->Number
= LABEL_END
;
1056 NET_LIST_FOR_EACH (Entry
, &mIp4ConfigFormList
) {
1057 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, IP4CONFIG_FORM_ENTRY
, Link
);
1059 HiiCreateGotoOpCode (
1060 StartOpCodeHandle
, // Container for dynamic created opcodes
1061 FORMID_DEVICE_FORM
, // Target Form ID
1062 ConfigFormEntry
->PortTitleToken
, // Prompt text
1063 ConfigFormEntry
->PortTitleHelpToken
, // Help text
1064 EFI_IFR_FLAG_CALLBACK
, // Question flag
1065 (UINT16
)(KEY_DEVICE_ENTRY_BASE
+ FormIndex
) // Question ID
1072 mCallbackInfo
->RegisteredHandle
,
1073 &gEfiNicIp4ConfigVariableGuid
,
1075 StartOpCodeHandle
, // Label DEVICE_ENTRY_LABEL
1076 EndOpCodeHandle
// LABEL_END
1079 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1080 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1086 Initialize the network configuration form, this includes: delete all the network
1087 device configuration entries, install the form callback protocol and
1088 allocate the resources used.
1090 @retval EFI_SUCCESS The network configuration form is unloaded.
1091 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1099 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
1100 IP4_FORM_CALLBACK_INFO
*CallbackInfo
;
1102 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**)&HiiDatabase
);
1103 if (EFI_ERROR (Status
)) {
1107 CallbackInfo
= (IP4_FORM_CALLBACK_INFO
*) AllocateZeroPool (sizeof (IP4_FORM_CALLBACK_INFO
));
1108 if (CallbackInfo
== NULL
) {
1109 return EFI_OUT_OF_RESOURCES
;
1112 CallbackInfo
->Signature
= IP4CONFIG_FORM_CALLBACK_INFO_SIGNATURE
;
1113 CallbackInfo
->HiiDatabase
= HiiDatabase
;
1115 CallbackInfo
->ConfigAccess
.ExtractConfig
= Ip4FormExtractConfig
;
1116 CallbackInfo
->ConfigAccess
.RouteConfig
= Ip4FormRouteConfig
;
1117 CallbackInfo
->ConfigAccess
.Callback
= Ip4FormCallback
;
1119 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**)&CallbackInfo
->ConfigRouting
);
1120 if (EFI_ERROR (Status
)) {
1124 CallbackInfo
->DriverHandle
= NULL
;
1126 // Install Device Path Protocol and Config Access protocol to driver handle
1128 Status
= gBS
->InstallMultipleProtocolInterfaces (
1129 &CallbackInfo
->DriverHandle
,
1130 &gEfiDevicePathProtocolGuid
,
1131 &mIp4ConifgHiiVendorDevicePath
,
1132 &gEfiHiiConfigAccessProtocolGuid
,
1133 &CallbackInfo
->ConfigAccess
,
1136 ASSERT_EFI_ERROR (Status
);
1139 // Publish our HII data
1141 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1142 &gEfiNicIp4ConfigVariableGuid
,
1143 CallbackInfo
->DriverHandle
,
1144 Ip4ConfigDxeStrings
,
1148 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1149 return EFI_OUT_OF_RESOURCES
;
1152 mCallbackInfo
= CallbackInfo
;