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