]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
code scrub fix
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4Config.c
1 /** @file
2 This code implements the IP4Config and NicIp4Config protocols.
3
4 Copyright (c) 2006 - 2008, 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<BR>
8 http://opensource.org/licenses/bsd-license.php
9
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.
12
13 **/
14
15 #include "Ip4Config.h"
16
17 IP4_CONFIG_INSTANCE *mIp4ConfigNicList[MAX_IP4_CONFIG_IN_VARIABLE];
18
19 /**
20 Return the name and MAC address for the NIC. The Name, if not NULL,
21 has at least IP4_NIC_NAME_LENGTH bytes.
22
23 @param This The NIC IP4 CONFIG protocol
24 @param Name The buffer to return the name
25 @param NicAddr The buffer to return the MAC addr
26
27 @retval EFI_INVALID_PARAMETER This is NULL
28 @retval EFI_SUCCESS The name or address of the NIC are returned.
29
30 **/
31 EFI_STATUS
32 EFIAPI
33 EfiNicIp4ConfigGetName (
34 IN EFI_NIC_IP4_CONFIG_PROTOCOL *This,
35 OUT UINT16 *Name OPTIONAL,
36 OUT NIC_ADDR *NicAddr OPTIONAL
37 )
38 {
39 IP4_CONFIG_INSTANCE *Instance;
40
41 if (This == NULL) {
42 return EFI_INVALID_PARAMETER;
43 }
44
45 Instance = IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG (This);
46
47 if (Name != NULL) {
48 CopyMem (Name, Instance->NicName, IP4_NIC_NAME_LENGTH);
49 }
50
51 if (NicAddr != NULL) {
52 CopyMem (NicAddr, &Instance->NicAddr, sizeof (*NicAddr));
53 }
54
55 return EFI_SUCCESS;
56 }
57
58
59 /**
60 Get the NIC's configure information from the IP4 configure variable.
61 It will remove the invalid variable.
62
63 @param NicAddr The NIC to check
64
65 @return NULL if no configure for the NIC in the variable, or it is invalid.
66 Otherwise the pointer to the NIC's IP configure parameter will be returned.
67
68 **/
69 NIC_IP4_CONFIG_INFO *
70 Ip4ConfigGetNicInfo (
71 IN NIC_ADDR *NicAddr
72 )
73 {
74 IP4_CONFIG_VARIABLE *Variable;
75 IP4_CONFIG_VARIABLE *NewVariable;
76 NIC_IP4_CONFIG_INFO *Config;
77
78 //
79 // Read the configuration parameter for this NicAddr from
80 // the EFI variable
81 //
82 Variable = Ip4ConfigReadVariable ();
83
84 if (Variable == NULL) {
85 return NULL;
86 }
87
88 Config = Ip4ConfigFindNicVariable (Variable, NicAddr);
89
90 if (Config == NULL) {
91 gBS->FreePool (Variable);
92 return NULL;
93 }
94
95 //
96 // Validate the configuration, if the configuration is invalid,
97 // remove it from the variable.
98 //
99 if (!Ip4ConfigIsValid (Config)) {
100 NewVariable = Ip4ConfigModifyVariable (Variable, &Config->NicAddr, NULL);
101 Ip4ConfigWriteVariable (NewVariable);
102
103 if (NewVariable != NULL) {
104 gBS->FreePool (NewVariable);
105 };
106
107 gBS->FreePool (Config);
108 Config = NULL;
109 }
110
111 gBS->FreePool (Variable);
112 return Config;
113 }
114
115
116 /**
117 Get the configure parameter for this NIC.
118
119 @param This The NIC IP4 CONFIG protocol.
120 @param ConfigLen The length of the NicConfig buffer.
121 @param NicConfig The buffer to receive the NIC's configure
122 parameter.
123
124 @retval EFI_SUCCESS The configure parameter for this NIC was
125 obtained successfully .
126 @retval EFI_INVALID_PARAMETER This or ConfigLen is NULL.
127 @retval EFI_NOT_FOUND There is no configure parameter for the NIC in
128 NVRam.
129 @retval EFI_BUFFER_TOO_SMALL The ConfigLen is too small or the NicConfig is
130 NULL.
131
132 **/
133 EFI_STATUS
134 EFIAPI
135 EfiNicIp4ConfigGetInfo (
136 IN EFI_NIC_IP4_CONFIG_PROTOCOL *This,
137 IN OUT UINTN *ConfigLen,
138 OUT NIC_IP4_CONFIG_INFO *NicConfig
139 )
140 {
141 IP4_CONFIG_INSTANCE *Instance;
142 NIC_IP4_CONFIG_INFO *Config;
143 EFI_STATUS Status;
144 UINTN Len;
145
146 if ((This == NULL) || (ConfigLen == NULL)) {
147 return EFI_INVALID_PARAMETER;
148 }
149
150 //
151 // Read the Nic's configuration parameter from variable
152 //
153 Instance = IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG (This);
154 Config = Ip4ConfigGetNicInfo (&Instance->NicAddr);
155
156 if (Config == NULL) {
157 return EFI_NOT_FOUND;
158 }
159
160 //
161 // Copy the data to user's buffer
162 //
163 Len = SIZEOF_NIC_IP4_CONFIG_INFO (Config);
164
165 if ((*ConfigLen < Len) || (NicConfig == NULL)) {
166 Status = EFI_BUFFER_TOO_SMALL;
167 } else {
168 Status = EFI_SUCCESS;
169 CopyMem (NicConfig, Config, Len);
170 Ip4ConfigFixRouteTablePointer (&NicConfig->Ip4Info);
171 }
172
173 *ConfigLen = Len;
174
175 gBS->FreePool (Config);
176 return Status;
177 }
178
179
180 /**
181 Set the IP configure parameters for this NIC.
182
183 If Reconfig is TRUE, the IP driver will be informed to discard current
184 auto configure parameter and restart the auto configuration process.
185 If current there is a pending auto configuration, EFI_ALREADY_STARTED is
186 returned. You can only change the configure setting when either
187 the configure has finished or not started yet. If NicConfig, the
188 NIC's configure parameter is removed from the variable.
189
190 @param This The NIC IP4 CONFIG protocol
191 @param NicConfig The new NIC IP4 configure parameter
192 @param Reconfig Inform the IP4 driver to restart the auto
193 configuration
194
195 @retval EFI_SUCCESS The configure parameter for this NIC was
196 set successfully .
197 @retval EFI_INVALID_PARAMETER This is NULL or the configure parameter is
198 invalid.
199 @retval EFI_ALREADY_STARTED There is a pending auto configuration.
200 @retval EFI_NOT_FOUND No auto configure parameter is found
201
202 **/
203 EFI_STATUS
204 EFIAPI
205 EfiNicIp4ConfigSetInfo (
206 IN EFI_NIC_IP4_CONFIG_PROTOCOL *This,
207 IN NIC_IP4_CONFIG_INFO *NicConfig OPTIONAL,
208 IN BOOLEAN Reconfig
209 )
210 {
211 IP4_CONFIG_INSTANCE *Instance;
212 IP4_CONFIG_VARIABLE *Variable;
213 IP4_CONFIG_VARIABLE *NewVariable;
214 EFI_STATUS Status;
215
216 //
217 // Validate the parameters
218 //
219 if (This == NULL) {
220 return EFI_INVALID_PARAMETER;
221 }
222
223 Instance = IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG (This);
224
225 if ((NicConfig != NULL) && (!Ip4ConfigIsValid (NicConfig) ||
226 !NIC_ADDR_EQUAL (&NicConfig->NicAddr, &Instance->NicAddr))) {
227 return EFI_INVALID_PARAMETER;
228 }
229
230 if (Instance->State == IP4_CONFIG_STATE_STARTED) {
231 return EFI_ALREADY_STARTED;
232 }
233
234 //
235 // Update the parameter in the configure variable
236 //
237 Variable = Ip4ConfigReadVariable ();
238
239 if ((Variable == NULL) && (NicConfig == NULL)) {
240 return EFI_NOT_FOUND;
241 }
242
243 NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NicConfig);
244 Status = Ip4ConfigWriteVariable (NewVariable);
245
246 if (NewVariable != NULL) {
247 gBS->FreePool (NewVariable);
248 }
249
250 //
251 // Variable is NULL when saving the first configure parameter
252 //
253 if (Variable != NULL) {
254 gBS->FreePool (Variable);
255 }
256
257 if (EFI_ERROR (Status)) {
258 return Status;
259 }
260
261 //
262 // Signal the IP4 to run the auto configuration again
263 //
264 if (Reconfig && (Instance->ReconfigEvent != NULL)) {
265 Status = gBS->SignalEvent (Instance->ReconfigEvent);
266 NetLibDispatchDpc ();
267 }
268
269 return Status;
270 }
271
272 /**
273 Callback function when DHCP process finished. It will save the
274 retrieved IP configure parameter from DHCP to the NVRam.
275
276 @param Event The callback event
277 @param Context Opaque context to the callback
278
279 @return None
280
281 **/
282 VOID
283 EFIAPI
284 Ip4ConfigOnDhcp4Complete (
285 IN EFI_EVENT Event,
286 IN VOID *Context
287 )
288 {
289 IP4_CONFIG_INSTANCE *Instance;
290 EFI_DHCP4_MODE_DATA Dhcp4Mode;
291 EFI_IP4_IPCONFIG_DATA *Ip4Config;
292 EFI_STATUS Status;
293 BOOLEAN Perment;
294 IP4_ADDR Subnet;
295 IP4_ADDR Ip1;
296 IP4_ADDR Ip2;
297
298 Instance = (IP4_CONFIG_INSTANCE *) Context;
299 ASSERT (Instance->Dhcp4 != NULL);
300
301 Instance->State = IP4_CONFIG_STATE_CONFIGURED;
302 Instance->Result = EFI_TIMEOUT;
303
304 //
305 // Get the DHCP retrieved parameters
306 //
307 Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);
308
309 if (EFI_ERROR (Status)) {
310 goto ON_EXIT;
311 }
312
313 if (Dhcp4Mode.State == Dhcp4Bound) {
314 //
315 // Save the new configuration retrieved by DHCP both in
316 // the instance and to NVRam. So, both the IP4 driver and
317 // other user can get that address.
318 //
319 Perment = FALSE;
320
321 if (Instance->NicConfig != NULL) {
322 ASSERT (Instance->NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);
323 Perment = Instance->NicConfig->Perment;
324 gBS->FreePool (Instance->NicConfig);
325 }
326
327 Instance->NicConfig = AllocatePool (sizeof (NIC_IP4_CONFIG_INFO) + 2* sizeof (EFI_IP4_ROUTE_TABLE));
328
329 if (Instance->NicConfig == NULL) {
330 Instance->Result = EFI_OUT_OF_RESOURCES;
331 goto ON_EXIT;
332 }
333
334 Instance->NicConfig->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (Instance->NicConfig + 1);
335
336 CopyMem (&Instance->NicConfig->NicAddr, &Instance->NicAddr, sizeof (Instance->NicConfig->NicAddr));
337 Instance->NicConfig->Source = IP4_CONFIG_SOURCE_DHCP;
338 Instance->NicConfig->Perment = Perment;
339
340 Ip4Config = &Instance->NicConfig->Ip4Info;
341 Ip4Config->StationAddress = Dhcp4Mode.ClientAddress;
342 Ip4Config->SubnetMask = Dhcp4Mode.SubnetMask;
343
344 //
345 // Create a route for the connected network
346 //
347 Ip4Config->RouteTableSize = 1;
348
349 CopyMem (&Ip1, &Dhcp4Mode.ClientAddress, sizeof (IP4_ADDR));
350 CopyMem (&Ip2, &Dhcp4Mode.SubnetMask, sizeof (IP4_ADDR));
351
352 Subnet = Ip1 & Ip2;
353
354 CopyMem (&Ip4Config->RouteTable[0].SubnetAddress, &Subnet, sizeof (EFI_IPv4_ADDRESS));
355 CopyMem (&Ip4Config->RouteTable[0].SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
356 ZeroMem (&Ip4Config->RouteTable[0].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
357
358 //
359 // Create a route if there is a default router.
360 //
361 if (!EFI_IP4_EQUAL (&Dhcp4Mode.RouterAddress, &mZeroIp4Addr)) {
362 Ip4Config->RouteTableSize = 2;
363
364 ZeroMem (&Ip4Config->RouteTable[1].SubnetAddress, sizeof (EFI_IPv4_ADDRESS));
365 ZeroMem (&Ip4Config->RouteTable[1].SubnetMask, sizeof (EFI_IPv4_ADDRESS));
366 CopyMem (&Ip4Config->RouteTable[1].GatewayAddress, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));
367 }
368
369 Instance->Result = EFI_SUCCESS;
370
371 //
372 // ignore the return status of EfiNicIp4ConfigSetInfo. Network
373 // stack can operate even that failed.
374 //
375 EfiNicIp4ConfigSetInfo (&Instance->NicIp4Protocol, Instance->NicConfig, FALSE);
376 }
377
378 ON_EXIT:
379 gBS->SignalEvent (Instance->DoneEvent);
380 Ip4ConfigCleanDhcp4 (Instance);
381
382 NetLibDispatchDpc ();
383
384 return ;
385 }
386
387 /**
388 Starts running the configuration policy for the EFI IPv4 Protocol driver.
389
390 The Start() function is called to determine and to begin the platform
391 configuration policy by the EFI IPv4 Protocol driver. This determination may
392 be as simple as returning EFI_UNSUPPORTED if there is no EFI IPv4 Protocol
393 driver configuration policy. It may be as involved as loading some defaults
394 from nonvolatile storage, downloading dynamic data from a DHCP server, and
395 checking permissions with a site policy server.
396 Starting the configuration policy is just the beginning. It may finish almost
397 instantly or it may take several minutes before it fails to retrieve configuration
398 information from one or more servers. Once the policy is started, drivers
399 should use the DoneEvent parameter to determine when the configuration policy
400 has completed. EFI_IP4_CONFIG_PROTOCOL.GetData() must then be called to
401 determine if the configuration succeeded or failed.
402 Until the configuration completes successfully, EFI IPv4 Protocol driver instances
403 that are attempting to use default configurations must return EFI_NO_MAPPING.
404 Once the configuration is complete, the EFI IPv4 Configuration Protocol driver
405 signals DoneEvent. The configuration may need to be updated in the future,
406 however; in this case, the EFI IPv4 Configuration Protocol driver must signal
407 ReconfigEvent, and all EFI IPv4 Protocol driver instances that are using default
408 configurations must return EFI_NO_MAPPING until the configuration policy has
409 been rerun.
410
411 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.
412 @param DoneEvent Event that will be signaled when the EFI IPv4
413 Protocol driver configuration policy completes
414 execution. This event must be of type EVT_NOTIFY_SIGNAL.
415 @param ReconfigEvent Event that will be signaled when the EFI IPv4
416 Protocol driver configuration needs to be updated.
417 This event must be of type EVT_NOTIFY_SIGNAL.
418
419 @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol
420 driver is now running.
421 @retval EFI_INVALID_PARAMETER One or more of the following parameters is NULL:
422 This
423 DoneEvent
424 ReconfigEvent
425 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
426 @retval EFI_ALREADY_STARTED The configuration policy for the EFI IPv4 Protocol
427 driver was already started.
428 @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.
429 @retval EFI_UNSUPPORTED This interface does not support the EFI IPv4 Protocol
430 driver configuration.
431
432 **/
433 EFI_STATUS
434 EFIAPI
435 EfiIp4ConfigStart (
436 IN EFI_IP4_CONFIG_PROTOCOL *This,
437 IN EFI_EVENT DoneEvent,
438 IN EFI_EVENT ReconfigEvent
439 )
440 {
441 IP4_CONFIG_INSTANCE *Instance;
442 EFI_DHCP4_PROTOCOL *Dhcp4;
443 EFI_DHCP4_MODE_DATA Dhcp4Mode;
444 EFI_DHCP4_PACKET_OPTION *OptionList[1];
445 IP4_CONFIG_DHCP4_OPTION ParaList;
446 EFI_STATUS Status;
447 UINT32 Source;
448 EFI_TPL OldTpl;
449
450 if ((This == NULL) || (DoneEvent == NULL) || (ReconfigEvent == NULL)) {
451 return EFI_INVALID_PARAMETER;
452 }
453
454 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);
455
456 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
457
458 if (Instance->State != IP4_CONFIG_STATE_IDLE) {
459 Status = EFI_ALREADY_STARTED;
460
461 goto ON_EXIT;
462 }
463
464 Instance->DoneEvent = DoneEvent;
465 Instance->ReconfigEvent = ReconfigEvent;
466
467 Instance->NicConfig = Ip4ConfigGetNicInfo (&Instance->NicAddr);
468
469 if (Instance->NicConfig == NULL) {
470 Source = IP4_CONFIG_SOURCE_DHCP;
471 } else {
472 Source = Instance->NicConfig->Source;
473 }
474
475 //
476 // If the source is static, the auto configuration is done.
477 // return now.
478 //
479 if (Source == IP4_CONFIG_SOURCE_STATIC) {
480 Instance->State = IP4_CONFIG_STATE_CONFIGURED;
481 Instance->Result = EFI_SUCCESS;
482
483 gBS->SignalEvent (Instance->DoneEvent);
484 Status = EFI_SUCCESS;
485 goto ON_EXIT;
486 }
487
488 //
489 // Start the dhcp process
490 //
491 ASSERT ((Source == IP4_CONFIG_SOURCE_DHCP) && (Instance->Dhcp4 == NULL));
492
493 Status = NetLibCreateServiceChild (
494 Instance->Controller,
495 Instance->Image,
496 &gEfiDhcp4ServiceBindingProtocolGuid,
497 &Instance->Dhcp4Handle
498 );
499
500 if (EFI_ERROR (Status)) {
501 goto ON_ERROR;
502 }
503
504 Status = gBS->OpenProtocol (
505 Instance->Dhcp4Handle,
506 &gEfiDhcp4ProtocolGuid,
507 (VOID **) &Instance->Dhcp4,
508 Instance->Image,
509 Instance->Controller,
510 EFI_OPEN_PROTOCOL_BY_DRIVER
511 );
512
513 if (EFI_ERROR (Status)) {
514 goto ON_ERROR;
515 }
516
517 //
518 // Check the current DHCP status, if the DHCP process has
519 // already finished, return now.
520 //
521 Dhcp4 = Instance->Dhcp4;
522 Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);
523
524 if (EFI_ERROR (Status)) {
525 goto ON_ERROR;
526 }
527
528 if (Dhcp4Mode.State == Dhcp4Bound) {
529 Ip4ConfigOnDhcp4Complete (NULL, Instance);
530
531 goto ON_EXIT;
532 }
533
534 //
535 // Try to start the DHCP process. Use most of the current
536 // DHCP configuration to avoid problems if some DHCP client
537 // yields the control of this DHCP service to us.
538 //
539 ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;
540 ParaList.Head.Length = 2;
541 ParaList.Head.Data[0] = DHCP_TAG_NETMASK;
542 ParaList.Route = DHCP_TAG_ROUTER;
543 OptionList[0] = &ParaList.Head;
544 Dhcp4Mode.ConfigData.OptionCount = 1;
545 Dhcp4Mode.ConfigData.OptionList = OptionList;
546
547 Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);
548
549 if (EFI_ERROR (Status)) {
550 goto ON_ERROR;
551 }
552
553 //
554 // Start the DHCP process
555 //
556 Status = gBS->CreateEvent (
557 EVT_NOTIFY_SIGNAL,
558 TPL_CALLBACK,
559 Ip4ConfigOnDhcp4Complete,
560 Instance,
561 &Instance->Dhcp4Event
562 );
563
564 if (EFI_ERROR (Status)) {
565 goto ON_ERROR;
566 }
567
568 Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);
569
570 if (EFI_ERROR (Status)) {
571 goto ON_ERROR;
572 }
573
574 Instance->State = IP4_CONFIG_STATE_STARTED;
575 Instance->Result = EFI_NOT_READY;
576
577 ON_ERROR:
578 if (EFI_ERROR (Status)) {
579 Ip4ConfigCleanConfig (Instance);
580 }
581
582 ON_EXIT:
583 gBS->RestoreTPL (OldTpl);
584
585 NetLibDispatchDpc ();
586
587 return Status;
588 }
589
590
591 /**
592 Stops running the configuration policy for the EFI IPv4 Protocol driver.
593
594 The Stop() function stops the configuration policy for the EFI IPv4 Protocol driver.
595 All configuration data will be lost after calling Stop().
596
597 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.
598
599 @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol
600 driver has been stopped.
601 @retval EFI_INVALID_PARAMETER This is NULL.
602 @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol
603 driver was not started.
604
605 **/
606 EFI_STATUS
607 EFIAPI
608 EfiIp4ConfigStop (
609 IN EFI_IP4_CONFIG_PROTOCOL *This
610 )
611 {
612 IP4_CONFIG_INSTANCE *Instance;
613 EFI_STATUS Status;
614 EFI_TPL OldTpl;
615
616 if (This == NULL) {
617 return EFI_INVALID_PARAMETER;
618 }
619
620 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);
621
622 Status = EFI_SUCCESS;
623 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
624
625 if (Instance->State == IP4_CONFIG_STATE_IDLE) {
626 Status = EFI_NOT_STARTED;
627 goto ON_EXIT;
628 }
629
630 //
631 // Release all the configure parameters. Don't signal the user
632 // event. The user wants to abort the configuration, this isn't
633 // the configuration done or reconfiguration.
634 //
635 Ip4ConfigCleanConfig (Instance);
636
637 ON_EXIT:
638 gBS->RestoreTPL (OldTpl);
639
640 return Status;
641 }
642
643
644 /**
645 Returns the default configuration data (if any) for the EFI IPv4 Protocol driver.
646
647 The GetData() function returns the current configuration data for the EFI IPv4
648 Protocol driver after the configuration policy has completed.
649
650 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.
651 @param ConfigDataSize On input, the size of the ConfigData buffer.
652 On output, the count of bytes that were written
653 into the ConfigData buffer.
654 @param ConfigData Pointer to the EFI IPv4 Configuration Protocol
655 driver configuration data structure.
656 Type EFI_IP4_IPCONFIG_DATA is defined in
657 "Related Definitions" below.
658
659 @retval EFI_SUCCESS The EFI IPv4 Protocol driver configuration has been returned.
660 @retval EFI_INVALID_PARAMETER This is NULL.
661 @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol
662 driver is not running.
663 @retval EFI_NOT_READY EFI IPv4 Protocol driver configuration is still running.
664 @retval EFI_ABORTED EFI IPv4 Protocol driver configuration could not complete.
665 Currently not implemented.
666 @retval EFI_BUFFER_TOO_SMALL *ConfigDataSize is smaller than the configuration
667 data buffer or ConfigData is NULL.
668
669 **/
670 EFI_STATUS
671 EFIAPI
672 EfiIp4ConfigGetData (
673 IN EFI_IP4_CONFIG_PROTOCOL *This,
674 IN OUT UINTN *ConfigDataSize,
675 OUT EFI_IP4_IPCONFIG_DATA *ConfigData OPTIONAL
676 )
677 {
678 IP4_CONFIG_INSTANCE *Instance;
679 NIC_IP4_CONFIG_INFO *NicConfig;
680 EFI_STATUS Status;
681 EFI_TPL OldTpl;
682 UINTN Len;
683
684 if ((This == NULL) || (ConfigDataSize == NULL)) {
685 return EFI_INVALID_PARAMETER;
686 }
687
688 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);
689
690 Status = EFI_SUCCESS;
691 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
692
693 if (Instance->State == IP4_CONFIG_STATE_IDLE) {
694 Status = EFI_NOT_STARTED;
695 } else if (Instance->State == IP4_CONFIG_STATE_STARTED) {
696 Status = EFI_NOT_READY;
697 }
698
699 if (EFI_ERROR (Status)) {
700 goto ON_EXIT;
701 }
702
703 //
704 // Copy the configure data if auto configuration succeeds.
705 //
706 Status = Instance->Result;
707
708 if (Status == EFI_SUCCESS) {
709 ASSERT (Instance->NicConfig != NULL);
710
711 NicConfig = Instance->NicConfig;
712 Len = SIZEOF_IP4_CONFIG_INFO (&NicConfig->Ip4Info);
713
714 if ((*ConfigDataSize < Len) || (ConfigData == NULL)) {
715 Status = EFI_BUFFER_TOO_SMALL;
716 } else {
717 CopyMem (ConfigData, &NicConfig->Ip4Info, Len);
718 Ip4ConfigFixRouteTablePointer (ConfigData);
719 }
720
721 *ConfigDataSize = Len;
722 }
723
724 ON_EXIT:
725 gBS->RestoreTPL (OldTpl);
726
727 return Status;
728 }
729
730 /**
731 Release all the DHCP related resources.
732
733 @param This The IP4 configure instance
734
735 @return None
736
737 **/
738 VOID
739 Ip4ConfigCleanDhcp4 (
740 IN IP4_CONFIG_INSTANCE *This
741 )
742 {
743 if (This->Dhcp4 != NULL) {
744 This->Dhcp4->Stop (This->Dhcp4);
745
746 gBS->CloseProtocol (
747 This->Dhcp4Handle,
748 &gEfiDhcp4ProtocolGuid,
749 This->Image,
750 This->Controller
751 );
752
753 This->Dhcp4 = NULL;
754 }
755
756 if (This->Dhcp4Handle != NULL) {
757 NetLibDestroyServiceChild (
758 This->Controller,
759 This->Image,
760 &gEfiDhcp4ServiceBindingProtocolGuid,
761 This->Dhcp4Handle
762 );
763
764 This->Dhcp4Handle = NULL;
765 }
766
767 if (This->Dhcp4Event == NULL) {
768 gBS->CloseEvent (This->Dhcp4Event);
769 This->Dhcp4Event = NULL;
770 }
771 }
772
773
774 /**
775 Clean up all the configuration parameters.
776
777 @param Instance The IP4 configure instance
778
779 @return None
780
781 **/
782 VOID
783 Ip4ConfigCleanConfig (
784 IN IP4_CONFIG_INSTANCE *Instance
785 )
786 {
787 if (Instance->NicConfig != NULL) {
788 gBS->FreePool (Instance->NicConfig);
789 Instance->NicConfig = NULL;
790 }
791
792 Instance->State = IP4_CONFIG_STATE_IDLE;
793 Instance->DoneEvent = NULL;
794 Instance->ReconfigEvent = NULL;
795
796 Ip4ConfigCleanDhcp4 (Instance);
797 }
798
799 EFI_IP4_CONFIG_PROTOCOL mIp4ConfigProtocolTemplate = {
800 EfiIp4ConfigStart,
801 EfiIp4ConfigStop,
802 EfiIp4ConfigGetData
803 };
804
805 EFI_NIC_IP4_CONFIG_PROTOCOL mNicIp4ConfigProtocolTemplate = {
806 EfiNicIp4ConfigGetName,
807 EfiNicIp4ConfigGetInfo,
808 EfiNicIp4ConfigSetInfo
809 };