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