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