2 The implementation of EFI IPv4 Configuration II Protocol.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 LIST_ENTRY mIp4Config2InstanceList
= {&mIp4Config2InstanceList
, &mIp4Config2InstanceList
};
21 The event process routine when the DHCPv4 service binding protocol is installed
24 @param[in] Event Not used.
25 @param[in] Context Pointer to the IP4 config2 instance data.
30 Ip4Config2OnDhcp4SbInstalled (
36 Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.
38 @param[in, out] Instance The buffer of IP4 config2 instance to be freed.
40 @retval EFI_SUCCESS The child was successfully destroyed.
41 @retval Others Failed to destroy the child.
45 Ip4Config2DestroyDhcp4 (
46 IN OUT IP4_CONFIG2_INSTANCE
*Instance
51 EFI_DHCP4_PROTOCOL
*Dhcp4
;
53 Dhcp4
= Instance
->Dhcp4
;
54 ASSERT (Dhcp4
!= NULL
);
57 Dhcp4
->Configure (Dhcp4
, NULL
);
58 Instance
->Dhcp4
= NULL
;
60 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
63 // Close DHCPv4 protocol and destroy the child.
65 Status
= gBS
->CloseProtocol (
66 Instance
->Dhcp4Handle
,
67 &gEfiDhcp4ProtocolGuid
,
71 if (EFI_ERROR (Status
)) {
75 Status
= NetLibDestroyServiceChild (
78 &gEfiDhcp4ServiceBindingProtocolGuid
,
82 Instance
->Dhcp4Handle
= NULL
;
88 Update the current policy to NewPolicy. During the transition
89 period, the default router list
90 and address list in all interfaces will be released.
92 @param[in] IpSb The IP4 service binding instance.
93 @param[in] NewPolicy The new policy to be updated to.
97 Ip4Config2OnPolicyChanged (
99 IN EFI_IP4_CONFIG2_POLICY NewPolicy
103 IP4_ROUTE_TABLE
*RouteTable
;
106 // Currently there are only two policies: static and dhcp. Regardless of
107 // what transition is going on, i.e., static -> dhcp and dhcp ->
108 // static, we have to free default router table and all addresses.
111 if (IpSb
->DefaultInterface
!= NULL
) {
112 if (IpSb
->DefaultRouteTable
!= NULL
) {
113 Ip4FreeRouteTable (IpSb
->DefaultRouteTable
);
114 IpSb
->DefaultRouteTable
= NULL
;
117 Ip4CancelReceive (IpSb
->DefaultInterface
);
119 Ip4FreeInterface (IpSb
->DefaultInterface
, NULL
);
120 IpSb
->DefaultInterface
= NULL
;
123 Ip4CleanAssembleTable (&IpSb
->Assemble
);
126 // Create new default interface and route table.
128 IpIf
= Ip4CreateInterface (IpSb
->Mnp
, IpSb
->Controller
, IpSb
->Image
);
133 RouteTable
= Ip4CreateRouteTable ();
134 if (RouteTable
== NULL
) {
135 Ip4FreeInterface (IpIf
, NULL
);
139 IpSb
->DefaultInterface
= IpIf
;
140 InsertHeadList (&IpSb
->Interfaces
, &IpIf
->Link
);
141 IpSb
->DefaultRouteTable
= RouteTable
;
142 Ip4ReceiveFrame (IpIf
, NULL
, Ip4AccpetFrame
, IpSb
);
144 if (IpSb
->State
== IP4_SERVICE_CONFIGED
) {
145 IpSb
->State
= IP4_SERVICE_UNSTARTED
;
149 // Start the dhcp configuration.
151 if (NewPolicy
== Ip4Config2PolicyDhcp
) {
152 Ip4StartAutoConfig (&IpSb
->Ip4Config2Instance
);
158 Signal the registered event. It is the callback routine for NetMapIterate.
160 @param[in] Map Points to the list of registered event.
161 @param[in] Item The registered event.
162 @param[in] Arg Not used.
164 @retval EFI_SUCCESS The event was signaled successfully.
168 Ip4Config2SignalEvent (
170 IN NET_MAP_ITEM
*Item
,
174 gBS
->SignalEvent ((EFI_EVENT
) Item
->Key
);
180 Read the configuration data from variable storage according to the VarName and
181 gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the
182 data is corrupted, it clears the variable data to ZERO. Othewise, it outputs the
183 configuration data to IP4_CONFIG2_INSTANCE.
185 @param[in] VarName The pointer to the variable name
186 @param[in, out] Instance The pointer to the IP4 config2 instance data.
188 @retval EFI_NOT_FOUND The variable can not be found or already corrupted.
189 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.
190 @retval EFI_SUCCESS The configuration data was retrieved successfully.
194 Ip4Config2ReadConfigData (
196 IN OUT IP4_CONFIG2_INSTANCE
*Instance
201 IP4_CONFIG2_VARIABLE
*Variable
;
202 IP4_CONFIG2_DATA_ITEM
*DataItem
;
204 IP4_CONFIG2_DATA_RECORD DataRecord
;
208 // Try to read the configuration variable.
211 Status
= gRT
->GetVariable (
213 &gEfiIp4Config2ProtocolGuid
,
219 if (Status
== EFI_BUFFER_TOO_SMALL
) {
221 // Allocate buffer and read the config variable.
223 Variable
= AllocatePool (VarSize
);
224 if (Variable
== NULL
) {
225 return EFI_OUT_OF_RESOURCES
;
228 Status
= gRT
->GetVariable (
230 &gEfiIp4Config2ProtocolGuid
,
235 if (EFI_ERROR (Status
) || (UINT16
) (~NetblockChecksum ((UINT8
*) Variable
, (UINT32
) VarSize
)) != 0) {
237 // GetVariable still error or the variable is corrupted.
238 // Fall back to the default value.
243 // Remove the problematic variable and return EFI_NOT_FOUND, a new
244 // variable will be set again.
248 &gEfiIp4Config2ProtocolGuid
,
249 IP4_CONFIG2_VARIABLE_ATTRIBUTE
,
254 return EFI_NOT_FOUND
;
258 for (Index
= 0; Index
< Variable
->DataRecordCount
; Index
++) {
260 CopyMem (&DataRecord
, &Variable
->DataRecord
[Index
], sizeof (DataRecord
));
262 DataItem
= &Instance
->DataItem
[DataRecord
.DataType
];
263 if (DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
) &&
264 (DataItem
->DataSize
!= DataRecord
.DataSize
)
267 // Perhaps a corrupted data record...
272 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
)) {
274 // This data item has variable length data.
276 DataItem
->Data
.Ptr
= AllocatePool (DataRecord
.DataSize
);
277 if (DataItem
->Data
.Ptr
== NULL
) {
279 // no memory resource
285 Data
= (CHAR8
*) Variable
+ DataRecord
.Offset
;
286 CopyMem (DataItem
->Data
.Ptr
, Data
, DataRecord
.DataSize
);
288 DataItem
->DataSize
= DataRecord
.DataSize
;
289 DataItem
->Status
= EFI_SUCCESS
;
300 Write the configuration data from IP4_CONFIG2_INSTANCE to variable storage.
302 @param[in] VarName The pointer to the variable name.
303 @param[in] Instance The pointer to the IP4 config2 instance data.
305 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.
306 @retval EFI_SUCCESS The configuration data is written successfully.
310 Ip4Config2WriteConfigData (
312 IN IP4_CONFIG2_INSTANCE
*Instance
317 IP4_CONFIG2_DATA_ITEM
*DataItem
;
318 IP4_CONFIG2_VARIABLE
*Variable
;
319 IP4_CONFIG2_DATA_RECORD
*DataRecord
;
323 VarSize
= sizeof (IP4_CONFIG2_VARIABLE
) - sizeof (IP4_CONFIG2_DATA_RECORD
);
325 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
327 DataItem
= &Instance
->DataItem
[Index
];
328 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_VOLATILE
) && !EFI_ERROR (DataItem
->Status
)) {
330 VarSize
+= sizeof (IP4_CONFIG2_DATA_RECORD
) + DataItem
->DataSize
;
334 Variable
= AllocatePool (VarSize
);
335 if (Variable
== NULL
) {
336 return EFI_OUT_OF_RESOURCES
;
339 Heap
= (CHAR8
*) Variable
+ VarSize
;
340 Variable
->DataRecordCount
= 0;
342 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
344 DataItem
= &Instance
->DataItem
[Index
];
345 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_VOLATILE
) && !EFI_ERROR (DataItem
->Status
)) {
347 Heap
-= DataItem
->DataSize
;
348 CopyMem (Heap
, DataItem
->Data
.Ptr
, DataItem
->DataSize
);
350 DataRecord
= &Variable
->DataRecord
[Variable
->DataRecordCount
];
351 DataRecord
->DataType
= (EFI_IP4_CONFIG2_DATA_TYPE
) Index
;
352 DataRecord
->DataSize
= (UINT32
) DataItem
->DataSize
;
353 DataRecord
->Offset
= (UINT16
) (Heap
- (CHAR8
*) Variable
);
355 Variable
->DataRecordCount
++;
359 Variable
->Checksum
= 0;
360 Variable
->Checksum
= (UINT16
) ~NetblockChecksum ((UINT8
*) Variable
, (UINT32
) VarSize
);
362 Status
= gRT
->SetVariable (
364 &gEfiIp4Config2ProtocolGuid
,
365 IP4_CONFIG2_VARIABLE_ATTRIBUTE
,
377 Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData.
378 The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the
381 @param[in] IpSb The IP4 service binding instance.
382 @param[out] Table The built IP4 route table.
384 @retval EFI_SUCCESS The route table is successfully build
385 @retval EFI_NOT_FOUND Failed to allocate the memory for the rotue table.
389 Ip4Config2BuildDefaultRouteTable (
390 IN IP4_SERVICE
*IpSb
,
391 OUT EFI_IP4_ROUTE_TABLE
*Table
395 IP4_ROUTE_ENTRY
*RtEntry
;
399 if (IpSb
->DefaultRouteTable
== NULL
) {
400 return EFI_NOT_FOUND
;
403 Count
= IpSb
->DefaultRouteTable
->TotalNum
;
406 return EFI_NOT_FOUND
;
410 // Copy the route entry to EFI route table. Keep the order of
411 // route entry copied from most specific to default route. That
412 // is, interlevel the route entry from the instance's route area
413 // and those from the default route table's route area.
417 for (Index
= IP4_MASK_NUM
- 1; Index
>= 0; Index
--) {
419 NET_LIST_FOR_EACH (Entry
, &(IpSb
->DefaultRouteTable
->RouteArea
[Index
])) {
420 RtEntry
= NET_LIST_USER_STRUCT (Entry
, IP4_ROUTE_ENTRY
, Link
);
422 EFI_IP4 (Table
[Count
].SubnetAddress
) = HTONL (RtEntry
->Dest
& RtEntry
->Netmask
);
423 EFI_IP4 (Table
[Count
].SubnetMask
) = HTONL (RtEntry
->Netmask
);
424 EFI_IP4 (Table
[Count
].GatewayAddress
) = HTONL (RtEntry
->NextHop
);
435 The event process routine when the DHCPv4 service binding protocol is installed
438 @param[in] Event Not used.
439 @param[in] Context The pointer to the IP4 config2 instance data.
444 Ip4Config2OnDhcp4SbInstalled (
449 IP4_CONFIG2_INSTANCE
*Instance
;
451 Instance
= (IP4_CONFIG2_INSTANCE
*) Context
;
453 if ((Instance
->Dhcp4Handle
!= NULL
) || (Instance
->Policy
!= Ip4Config2PolicyDhcp
)) {
455 // The DHCP4 child is already created or the policy is no longer DHCP.
460 Ip4StartAutoConfig (Instance
);
464 Set the station address and subnetmask for the default interface.
466 @param[in] Instance The pointer to the IP4 config2 instance data.
467 @param[in] StationAddress Ip address to be set.
468 @param[in] SubnetMask Subnet to be set.
470 @retval EFI_SUCCESS Set default address successful.
471 @retval Others Some errors occur in setting.
475 Ip4Config2SetDefaultAddr (
476 IN IP4_CONFIG2_INSTANCE
*Instance
,
477 IN IP4_ADDR StationAddress
,
478 IN IP4_ADDR SubnetMask
484 IP4_PROTOCOL
*Ip4Instance
;
485 EFI_ARP_PROTOCOL
*Arp
;
488 IP4_ROUTE_TABLE
*RouteTable
;
490 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
491 IpIf
= IpSb
->DefaultInterface
;
492 ASSERT (IpIf
!= NULL
);
494 if ((IpIf
->Ip
== StationAddress
) && (IpIf
->SubnetMask
== SubnetMask
)) {
495 IpSb
->State
= IP4_SERVICE_CONFIGED
;
500 // The default address is changed, free the previous interface first.
502 if (IpSb
->DefaultRouteTable
!= NULL
) {
503 Ip4FreeRouteTable (IpSb
->DefaultRouteTable
);
504 IpSb
->DefaultRouteTable
= NULL
;
507 Ip4CancelReceive (IpSb
->DefaultInterface
);
508 Ip4FreeInterface (IpSb
->DefaultInterface
, NULL
);
509 IpSb
->DefaultInterface
= NULL
;
511 // Create new default interface and route table.
513 IpIf
= Ip4CreateInterface (IpSb
->Mnp
, IpSb
->Controller
, IpSb
->Image
);
515 return EFI_OUT_OF_RESOURCES
;
518 RouteTable
= Ip4CreateRouteTable ();
519 if (RouteTable
== NULL
) {
520 Ip4FreeInterface (IpIf
, NULL
);
521 return EFI_OUT_OF_RESOURCES
;
524 IpSb
->DefaultInterface
= IpIf
;
525 InsertHeadList (&IpSb
->Interfaces
, &IpIf
->Link
);
526 IpSb
->DefaultRouteTable
= RouteTable
;
527 Ip4ReceiveFrame (IpIf
, NULL
, Ip4AccpetFrame
, IpSb
);
529 if (IpSb
->State
== IP4_SERVICE_CONFIGED
) {
530 IpSb
->State
= IP4_SERVICE_UNSTARTED
;
533 Status
= Ip4SetAddress (IpIf
, StationAddress
, SubnetMask
);
534 if (EFI_ERROR (Status
)) {
538 if (IpIf
->Arp
!= NULL
) {
540 // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address,
541 // but some IP children may have referenced the default interface before it is configured,
542 // these IP instances also consume this ARP protocol so they need to open it BY_CHILD_CONTROLLER.
545 NET_LIST_FOR_EACH (Entry
, &IpIf
->IpInstances
) {
546 Ip4Instance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_PROTOCOL
, AddrLink
, IP4_PROTOCOL_SIGNATURE
);
547 Status
= gBS
->OpenProtocol (
549 &gEfiArpProtocolGuid
,
551 gIp4DriverBinding
.DriverBindingHandle
,
553 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
555 if (EFI_ERROR (Status
)) {
562 IpSb
->DefaultRouteTable
,
569 // Add a route for the connected network.
571 Subnet
= StationAddress
& SubnetMask
;
574 IpSb
->DefaultRouteTable
,
580 IpSb
->State
= IP4_SERVICE_CONFIGED
;
585 Set the station address, subnetmask and gateway address for the default interface.
587 @param[in] Instance The pointer to the IP4 config2 instance data.
588 @param[in] StationAddress Ip address to be set.
589 @param[in] SubnetMask Subnet to be set.
590 @param[in] GatewayAddress Gateway to be set.
592 @retval EFI_SUCCESS Set default If successful.
593 @retval Others Errors occur as indicated.
597 Ip4Config2SetDefaultIf (
598 IN IP4_CONFIG2_INSTANCE
*Instance
,
599 IN IP4_ADDR StationAddress
,
600 IN IP4_ADDR SubnetMask
,
601 IN IP4_ADDR GatewayAddress
607 Status
= Ip4Config2SetDefaultAddr (Instance
, StationAddress
, SubnetMask
);
608 if (EFI_ERROR (Status
)) {
613 // Create a route if there is a default router.
615 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
616 if (GatewayAddress
!= IP4_ALLZERO_ADDRESS
) {
618 IpSb
->DefaultRouteTable
,
630 Release all the DHCP related resources.
632 @param Instance The IP4 config2 instance.
638 Ip4Config2CleanDhcp4 (
639 IN IP4_CONFIG2_INSTANCE
*Instance
644 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
646 if (Instance
->Dhcp4
!= NULL
) {
647 Instance
->Dhcp4
->Stop (Instance
->Dhcp4
);
650 Instance
->Dhcp4Handle
,
651 &gEfiDhcp4ProtocolGuid
,
656 Instance
->Dhcp4
= NULL
;
659 if (Instance
->Dhcp4Handle
!= NULL
) {
660 NetLibDestroyServiceChild (
663 &gEfiDhcp4ServiceBindingProtocolGuid
,
664 Instance
->Dhcp4Handle
667 Instance
->Dhcp4Handle
= NULL
;
670 if (Instance
->Dhcp4Event
!= NULL
) {
671 gBS
->CloseEvent (Instance
->Dhcp4Event
);
672 Instance
->Dhcp4Event
= NULL
;
678 Callback function when DHCP process finished. It will save the
679 retrieved IP configure parameter from DHCP to the NVRam.
681 @param Event The callback event
682 @param Context Opaque context to the callback
689 Ip4Config2OnDhcp4Complete (
694 IP4_CONFIG2_INSTANCE
*Instance
;
695 EFI_DHCP4_MODE_DATA Dhcp4Mode
;
697 IP4_ADDR StationAddress
;
699 IP4_ADDR GatewayAddress
;
701 Instance
= (IP4_CONFIG2_INSTANCE
*) Context
;
702 ASSERT (Instance
->Dhcp4
!= NULL
);
705 // Get the DHCP retrieved parameters
707 Status
= Instance
->Dhcp4
->GetModeData (Instance
->Dhcp4
, &Dhcp4Mode
);
709 if (EFI_ERROR (Status
)) {
713 if (Dhcp4Mode
.State
== Dhcp4Bound
) {
714 StationAddress
= EFI_NTOHL (Dhcp4Mode
.ClientAddress
);
715 SubnetMask
= EFI_NTOHL (Dhcp4Mode
.SubnetMask
);
716 GatewayAddress
= EFI_NTOHL (Dhcp4Mode
.RouterAddress
);
718 Status
= Ip4Config2SetDefaultIf (Instance
, StationAddress
, SubnetMask
, GatewayAddress
);
719 if (EFI_ERROR (Status
)) {
723 Instance
->DhcpSuccess
= TRUE
;
727 Ip4Config2CleanDhcp4 (Instance
);
733 Start the DHCP configuration for this IP service instance.
734 It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the
737 @param[in] Instance The IP4 config2 instance to configure
739 @retval EFI_SUCCESS The auto configuration is successfull started
740 @retval Others Failed to start auto configuration.
745 IN IP4_CONFIG2_INSTANCE
*Instance
749 EFI_DHCP4_PROTOCOL
*Dhcp4
;
750 EFI_DHCP4_MODE_DATA Dhcp4Mode
;
751 EFI_DHCP4_PACKET_OPTION
*OptionList
[1];
752 IP4_CONFIG2_DHCP4_OPTION ParaList
;
756 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
758 if (IpSb
->State
> IP4_SERVICE_UNSTARTED
) {
763 // A host must not invoke DHCP configuration if it is already
764 // participating in the DHCP configuraiton process.
766 if (Instance
->Dhcp4Handle
!= NULL
) {
770 Status
= NetLibCreateServiceChild (
773 &gEfiDhcp4ServiceBindingProtocolGuid
,
774 &Instance
->Dhcp4Handle
777 if (Status
== EFI_UNSUPPORTED
) {
779 // No DHCPv4 Service Binding protocol, register a notify.
781 if (Instance
->Dhcp4SbNotifyEvent
== NULL
) {
782 Instance
->Dhcp4SbNotifyEvent
= EfiCreateProtocolNotifyEvent (
783 &gEfiDhcp4ServiceBindingProtocolGuid
,
785 Ip4Config2OnDhcp4SbInstalled
,
787 &Instance
->Registration
792 if (EFI_ERROR (Status
)) {
796 if (Instance
->Dhcp4SbNotifyEvent
!= NULL
) {
797 gBS
->CloseEvent (Instance
->Dhcp4SbNotifyEvent
);
800 Status
= gBS
->OpenProtocol (
801 Instance
->Dhcp4Handle
,
802 &gEfiDhcp4ProtocolGuid
,
803 (VOID
**) &Instance
->Dhcp4
,
806 EFI_OPEN_PROTOCOL_BY_DRIVER
808 ASSERT_EFI_ERROR (Status
);
812 // Check the current DHCP status, if the DHCP process has
813 // already finished, return now.
815 Dhcp4
= Instance
->Dhcp4
;
816 Status
= Dhcp4
->GetModeData (Dhcp4
, &Dhcp4Mode
);
818 if (Dhcp4Mode
.State
== Dhcp4Bound
) {
819 Ip4Config2OnDhcp4Complete (NULL
, Instance
);
825 // Try to start the DHCP process. Use most of the current
826 // DHCP configuration to avoid problems if some DHCP client
827 // yields the control of this DHCP service to us.
829 ParaList
.Head
.OpCode
= DHCP_TAG_PARA_LIST
;
830 ParaList
.Head
.Length
= 2;
831 ParaList
.Head
.Data
[0] = DHCP_TAG_NETMASK
;
832 ParaList
.Route
= DHCP_TAG_ROUTER
;
833 OptionList
[0] = &ParaList
.Head
;
834 Dhcp4Mode
.ConfigData
.OptionCount
= 1;
835 Dhcp4Mode
.ConfigData
.OptionList
= OptionList
;
837 Status
= Dhcp4
->Configure (Dhcp4
, &Dhcp4Mode
.ConfigData
);
839 if (EFI_ERROR (Status
)) {
844 // Start the DHCP process
846 Status
= gBS
->CreateEvent (
849 Ip4Config2OnDhcp4Complete
,
851 &Instance
->Dhcp4Event
854 if (EFI_ERROR (Status
)) {
858 Status
= Dhcp4
->Start (Dhcp4
, Instance
->Dhcp4Event
);
860 if (EFI_ERROR (Status
)) {
864 IpSb
->State
= IP4_SERVICE_STARTED
;
873 The work function is to get the interface information of the communication
874 device this IP4_CONFIG2_INSTANCE manages.
876 @param[in] Instance Pointer to the IP4 config2 instance data.
877 @param[in, out] DataSize On input, in bytes, the size of Data. On output, in
878 bytes, the size of buffer required to store the specified
880 @param[in] Data The data buffer in which the configuration data is returned.
881 Ignored if DataSize is ZERO.
883 @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified
884 configuration data, and the required size is
885 returned in DataSize.
886 @retval EFI_SUCCESS The specified configuration data was obtained.
890 Ip4Config2GetIfInfo (
891 IN IP4_CONFIG2_INSTANCE
*Instance
,
892 IN OUT UINTN
*DataSize
,
893 IN VOID
*Data OPTIONAL
899 IP4_CONFIG2_DATA_ITEM
*Item
;
900 EFI_IP4_CONFIG2_INTERFACE_INFO
*IfInfo
;
903 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
904 Length
= sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO
);
906 if (IpSb
->DefaultRouteTable
!= NULL
) {
907 Length
+= IpSb
->DefaultRouteTable
->TotalNum
* sizeof (EFI_IP4_ROUTE_TABLE
);
910 if (*DataSize
< Length
) {
912 return EFI_BUFFER_TOO_SMALL
;
916 // Copy the fixed size part of the interface info.
918 Item
= &Instance
->DataItem
[Ip4Config2DataTypeInterfaceInfo
];
919 IfInfo
= (EFI_IP4_CONFIG2_INTERFACE_INFO
*) Data
;
920 CopyMem (IfInfo
, Item
->Data
.Ptr
, sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO
));
923 // Update the address info.
925 if (IpSb
->DefaultInterface
!= NULL
) {
926 Address
= HTONL (IpSb
->DefaultInterface
->Ip
);
927 CopyMem (&IfInfo
->StationAddress
, &Address
, sizeof (EFI_IPv4_ADDRESS
));
928 Address
= HTONL (IpSb
->DefaultInterface
->SubnetMask
);
929 CopyMem (&IfInfo
->SubnetMask
, &Address
, sizeof (EFI_IPv4_ADDRESS
));
932 if (IpSb
->DefaultRouteTable
!= NULL
) {
933 IfInfo
->RouteTableSize
= IpSb
->DefaultRouteTable
->TotalNum
;
934 IfInfo
->RouteTable
= (EFI_IP4_ROUTE_TABLE
*) ((UINT8
*) Data
+ sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO
));
936 Ip4Config2BuildDefaultRouteTable (IpSb
, IfInfo
->RouteTable
);
943 The work function is to set the general configuration policy for the EFI IPv4 network
944 stack that is running on the communication device managed by this IP4_CONFIG2_INSTANCE.
945 The policy will affect other configuration settings.
947 @param[in] Instance Pointer to the IP4 config2 instance data.
948 @param[in] DataSize Size of the buffer pointed to by Data in bytes.
949 @param[in] Data The data buffer to set.
951 @retval EFI_INVALID_PARAMETER The to be set policy is invalid.
952 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
953 @retval EFI_ABORTED The new policy equals the current policy.
954 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
955 network stack was set.
959 Ip4Config2SetPolicy (
960 IN IP4_CONFIG2_INSTANCE
*Instance
,
965 EFI_IP4_CONFIG2_POLICY NewPolicy
;
966 IP4_CONFIG2_DATA_ITEM
*DataItem
;
969 if (DataSize
!= sizeof (EFI_IP4_CONFIG2_POLICY
)) {
970 return EFI_BAD_BUFFER_SIZE
;
973 NewPolicy
= *((EFI_IP4_CONFIG2_POLICY
*) Data
);
975 if (NewPolicy
>= Ip4Config2PolicyMax
) {
976 return EFI_INVALID_PARAMETER
;
979 if (NewPolicy
== Instance
->Policy
) {
982 if (NewPolicy
== Ip4Config2PolicyDhcp
) {
984 // The policy is changed from static to dhcp:
985 // Clean the ManualAddress, Gateway and DnsServers, shrink the variable
986 // data size, and fire up all the related events.
988 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeManualAddress
];
989 if (DataItem
->Data
.Ptr
!= NULL
) {
990 FreePool (DataItem
->Data
.Ptr
);
992 DataItem
->Data
.Ptr
= NULL
;
993 DataItem
->DataSize
= 0;
994 DataItem
->Status
= EFI_NOT_FOUND
;
995 NetMapIterate (&DataItem
->EventMap
, Ip4Config2SignalEvent
, NULL
);
997 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeGateway
];
998 if (DataItem
->Data
.Ptr
!= NULL
) {
999 FreePool (DataItem
->Data
.Ptr
);
1001 DataItem
->Data
.Ptr
= NULL
;
1002 DataItem
->DataSize
= 0;
1003 DataItem
->Status
= EFI_NOT_FOUND
;
1004 NetMapIterate (&DataItem
->EventMap
, Ip4Config2SignalEvent
, NULL
);
1006 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeDnsServer
];
1007 if (DataItem
->Data
.Ptr
!= NULL
) {
1008 FreePool (DataItem
->Data
.Ptr
);
1010 DataItem
->Data
.Ptr
= NULL
;
1011 DataItem
->DataSize
= 0;
1012 DataItem
->Status
= EFI_NOT_FOUND
;
1013 NetMapIterate (&DataItem
->EventMap
, Ip4Config2SignalEvent
, NULL
);
1016 // The policy is changed from dhcp to static. Stop the DHCPv4 process
1017 // and destroy the DHCPv4 child.
1019 if (Instance
->Dhcp4Handle
!= NULL
) {
1020 Ip4Config2DestroyDhcp4 (Instance
);
1026 if (Instance
->Dhcp4Event
!= NULL
) {
1027 gBS
->CloseEvent (Instance
->Dhcp4Event
);
1032 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1033 Ip4Config2OnPolicyChanged (IpSb
, NewPolicy
);
1035 Instance
->Policy
= NewPolicy
;
1041 The work function is to set the station addresses manually for the EFI IPv4
1042 network stack. It is only configurable when the policy is Ip4Config2PolicyStatic.
1044 @param[in] Instance Pointer to the IP4 config2 instance data.
1045 @param[in] DataSize Size of the buffer pointed to by Data in bytes.
1046 @param[in] Data The data buffer to set.
1048 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
1049 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
1050 under the current policy.
1051 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
1052 @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation.
1053 @retval EFI_NOT_READY An asynchrous process is invoked to set the specified
1054 configuration data, and the process is not finished.
1055 @retval EFI_ABORTED The manual addresses to be set equal current
1057 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
1058 network stack was set.
1062 Ip4Config2SetMaunualAddress (
1063 IN IP4_CONFIG2_INSTANCE
*Instance
,
1068 EFI_IP4_CONFIG2_MANUAL_ADDRESS NewAddress
;
1069 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1071 IP4_ADDR StationAddress
;
1072 IP4_ADDR SubnetMask
;
1075 ASSERT (Instance
->DataItem
[Ip4Config2DataTypeManualAddress
].Status
!= EFI_NOT_READY
);
1077 if (((DataSize
% sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS
)) != 0) || (DataSize
== 0)) {
1078 return EFI_BAD_BUFFER_SIZE
;
1081 if (Instance
->Policy
!= Ip4Config2PolicyStatic
) {
1082 return EFI_WRITE_PROTECTED
;
1085 NewAddress
= *((EFI_IP4_CONFIG2_MANUAL_ADDRESS
*) Data
);
1088 // Store the new data, and init the DataItem status to EFI_NOT_READY because
1089 // we may have an asynchronous configuration process.
1091 Ptr
= AllocateCopyPool (DataSize
, Data
);
1093 return EFI_OUT_OF_RESOURCES
;
1096 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeManualAddress
];
1097 if (DataItem
->Data
.Ptr
!= NULL
) {
1098 FreePool (DataItem
->Data
.Ptr
);
1101 DataItem
->Data
.Ptr
= Ptr
;
1102 DataItem
->DataSize
= DataSize
;
1103 DataItem
->Status
= EFI_NOT_READY
;
1105 StationAddress
= EFI_NTOHL (NewAddress
.Address
);
1106 SubnetMask
= EFI_NTOHL (NewAddress
.SubnetMask
);
1108 Status
= Ip4Config2SetDefaultAddr (Instance
, StationAddress
, SubnetMask
);
1109 if (EFI_ERROR (Status
)) {
1113 DataItem
->Status
= EFI_SUCCESS
;
1116 if (EFI_ERROR (DataItem
->Status
)) {
1120 DataItem
->Data
.Ptr
= NULL
;
1127 The work function is to set the gateway addresses manually for the EFI IPv4
1128 network stack that is running on the communication device that this EFI IPv4
1129 Configuration Protocol manages. It is not configurable when the policy is
1130 Ip4Config2PolicyDhcp. The gateway addresses must be unicast IPv4 addresses.
1132 @param[in] Instance The pointer to the IP4 config2 instance data.
1133 @param[in] DataSize The size of the buffer pointed to by Data in bytes.
1134 @param[in] Data The data buffer to set. This points to an array of
1135 EFI_IPv6_ADDRESS instances.
1137 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
1138 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
1139 under the current policy.
1140 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
1141 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to complete the operation.
1142 @retval EFI_ABORTED The manual gateway addresses to be set equal the
1143 current configuration.
1144 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
1145 network stack was set.
1149 Ip4Config2SetGateway (
1150 IN IP4_CONFIG2_INSTANCE
*Instance
,
1156 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1161 EFI_IPv4_ADDRESS
*OldGateway
;
1162 EFI_IPv4_ADDRESS
*NewGateway
;
1163 UINTN OldGatewayCount
;
1164 UINTN NewGatewayCount
;
1169 if ((DataSize
% sizeof (EFI_IPv4_ADDRESS
) != 0) || (DataSize
== 0)) {
1170 return EFI_BAD_BUFFER_SIZE
;
1173 if (Instance
->Policy
!= Ip4Config2PolicyStatic
) {
1174 return EFI_WRITE_PROTECTED
;
1178 NewGateway
= (EFI_IPv4_ADDRESS
*) Data
;
1179 NewGatewayCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1180 for (Index1
= 0; Index1
< NewGatewayCount
; Index1
++) {
1181 CopyMem (&Gateway
, NewGateway
+ Index1
, sizeof (IP4_ADDR
));
1183 if (!NetIp4IsUnicast (NTOHL (Gateway
), 0)) {
1185 return EFI_INVALID_PARAMETER
;
1188 for (Index2
= Index1
+ 1; Index2
< NewGatewayCount
; Index2
++) {
1189 if (EFI_IP4_EQUAL (NewGateway
+ Index1
, NewGateway
+ Index2
)) {
1190 return EFI_INVALID_PARAMETER
;
1195 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1196 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeGateway
];
1197 OldGateway
= DataItem
->Data
.Gateway
;
1198 OldGatewayCount
= DataItem
->DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1202 if (NewGatewayCount
!= OldGatewayCount
) {
1203 Tmp
= AllocatePool (DataSize
);
1205 return EFI_OUT_OF_RESOURCES
;
1211 for (Index1
= 0; Index1
< OldGatewayCount
; Index1
++) {
1213 // Remove this route entry.
1215 CopyMem (&Gateway
, OldGateway
+ Index1
, sizeof (IP4_ADDR
));
1217 IpSb
->DefaultRouteTable
,
1218 IP4_ALLZERO_ADDRESS
,
1219 IP4_ALLZERO_ADDRESS
,
1226 for (Index1
= 0; Index1
< NewGatewayCount
; Index1
++) {
1227 CopyMem (&Gateway
, NewGateway
+ Index1
, sizeof (IP4_ADDR
));
1229 IpSb
->DefaultRouteTable
,
1230 IP4_ALLZERO_ADDRESS
,
1231 IP4_ALLZERO_ADDRESS
,
1239 if (!OneRemoved
&& !OneAdded
) {
1240 DataItem
->Status
= EFI_SUCCESS
;
1245 if (DataItem
->Data
.Ptr
!= NULL
) {
1246 FreePool (DataItem
->Data
.Ptr
);
1248 DataItem
->Data
.Ptr
= Tmp
;
1251 CopyMem (DataItem
->Data
.Ptr
, Data
, DataSize
);
1252 DataItem
->DataSize
= DataSize
;
1253 DataItem
->Status
= EFI_SUCCESS
;
1260 The work function is to set the DNS server list for the EFI IPv4 network
1261 stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL
1262 manages. It is not configurable when the policy is Ip4Config2PolicyDhcp.
1263 The DNS server addresses must be unicast IPv4 addresses.
1265 @param[in] Instance The pointer to the IP4 config2 instance data.
1266 @param[in] DataSize The size of the buffer pointed to by Data in bytes.
1267 @param[in] Data The data buffer to set, points to an array of
1268 EFI_IPv4_ADDRESS instances.
1270 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
1271 @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
1272 under the current policy.
1273 @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
1274 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.
1275 @retval EFI_ABORTED The DNS server addresses to be set equal the current
1277 @retval EFI_SUCCESS The specified configuration data for the EFI IPv4
1278 network stack was set.
1282 Ip4Config2SetDnsServer (
1283 IN IP4_CONFIG2_INSTANCE
*Instance
,
1291 EFI_IPv4_ADDRESS
*OldDns
;
1292 EFI_IPv4_ADDRESS
*NewDns
;
1295 IP4_CONFIG2_DATA_ITEM
*Item
;
1298 IP4_ADDR DnsAddress
;
1300 if ((DataSize
% sizeof (EFI_IPv4_ADDRESS
) != 0) || (DataSize
== 0)) {
1301 return EFI_BAD_BUFFER_SIZE
;
1304 if (Instance
->Policy
!= Ip4Config2PolicyStatic
) {
1305 return EFI_WRITE_PROTECTED
;
1308 Item
= &Instance
->DataItem
[Ip4Config2DataTypeDnsServer
];
1309 NewDns
= (EFI_IPv4_ADDRESS
*) Data
;
1310 OldDns
= Item
->Data
.DnsServers
;
1311 NewDnsCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1312 OldDnsCount
= Item
->DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
1315 if (NewDnsCount
!= OldDnsCount
) {
1316 Tmp
= AllocatePool (DataSize
);
1318 return EFI_OUT_OF_RESOURCES
;
1324 for (NewIndex
= 0; NewIndex
< NewDnsCount
; NewIndex
++) {
1325 CopyMem (&DnsAddress
, NewDns
+ NewIndex
, sizeof (IP4_ADDR
));
1327 if (!NetIp4IsUnicast (NTOHL (DnsAddress
), 0)) {
1329 // The dns server address must be unicast.
1332 return EFI_INVALID_PARAMETER
;
1335 for (Index1
= NewIndex
+ 1; Index1
< NewDnsCount
; Index1
++) {
1336 if (EFI_IP4_EQUAL (NewDns
+ NewIndex
, NewDns
+ Index1
)) {
1338 return EFI_INVALID_PARAMETER
;
1344 // If any address in the new setting is not in the old settings, skip the
1345 // comparision below.
1350 for (OldIndex
= 0; OldIndex
< OldDnsCount
; OldIndex
++) {
1351 if (EFI_IP4_EQUAL (NewDns
+ NewIndex
, OldDns
+ OldIndex
)) {
1353 // If found break out.
1359 if (OldIndex
== OldDnsCount
) {
1364 if (!OneAdded
&& (DataSize
== Item
->DataSize
)) {
1366 // No new item is added and the size is the same.
1368 Item
->Status
= EFI_SUCCESS
;
1372 if (Item
->Data
.Ptr
!= NULL
) {
1373 FreePool (Item
->Data
.Ptr
);
1375 Item
->Data
.Ptr
= Tmp
;
1378 CopyMem (Item
->Data
.Ptr
, Data
, DataSize
);
1379 Item
->DataSize
= DataSize
;
1380 Item
->Status
= EFI_SUCCESS
;
1387 Generate the operational state of the interface this IP4 config2 instance manages
1388 and output in EFI_IP4_CONFIG2_INTERFACE_INFO.
1390 @param[in] IpSb The pointer to the IP4 service binding instance.
1391 @param[out] IfInfo The pointer to the IP4 config2 interface information structure.
1395 Ip4Config2InitIfInfo (
1396 IN IP4_SERVICE
*IpSb
,
1397 OUT EFI_IP4_CONFIG2_INTERFACE_INFO
*IfInfo
1400 IfInfo
->Name
[0] = L
'e';
1401 IfInfo
->Name
[1] = L
't';
1402 IfInfo
->Name
[2] = L
'h';
1403 IfInfo
->Name
[3] = (CHAR16
) (L
'0' + IpSb
->Ip4Config2Instance
.IfIndex
);
1404 IfInfo
->Name
[4] = 0;
1406 IfInfo
->IfType
= IpSb
->SnpMode
.IfType
;
1407 IfInfo
->HwAddressSize
= IpSb
->SnpMode
.HwAddressSize
;
1408 CopyMem (&IfInfo
->HwAddress
, &IpSb
->SnpMode
.CurrentAddress
, IfInfo
->HwAddressSize
);
1412 The event handle routine when DHCPv4 process is finished or is updated.
1414 @param[in] Event Not used.
1415 @param[in] Context The pointer to the IP4 configuration instance data.
1420 Ip4Config2OnDhcp4Event (
1430 Set the configuration for the EFI IPv4 network stack running on the communication
1431 device this EFI_IP4_CONFIG2_PROTOCOL instance manages.
1433 This function is used to set the configuration data of type DataType for the EFI
1434 IPv4 network stack that is running on the communication device that this EFI IPv4
1435 Configuration Protocol instance manages.
1437 DataSize is used to calculate the count of structure instances in the Data for
1438 a DataType in which multiple structure instances are allowed.
1440 This function is always non-blocking. When setting some type of configuration data,
1441 an asynchronous process is invoked to check the correctness of the data, such as
1442 performing Duplicate Address Detection on the manually set local IPv4 addresses.
1443 EFI_NOT_READY is returned immediately to indicate that such an asynchronous process
1444 is invoked, and the process is not finished yet. The caller wanting to get the result
1445 of the asynchronous process is required to call RegisterDataNotify() to register an
1446 event on the specified configuration data. Once the event is signaled, the caller
1447 can call GetData() to obtain the configuration data and know the result.
1448 For other types of configuration data that do not require an asynchronous configuration
1449 process, the result of the operation is immediately returned.
1451 @param[in] This The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1452 @param[in] DataType The type of data to set.
1453 @param[in] DataSize Size of the buffer pointed to by Data in bytes.
1454 @param[in] Data The data buffer to set. The type of the data buffer is
1455 associated with the DataType.
1457 @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
1458 network stack was set successfully.
1459 @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
1462 - One or more fields in Data do not match the requirement of the
1463 data type indicated by DataType.
1464 @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified
1465 configuration data cannot be set under the current policy.
1466 @retval EFI_ACCESS_DENIED Another set operation on the specified configuration
1467 data is already in process.
1468 @retval EFI_NOT_READY An asynchronous process was invoked to set the specified
1469 configuration data, and the process is not finished yet.
1470 @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type
1471 indicated by DataType.
1472 @retval EFI_UNSUPPORTED This DataType is not supported.
1473 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
1474 @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.
1479 EfiIp4Config2SetData (
1480 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1481 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1488 IP4_CONFIG2_INSTANCE
*Instance
;
1491 if ((This
== NULL
) || (Data
== NULL
)) {
1492 return EFI_INVALID_PARAMETER
;
1495 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1496 return EFI_UNSUPPORTED
;
1499 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1500 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1501 NET_CHECK_SIGNATURE (IpSb
, IP4_SERVICE_SIGNATURE
);
1504 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1506 Status
= Instance
->DataItem
[DataType
].Status
;
1507 if (Status
!= EFI_NOT_READY
) {
1509 if (Instance
->DataItem
[DataType
].SetData
== NULL
) {
1511 // This type of data is readonly.
1513 Status
= EFI_WRITE_PROTECTED
;
1516 Status
= Instance
->DataItem
[DataType
].SetData (Instance
, DataSize
, Data
);
1517 if (!EFI_ERROR (Status
)) {
1519 // Fire up the events registered with this type of data.
1521 NetMapIterate (&Instance
->DataItem
[DataType
].EventMap
, Ip4Config2SignalEvent
, NULL
);
1522 Ip4Config2WriteConfigData (IpSb
->MacString
, Instance
);
1523 } else if (Status
== EFI_ABORTED
) {
1525 // The SetData is aborted because the data to set is the same with
1526 // the one maintained.
1528 Status
= EFI_SUCCESS
;
1529 NetMapIterate (&Instance
->DataItem
[DataType
].EventMap
, Ip4Config2SignalEvent
, NULL
);
1534 // Another asynchornous process is on the way.
1536 Status
= EFI_ACCESS_DENIED
;
1539 gBS
->RestoreTPL (OldTpl
);
1545 Get the configuration data for the EFI IPv4 network stack running on the communication
1546 device that this EFI_IP4_CONFIG2_PROTOCOL instance manages.
1548 This function returns the configuration data of type DataType for the EFI IPv4 network
1549 stack running on the communication device that this EFI IPv4 Configuration Protocol instance
1552 The caller is responsible for allocating the buffer used to return the specified
1553 configuration data. The required size will be returned to the caller if the size of
1554 the buffer is too small.
1556 EFI_NOT_READY is returned if the specified configuration data is not ready due to an
1557 asynchronous configuration process already in progress. The caller can call RegisterDataNotify()
1558 to register an event on the specified configuration data. Once the asynchronous configuration
1559 process is finished, the event will be signaled, and a subsequent GetData() call will return
1560 the specified configuration data.
1562 @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1563 @param[in] DataType The type of data to get.
1564 @param[in, out] DataSize On input, in bytes, the size of Data. On output, in bytes, the
1565 size of buffer required to store the specified configuration data.
1566 @param[in] Data The data buffer in which the configuration data is returned. The
1567 type of the data buffer is associated with the DataType.
1568 This is an optional parameter that may be NULL.
1570 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
1571 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
1574 - Data is NULL if *DataSize is not zero.
1575 @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data,
1576 and the required size is returned in DataSize.
1577 @retval EFI_NOT_READY The specified configuration data is not ready due to an
1578 asynchronous configuration process already in progress.
1579 @retval EFI_NOT_FOUND The specified configuration data is not found.
1584 EfiIp4Config2GetData (
1585 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1586 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1587 IN OUT UINTN
*DataSize
,
1588 IN VOID
*Data OPTIONAL
1593 IP4_CONFIG2_INSTANCE
*Instance
;
1594 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1596 if ((This
== NULL
) || (DataSize
== NULL
) || ((*DataSize
!= 0) && (Data
== NULL
))) {
1597 return EFI_INVALID_PARAMETER
;
1600 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1601 return EFI_NOT_FOUND
;
1604 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1606 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1607 DataItem
= &Instance
->DataItem
[DataType
];
1609 Status
= Instance
->DataItem
[DataType
].Status
;
1610 if (!EFI_ERROR (Status
)) {
1612 if (DataItem
->GetData
!= NULL
) {
1614 Status
= DataItem
->GetData (Instance
, DataSize
, Data
);
1615 } else if (*DataSize
< Instance
->DataItem
[DataType
].DataSize
) {
1617 // Update the buffer length.
1619 *DataSize
= Instance
->DataItem
[DataType
].DataSize
;
1620 Status
= EFI_BUFFER_TOO_SMALL
;
1623 *DataSize
= Instance
->DataItem
[DataType
].DataSize
;
1624 CopyMem (Data
, Instance
->DataItem
[DataType
].Data
.Ptr
, *DataSize
);
1628 gBS
->RestoreTPL (OldTpl
);
1634 Register an event that is signaled whenever a configuration process on the specified
1635 configuration data is done.
1637 This function registers an event that is to be signaled whenever a configuration
1638 process on the specified configuration data is performed. An event can be registered
1639 for a different DataType simultaneously. The caller is responsible for determining
1640 which type of configuration data causes the signaling of the event in such an event.
1642 @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1643 @param[in] DataType The type of data to unregister the event for.
1644 @param[in] Event The event to register.
1646 @retval EFI_SUCCESS The notification event for the specified configuration data is
1648 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
1649 @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not
1651 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
1652 @retval EFI_ACCESS_DENIED The Event is already registered for the DataType.
1657 EfiIp4Config2RegisterDataNotify (
1658 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1659 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1665 IP4_CONFIG2_INSTANCE
*Instance
;
1669 if ((This
== NULL
) || (Event
== NULL
)) {
1670 return EFI_INVALID_PARAMETER
;
1673 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1674 return EFI_UNSUPPORTED
;
1677 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1679 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1680 EventMap
= &Instance
->DataItem
[DataType
].EventMap
;
1683 // Check whether this event is already registered for this DataType.
1685 Item
= NetMapFindKey (EventMap
, Event
);
1688 Status
= NetMapInsertTail (EventMap
, Event
, NULL
);
1690 if (EFI_ERROR (Status
)) {
1692 Status
= EFI_OUT_OF_RESOURCES
;
1697 Status
= EFI_ACCESS_DENIED
;
1700 gBS
->RestoreTPL (OldTpl
);
1706 Remove a previously registered event for the specified configuration data.
1708 @param This The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
1709 @param DataType The type of data to remove from the previously
1711 @param Event The event to be unregistered.
1713 @retval EFI_SUCCESS The event registered for the specified
1714 configuration data was removed.
1715 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
1716 @retval EFI_NOT_FOUND The Event has not been registered for the
1722 EfiIp4Config2UnregisterDataNotify (
1723 IN EFI_IP4_CONFIG2_PROTOCOL
*This
,
1724 IN EFI_IP4_CONFIG2_DATA_TYPE DataType
,
1730 IP4_CONFIG2_INSTANCE
*Instance
;
1733 if ((This
== NULL
) || (Event
== NULL
)) {
1734 return EFI_INVALID_PARAMETER
;
1737 if (DataType
>= Ip4Config2DataTypeMaximum
) {
1738 return EFI_NOT_FOUND
;
1741 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1743 Instance
= IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This
);
1745 Item
= NetMapFindKey (&Instance
->DataItem
[DataType
].EventMap
, Event
);
1748 NetMapRemoveItem (&Instance
->DataItem
[DataType
].EventMap
, Item
, NULL
);
1749 Status
= EFI_SUCCESS
;
1752 Status
= EFI_NOT_FOUND
;
1755 gBS
->RestoreTPL (OldTpl
);
1761 Initialize an IP4_CONFIG2_INSTANCE.
1763 @param[out] Instance The buffer of IP4_CONFIG2_INSTANCE to be initialized.
1765 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.
1766 @retval EFI_SUCCESS The IP4_CONFIG2_INSTANCE initialized successfully.
1770 Ip4Config2InitInstance (
1771 OUT IP4_CONFIG2_INSTANCE
*Instance
1775 IP4_CONFIG2_INSTANCE
*TmpInstance
;
1780 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1783 IpSb
= IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance
);
1785 Instance
->Signature
= IP4_CONFIG2_INSTANCE_SIGNATURE
;
1789 // Determine the index of this interface.
1792 NET_LIST_FOR_EACH (Entry
, &mIp4Config2InstanceList
) {
1793 TmpInstance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_CONFIG2_INSTANCE
, Link
, IP4_CONFIG2_INSTANCE_SIGNATURE
);
1795 if (TmpInstance
->IfIndex
> IfIndex
) {
1797 // There is a sequence hole because some interface is down.
1805 Instance
->IfIndex
= IfIndex
;
1806 NetListInsertBefore (Entry
, &Instance
->Link
);
1808 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
1810 // Initialize the event map for each data item.
1812 NetMapInit (&Instance
->DataItem
[Index
].EventMap
);
1817 // Initialize each data type: associate storage and set data size for the
1818 // fixed size data types, hook the SetData function, set the data attribute.
1820 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeInterfaceInfo
];
1821 DataItem
->GetData
= Ip4Config2GetIfInfo
;
1822 DataItem
->Data
.Ptr
= &Instance
->InterfaceInfo
;
1823 DataItem
->DataSize
= sizeof (Instance
->InterfaceInfo
);
1824 SET_DATA_ATTRIB (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
| DATA_ATTRIB_VOLATILE
);
1825 Ip4Config2InitIfInfo (IpSb
, &Instance
->InterfaceInfo
);
1827 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypePolicy
];
1828 DataItem
->SetData
= Ip4Config2SetPolicy
;
1829 DataItem
->Data
.Ptr
= &Instance
->Policy
;
1830 DataItem
->DataSize
= sizeof (Instance
->Policy
);
1831 Instance
->Policy
= Ip4Config2PolicyDhcp
;
1832 SET_DATA_ATTRIB (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
);
1834 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeManualAddress
];
1835 DataItem
->SetData
= Ip4Config2SetMaunualAddress
;
1836 DataItem
->Status
= EFI_NOT_FOUND
;
1838 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeGateway
];
1839 DataItem
->SetData
= Ip4Config2SetGateway
;
1840 DataItem
->Status
= EFI_NOT_FOUND
;
1842 DataItem
= &Instance
->DataItem
[Ip4Config2DataTypeDnsServer
];
1843 DataItem
->SetData
= Ip4Config2SetDnsServer
;
1844 DataItem
->Status
= EFI_NOT_FOUND
;
1847 // Create the event used for DHCP.
1849 Status
= gBS
->CreateEvent (
1852 Ip4Config2OnDhcp4Event
,
1854 &Instance
->Dhcp4Event
1856 ASSERT_EFI_ERROR (Status
);
1858 Instance
->Configured
= TRUE
;
1861 // Try to read the config data from NV variable.
1863 Status
= Ip4Config2ReadConfigData (IpSb
->MacString
, Instance
);
1864 if (Status
== EFI_NOT_FOUND
) {
1865 Status
= Ip4Config2WriteConfigData (IpSb
->MacString
, Instance
);
1868 if (EFI_ERROR (Status
)) {
1873 // Try to set the configured parameter.
1875 for (Index
= Ip4Config2DataTypePolicy
; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
1876 DataItem
= &IpSb
->Ip4Config2Instance
.DataItem
[Index
];
1877 if (DataItem
->Data
.Ptr
!= NULL
) {
1879 &IpSb
->Ip4Config2Instance
,
1886 Instance
->Ip4Config2
.SetData
= EfiIp4Config2SetData
;
1887 Instance
->Ip4Config2
.GetData
= EfiIp4Config2GetData
;
1888 Instance
->Ip4Config2
.RegisterDataNotify
= EfiIp4Config2RegisterDataNotify
;
1889 Instance
->Ip4Config2
.UnregisterDataNotify
= EfiIp4Config2UnregisterDataNotify
;
1892 // Publish the IP4 configuration form
1894 return Ip4Config2FormInit (Instance
);
1899 Release an IP4_CONFIG2_INSTANCE.
1901 @param[in, out] Instance The buffer of IP4_CONFIG2_INSTANCE to be freed.
1905 Ip4Config2CleanInstance (
1906 IN OUT IP4_CONFIG2_INSTANCE
*Instance
1910 IP4_CONFIG2_DATA_ITEM
*DataItem
;
1912 if (Instance
->DeclineAddress
!= NULL
) {
1913 FreePool (Instance
->DeclineAddress
);
1916 if (!Instance
->Configured
) {
1920 if (Instance
->Dhcp4Handle
!= NULL
) {
1922 Ip4Config2DestroyDhcp4 (Instance
);
1928 if (Instance
->Dhcp4Event
!= NULL
) {
1929 gBS
->CloseEvent (Instance
->Dhcp4Event
);
1932 for (Index
= 0; Index
< Ip4Config2DataTypeMaximum
; Index
++) {
1934 DataItem
= &Instance
->DataItem
[Index
];
1936 if (!DATA_ATTRIB_SET (DataItem
->Attribute
, DATA_ATTRIB_SIZE_FIXED
)) {
1937 if (DataItem
->Data
.Ptr
!= NULL
) {
1938 FreePool (DataItem
->Data
.Ptr
);
1940 DataItem
->Data
.Ptr
= NULL
;
1941 DataItem
->DataSize
= 0;
1944 NetMapClean (&Instance
->DataItem
[Index
].EventMap
);
1947 Ip4Config2FormUnload (Instance
);
1949 RemoveEntryList (&Instance
->Link
);