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