]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/DnsDxe/DnsImpl.c
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" with PatchInstructionX86()
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsImpl.c
CommitLineData
99c048ef 1/** @file\r
2DnsDxe support functions implementation.\r
3 \r
eed4585b 4Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
99c048ef 5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
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
13**/\r
14\r
15#include "DnsImpl.h"\r
16\r
17/**\r
18 Remove TokenEntry from TokenMap.\r
19\r
20 @param[in] TokenMap All DNSv4 Token entrys.\r
21 @param[in] TokenEntry TokenEntry need to be removed.\r
22\r
23 @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.\r
24 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.\r
25\r
26**/\r
27EFI_STATUS\r
28Dns4RemoveTokenEntry (\r
29 IN NET_MAP *TokenMap,\r
30 IN DNS4_TOKEN_ENTRY *TokenEntry\r
31 )\r
32{\r
33 NET_MAP_ITEM *Item;\r
34\r
35 //\r
36 // Find the TokenEntry first.\r
37 //\r
38 Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);\r
39\r
40 if (Item != NULL) {\r
41 //\r
42 // Remove the TokenEntry if it's found in the map.\r
43 //\r
44 NetMapRemoveItem (TokenMap, Item, NULL);\r
45\r
46 return EFI_SUCCESS;\r
47 }\r
48 \r
49 return EFI_NOT_FOUND;\r
50}\r
51\r
52/**\r
53 Remove TokenEntry from TokenMap.\r
54\r
55 @param[in] TokenMap All DNSv6 Token entrys.\r
56 @param[in] TokenEntry TokenEntry need to be removed.\r
57\r
58 @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.\r
59 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.\r
60 \r
61**/\r
62EFI_STATUS\r
63Dns6RemoveTokenEntry (\r
64 IN NET_MAP *TokenMap,\r
65 IN DNS6_TOKEN_ENTRY *TokenEntry\r
66 )\r
67{\r
68 NET_MAP_ITEM *Item;\r
69\r
70 //\r
71 // Find the TokenEntry first.\r
72 //\r
73 Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);\r
74\r
75 if (Item != NULL) {\r
76 //\r
77 // Remove the TokenEntry if it's found in the map.\r
78 //\r
79 NetMapRemoveItem (TokenMap, Item, NULL);\r
80\r
81 return EFI_SUCCESS;\r
82 }\r
83 \r
84 return EFI_NOT_FOUND;\r
85}\r
86\r
87/**\r
88 This function cancle the token specified by Arg in the Map.\r
89\r
90 @param[in] Map Pointer to the NET_MAP.\r
91 @param[in] Item Pointer to the NET_MAP_ITEM.\r
92 @param[in] Arg Pointer to the token to be cancelled. If NULL, all\r
93 the tokens in this Map will be cancelled.\r
94 This parameter is optional and may be NULL.\r
95\r
96 @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token\r
97 is not the same as that in the Item, if Arg is not\r
98 NULL.\r
99 @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is\r
100 cancelled.\r
101\r
102**/\r
103EFI_STATUS\r
104EFIAPI\r
105Dns4CancelTokens (\r
106 IN NET_MAP *Map,\r
107 IN NET_MAP_ITEM *Item,\r
108 IN VOID *Arg OPTIONAL\r
109 )\r
110{\r
111 DNS4_TOKEN_ENTRY *TokenEntry;\r
112 NET_BUF *Packet;\r
113 UDP_IO *UdpIo;\r
114\r
115 if ((Arg != NULL) && (Item->Key != Arg)) {\r
116 return EFI_SUCCESS;\r
117 }\r
118\r
119 if (Item->Value != NULL) {\r
120 //\r
121 // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in\r
122 // Item->Value.\r
123 //\r
124 Packet = (NET_BUF *) (Item->Value);\r
125 UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));\r
126\r
127 UdpIoCancelSentDatagram (UdpIo, Packet);\r
128 }\r
129\r
130 //\r
131 // Remove TokenEntry from Dns4TxTokens.\r
132 //\r
133 TokenEntry = (DNS4_TOKEN_ENTRY *) Item->Key;\r
134 if (Dns4RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {\r
135 TokenEntry->Token->Status = EFI_ABORTED;\r
136 gBS->SignalEvent (TokenEntry->Token->Event);\r
137 DispatchDpc ();\r
138 }\r
139\r
140 if (Arg != NULL) {\r
141 return EFI_ABORTED;\r
142 }\r
143\r
144 return EFI_SUCCESS;\r
145}\r
146\r
147/**\r
148 This function cancle the token specified by Arg in the Map.\r
149\r
150 @param[in] Map Pointer to the NET_MAP.\r
151 @param[in] Item Pointer to the NET_MAP_ITEM.\r
152 @param[in] Arg Pointer to the token to be cancelled. If NULL, all\r
153 the tokens in this Map will be cancelled.\r
154 This parameter is optional and may be NULL.\r
155\r
156 @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token\r
157 is not the same as that in the Item, if Arg is not\r
158 NULL.\r
159 @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is\r
160 cancelled.\r
161\r
162**/\r
163EFI_STATUS\r
164EFIAPI\r
165Dns6CancelTokens (\r
166 IN NET_MAP *Map,\r
167 IN NET_MAP_ITEM *Item,\r
168 IN VOID *Arg OPTIONAL\r
169 )\r
170{\r
171 DNS6_TOKEN_ENTRY *TokenEntry;\r
172 NET_BUF *Packet;\r
173 UDP_IO *UdpIo;\r
174\r
175 if ((Arg != NULL) && (Item->Key != Arg)) {\r
176 return EFI_SUCCESS;\r
177 }\r
178\r
179 if (Item->Value != NULL) {\r
180 //\r
181 // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in\r
182 // Item->Value.\r
183 //\r
184 Packet = (NET_BUF *) (Item->Value);\r
185 UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));\r
186\r
187 UdpIoCancelSentDatagram (UdpIo, Packet);\r
188 }\r
189\r
190 //\r
191 // Remove TokenEntry from Dns6TxTokens.\r
192 //\r
193 TokenEntry = (DNS6_TOKEN_ENTRY *) Item->Key;\r
194 if (Dns6RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {\r
195 TokenEntry->Token->Status = EFI_ABORTED;\r
196 gBS->SignalEvent (TokenEntry->Token->Event);\r
197 DispatchDpc ();\r
198 }\r
199\r
200 if (Arg != NULL) {\r
201 return EFI_ABORTED;\r
202 }\r
203\r
204 return EFI_SUCCESS;\r
205}\r
206\r
207/**\r
208 Get the TokenEntry from the TokensMap.\r
209\r
210 @param[in] TokensMap All DNSv4 Token entrys\r
211 @param[in] Token Pointer to the token to be get.\r
212 @param[out] TokenEntry Pointer to TokenEntry corresponding Token.\r
213\r
214 @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.\r
215 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.\r
216\r
217**/\r
218EFI_STATUS\r
219EFIAPI\r
220GetDns4TokenEntry (\r
221 IN NET_MAP *TokensMap,\r
222 IN EFI_DNS4_COMPLETION_TOKEN *Token, \r
223 OUT DNS4_TOKEN_ENTRY **TokenEntry\r
224 )\r
225{\r
226 LIST_ENTRY *Entry;\r
227 \r
228 NET_MAP_ITEM *Item;\r
229 \r
230 NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
231 Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
232 *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key); \r
233 if ((*TokenEntry)->Token == Token) {\r
234 return EFI_SUCCESS;\r
235 }\r
236 }\r
237 \r
238 *TokenEntry = NULL;\r
239 \r
240 return EFI_NOT_FOUND;\r
241}\r
242\r
243/**\r
244 Get the TokenEntry from the TokensMap.\r
245\r
246 @param[in] TokensMap All DNSv6 Token entrys\r
247 @param[in] Token Pointer to the token to be get.\r
248 @param[out] TokenEntry Pointer to TokenEntry corresponding Token.\r
249\r
250 @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.\r
251 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.\r
252\r
253**/\r
254EFI_STATUS\r
255EFIAPI\r
256GetDns6TokenEntry (\r
257 IN NET_MAP *TokensMap,\r
258 IN EFI_DNS6_COMPLETION_TOKEN *Token, \r
259 OUT DNS6_TOKEN_ENTRY **TokenEntry\r
260 )\r
261{\r
262 LIST_ENTRY *Entry;\r
263 \r
264 NET_MAP_ITEM *Item;\r
265 \r
266 NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
267 Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
268 *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key); \r
269 if ((*TokenEntry)->Token == Token) {\r
270 return EFI_SUCCESS;\r
271 }\r
272 }\r
273 \r
274 *TokenEntry =NULL;\r
275 \r
276 return EFI_NOT_FOUND;\r
277}\r
278\r
279/**\r
280 Cancel DNS4 tokens from the DNS4 instance.\r
281\r
282 @param[in] Instance Pointer to the DNS instance context data.\r
283 @param[in] Token Pointer to the token to be canceled. If NULL, all\r
284 tokens in this instance will be cancelled.\r
285 This parameter is optional and may be NULL.\r
286\r
287 @retval EFI_SUCCESS The Token is cancelled.\r
288 @retval EFI_NOT_FOUND The Token is not found.\r
289\r
290**/\r
291EFI_STATUS\r
292Dns4InstanceCancelToken (\r
293 IN DNS_INSTANCE *Instance,\r
294 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
295 )\r
296{\r
297 EFI_STATUS Status;\r
298 DNS4_TOKEN_ENTRY *TokenEntry;\r
299\r
300 TokenEntry = NULL;\r
301\r
302 if(Token != NULL ) {\r
303 Status = GetDns4TokenEntry (&Instance->Dns4TxTokens, Token, &TokenEntry);\r
304 if (EFI_ERROR (Status)) {\r
305 return Status;\r
306 }\r
307 } else {\r
308 TokenEntry = NULL;\r
309 }\r
310\r
311 //\r
312 // Cancel this TokenEntry from the Dns4TxTokens map.\r
313 //\r
314 Status = NetMapIterate (&Instance->Dns4TxTokens, Dns4CancelTokens, TokenEntry);\r
315\r
316 if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {\r
317 //\r
318 // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from\r
319 // the Dns4TxTokens and returns success.\r
320 //\r
321 if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {\r
322 Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);\r
323 }\r
324 return EFI_SUCCESS;\r
325 }\r
326\r
327 ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns4TxTokens)));\r
328 \r
329 if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {\r
330 Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);\r
331 }\r
332\r
333 return EFI_SUCCESS;\r
334}\r
335\r
336/**\r
337 Cancel DNS6 tokens from the DNS6 instance.\r
338\r
339 @param[in] Instance Pointer to the DNS instance context data.\r
340 @param[in] Token Pointer to the token to be canceled. If NULL, all\r
341 tokens in this instance will be cancelled.\r
342 This parameter is optional and may be NULL.\r
343\r
344 @retval EFI_SUCCESS The Token is cancelled.\r
345 @retval EFI_NOT_FOUND The Token is not found.\r
346\r
347**/\r
348EFI_STATUS\r
349Dns6InstanceCancelToken (\r
350 IN DNS_INSTANCE *Instance,\r
351 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
352 )\r
353{\r
354 EFI_STATUS Status;\r
355 DNS6_TOKEN_ENTRY *TokenEntry;\r
356\r
357 TokenEntry = NULL;\r
358\r
359 if(Token != NULL ) {\r
360 Status = GetDns6TokenEntry (&Instance->Dns6TxTokens, Token, &TokenEntry);\r
361 if (EFI_ERROR (Status)) {\r
362 return Status;\r
363 }\r
364 } else {\r
365 TokenEntry = NULL;\r
366 }\r
367\r
368 //\r
369 // Cancel this TokenEntry from the Dns6TxTokens map.\r
370 //\r
371 Status = NetMapIterate (&Instance->Dns6TxTokens, Dns6CancelTokens, TokenEntry);\r
372\r
373 if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {\r
374 //\r
375 // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from\r
376 // the Dns6TxTokens and returns success.\r
377 //\r
378 if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {\r
379 Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);\r
380 }\r
381 return EFI_SUCCESS;\r
382 }\r
383\r
384 ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns6TxTokens)));\r
385 \r
386 if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {\r
387 Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);\r
388 }\r
389\r
390 return EFI_SUCCESS;\r
391}\r
392\r
393/**\r
394 Free the resource related to the configure parameters.\r
395\r
396 @param Config The DNS configure data\r
397\r
398**/\r
399VOID\r
400Dns4CleanConfigure (\r
401 IN OUT EFI_DNS4_CONFIG_DATA *Config\r
402 )\r
403{\r
404 if (Config->DnsServerList != NULL) {\r
405 FreePool (Config->DnsServerList);\r
406 }\r
407\r
408 ZeroMem (Config, sizeof (EFI_DNS4_CONFIG_DATA));\r
409}\r
410\r
411/**\r
412 Free the resource related to the configure parameters.\r
413\r
414 @param Config The DNS configure data\r
415\r
416**/\r
417VOID\r
418Dns6CleanConfigure (\r
419 IN OUT EFI_DNS6_CONFIG_DATA *Config\r
420 )\r
421{\r
422 if (Config->DnsServerList != NULL) {\r
423 FreePool (Config->DnsServerList);\r
424 }\r
425\r
426 ZeroMem (Config, sizeof (EFI_DNS6_CONFIG_DATA));\r
427}\r
428\r
429/**\r
430 Allocate memory for configure parameter such as timeout value for Dst,\r
431 then copy the configure parameter from Src to Dst.\r
432\r
433 @param[out] Dst The destination DHCP configure data.\r
434 @param[in] Src The source DHCP configure data.\r
435\r
436 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
437 @retval EFI_SUCCESS The configure is copied.\r
438\r
439**/\r
440EFI_STATUS\r
441Dns4CopyConfigure (\r
442 OUT EFI_DNS4_CONFIG_DATA *Dst,\r
443 IN EFI_DNS4_CONFIG_DATA *Src\r
444 )\r
445{\r
446 UINTN Len;\r
447 UINT32 Index;\r
448\r
449 CopyMem (Dst, Src, sizeof (*Dst));\r
450 Dst->DnsServerList = NULL;\r
451\r
452 //\r
453 // Allocate a memory then copy DnsServerList to it\r
454 //\r
455 if (Src->DnsServerList != NULL) {\r
456 Len = Src->DnsServerListCount * sizeof (EFI_IPv4_ADDRESS);\r
457 Dst->DnsServerList = AllocatePool (Len);\r
458 if (Dst->DnsServerList == NULL) {\r
459 Dns4CleanConfigure (Dst);\r
460 return EFI_OUT_OF_RESOURCES;\r
461 }\r
462\r
463 for (Index = 0; Index < Src->DnsServerListCount; Index++) {\r
464 CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv4_ADDRESS));\r
465 }\r
466 }\r
467\r
468 return EFI_SUCCESS;\r
469}\r
470\r
471/**\r
472 Allocate memory for configure parameter such as timeout value for Dst,\r
473 then copy the configure parameter from Src to Dst.\r
474\r
475 @param[out] Dst The destination DHCP configure data.\r
476 @param[in] Src The source DHCP configure data.\r
477\r
478 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
479 @retval EFI_SUCCESS The configure is copied.\r
480\r
481**/\r
482EFI_STATUS\r
483Dns6CopyConfigure (\r
484 OUT EFI_DNS6_CONFIG_DATA *Dst,\r
485 IN EFI_DNS6_CONFIG_DATA *Src\r
486 )\r
487{\r
488 UINTN Len;\r
489 UINT32 Index;\r
490\r
491 CopyMem (Dst, Src, sizeof (*Dst));\r
492 Dst->DnsServerList = NULL;\r
493\r
494 //\r
495 // Allocate a memory then copy DnsServerList to it\r
496 //\r
497 if (Src->DnsServerList != NULL) {\r
498 Len = Src->DnsServerCount * sizeof (EFI_IPv6_ADDRESS);\r
499 Dst->DnsServerList = AllocatePool (Len);\r
500 if (Dst->DnsServerList == NULL) {\r
501 Dns6CleanConfigure (Dst);\r
502 return EFI_OUT_OF_RESOURCES;\r
503 }\r
504\r
505 for (Index = 0; Index < Src->DnsServerCount; Index++) {\r
506 CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv6_ADDRESS));\r
507 }\r
508 }\r
509\r
510 return EFI_SUCCESS;\r
511}\r
512\r
513/**\r
514 Callback of Dns packet. Does nothing.\r
515\r
516 @param Arg The context.\r
517\r
518**/\r
519VOID\r
520EFIAPI\r
521DnsDummyExtFree (\r
522 IN VOID *Arg\r
523 )\r
524{\r
525}\r
526\r
527/**\r
528 Poll the UDP to get the IP4 default address, which may be retrieved\r
529 by DHCP. \r
530 \r
531 The default time out value is 5 seconds. If IP has retrieved the default address, \r
532 the UDP is reconfigured.\r
533\r
534 @param Instance The DNS instance\r
535 @param UdpIo The UDP_IO to poll\r
536 @param UdpCfgData The UDP configure data to reconfigure the UDP_IO\r
537\r
538 @retval TRUE The default address is retrieved and UDP is reconfigured.\r
539 @retval FALSE Some error occured.\r
540\r
541**/\r
542BOOLEAN\r
543Dns4GetMapping (\r
544 IN DNS_INSTANCE *Instance,\r
545 IN UDP_IO *UdpIo,\r
546 IN EFI_UDP4_CONFIG_DATA *UdpCfgData\r
547 )\r
548{\r
549 DNS_SERVICE *Service;\r
550 EFI_IP4_MODE_DATA Ip4Mode;\r
551 EFI_UDP4_PROTOCOL *Udp;\r
552 EFI_STATUS Status;\r
553\r
554 ASSERT (Instance->Dns4CfgData.UseDefaultSetting);\r
555\r
556 Service = Instance->Service;\r
557 Udp = UdpIo->Protocol.Udp4;\r
558\r
559 Status = gBS->SetTimer (\r
560 Service->TimerToGetMap,\r
561 TimerRelative,\r
562 DNS_TIME_TO_GETMAP * TICKS_PER_SECOND\r
563 );\r
564 if (EFI_ERROR (Status)) {\r
565 return FALSE;\r
566 }\r
567\r
d115b80b 568 while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
99c048ef 569 Udp->Poll (Udp);\r
570\r
571 if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&\r
572 Ip4Mode.IsConfigured) {\r
573\r
574 Udp->Configure (Udp, NULL);\r
575 return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);\r
576 }\r
577 }\r
578\r
579 return FALSE;\r
580}\r
581\r
582/**\r
583 Configure the opened Udp6 instance until the corresponding Ip6 instance\r
584 has been configured.\r
585\r
586 @param Instance The DNS instance\r
587 @param UdpIo The UDP_IO to poll\r
588 @param UdpCfgData The UDP configure data to reconfigure the UDP_IO\r
589\r
590 @retval TRUE Configure the Udp6 instance successfully.\r
591 @retval FALSE Some error occured.\r
592\r
593**/\r
594BOOLEAN\r
595Dns6GetMapping (\r
596 IN DNS_INSTANCE *Instance,\r
597 IN UDP_IO *UdpIo,\r
598 IN EFI_UDP6_CONFIG_DATA *UdpCfgData\r
599 )\r
600{\r
601 DNS_SERVICE *Service;\r
602 EFI_IP6_MODE_DATA Ip6Mode;\r
603 EFI_UDP6_PROTOCOL *Udp;\r
604 EFI_STATUS Status;\r
605\r
606 Service = Instance->Service;\r
607 Udp = UdpIo->Protocol.Udp6;\r
608\r
609 Status = gBS->SetTimer (\r
610 Service->TimerToGetMap,\r
611 TimerRelative,\r
612 DNS_TIME_TO_GETMAP * TICKS_PER_SECOND\r
613 );\r
614 if (EFI_ERROR (Status)) {\r
615 return FALSE;\r
616 }\r
617\r
d115b80b 618 while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
99c048ef 619 Udp->Poll (Udp);\r
620\r
ce22514e
ZL
621 if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL))) {\r
622 if (Ip6Mode.AddressList != NULL) {\r
623 FreePool (Ip6Mode.AddressList);\r
624 }\r
99c048ef 625\r
ce22514e
ZL
626 if (Ip6Mode.GroupTable != NULL) {\r
627 FreePool (Ip6Mode.GroupTable);\r
628 }\r
629\r
630 if (Ip6Mode.RouteTable != NULL) {\r
631 FreePool (Ip6Mode.RouteTable);\r
632 }\r
633\r
634 if (Ip6Mode.NeighborCache != NULL) {\r
635 FreePool (Ip6Mode.NeighborCache);\r
636 }\r
637\r
638 if (Ip6Mode.PrefixTable != NULL) {\r
639 FreePool (Ip6Mode.PrefixTable);\r
640 }\r
641\r
642 if (Ip6Mode.IcmpTypeList != NULL) {\r
643 FreePool (Ip6Mode.IcmpTypeList);\r
644 }\r
645\r
eed4585b 646 if (!Ip6Mode.IsStarted || Ip6Mode.IsConfigured) {\r
ce22514e 647 Udp->Configure (Udp, NULL);\r
eed4585b
JW
648 if (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS) {\r
649 return TRUE;\r
650 }\r
ce22514e 651 }\r
99c048ef 652 }\r
653 }\r
654\r
655 return FALSE;\r
656}\r
657\r
658/**\r
659 Configure the UDP.\r
660 \r
661 @param Instance The DNS session\r
662 @param UdpIo The UDP_IO instance\r
663 \r
664 @retval EFI_SUCCESS The UDP is successfully configured for the\r
665 session.\r
666\r
667**/\r
668EFI_STATUS\r
669Dns4ConfigUdp (\r
670 IN DNS_INSTANCE *Instance,\r
671 IN UDP_IO *UdpIo\r
672 )\r
673{\r
674 EFI_DNS4_CONFIG_DATA *Config;\r
675 EFI_UDP4_CONFIG_DATA UdpConfig;\r
676 EFI_STATUS Status;\r
677\r
678 Config = &Instance->Dns4CfgData;\r
679\r
680 UdpConfig.AcceptBroadcast = FALSE;\r
681 UdpConfig.AcceptPromiscuous = FALSE;\r
682 UdpConfig.AcceptAnyPort = FALSE;\r
683 UdpConfig.AllowDuplicatePort = FALSE;\r
684 UdpConfig.TypeOfService = 0;\r
685 UdpConfig.TimeToLive = 128;\r
686 UdpConfig.DoNotFragment = FALSE;\r
687 UdpConfig.ReceiveTimeout = 0;\r
688 UdpConfig.TransmitTimeout = 0;\r
689 UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;\r
690 UdpConfig.SubnetMask = Config->SubnetMask;\r
691 UdpConfig.StationPort = Config->LocalPort;\r
692 UdpConfig.RemotePort = DNS_SERVER_PORT;\r
693\r
694 CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
695 CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v4, sizeof (EFI_IPv4_ADDRESS));\r
696\r
697 Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);\r
698\r
699 if ((Status == EFI_NO_MAPPING) && Dns4GetMapping (Instance, UdpIo, &UdpConfig)) {\r
700 return EFI_SUCCESS;\r
701 }\r
702 \r
703 return Status;\r
704}\r
705\r
706/**\r
707 Configure the UDP.\r
708 \r
709 @param Instance The DNS session\r
710 @param UdpIo The UDP_IO instance\r
711\r
712 @retval EFI_SUCCESS The UDP is successfully configured for the\r
713 session.\r
714\r
715**/\r
716EFI_STATUS\r
717Dns6ConfigUdp (\r
718 IN DNS_INSTANCE *Instance,\r
719 IN UDP_IO *UdpIo\r
720 )\r
721{\r
722 EFI_DNS6_CONFIG_DATA *Config;\r
723 EFI_UDP6_CONFIG_DATA UdpConfig;\r
724 EFI_STATUS Status;\r
725\r
726 Config = &Instance->Dns6CfgData;\r
727\r
728 UdpConfig.AcceptPromiscuous = FALSE;\r
729 UdpConfig.AcceptAnyPort = FALSE;\r
730 UdpConfig.AllowDuplicatePort = FALSE;\r
731 UdpConfig.TrafficClass = 0;\r
732 UdpConfig.HopLimit = 128;\r
733 UdpConfig.ReceiveTimeout = 0;\r
734 UdpConfig.TransmitTimeout = 0;\r
735 UdpConfig.StationPort = Config->LocalPort;\r
736 UdpConfig.RemotePort = DNS_SERVER_PORT;\r
737 CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv6_ADDRESS));\r
738 CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v6, sizeof (EFI_IPv6_ADDRESS));\r
739\r
740 Status = UdpIo->Protocol.Udp6->Configure (UdpIo->Protocol.Udp6, &UdpConfig);\r
741\r
742 if ((Status == EFI_NO_MAPPING) && Dns6GetMapping (Instance, UdpIo, &UdpConfig)) {\r
743 return EFI_SUCCESS;\r
744 }\r
745 \r
746 return Status;\r
747}\r
748\r
749/**\r
750 Update Dns4 cache to shared list of caches of all DNSv4 instances.\r
751 \r
752 @param Dns4CacheList All Dns4 cache list.\r
753 @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache. \r
754 If TRUE, this function will delete matching DNS Cache entry. \r
755 @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
756 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
757 @param DnsCacheEntry Entry Pointer to DNS Cache entry.\r
758\r
759 @retval EFI_SUCCESS Update Dns4 cache successfully.\r
760 @retval Others Failed to update Dns4 cache. \r
761 \r
762**/ \r
763EFI_STATUS\r
764EFIAPI\r
765UpdateDns4Cache (\r
766 IN LIST_ENTRY *Dns4CacheList,\r
767 IN BOOLEAN DeleteFlag,\r
768 IN BOOLEAN Override,\r
769 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry\r
770 )\r
771{\r
772 DNS4_CACHE *NewDnsCache; \r
773 DNS4_CACHE *Item;\r
774 LIST_ENTRY *Entry;\r
775 LIST_ENTRY *Next;\r
776\r
777 NewDnsCache = NULL;\r
778 Item = NULL;\r
779 \r
780 //\r
781 // Search the database for the matching EFI_DNS_CACHE_ENTRY\r
782 //\r
783 NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4CacheList) {\r
784 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
785 if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \\r
786 CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS)) == 0) {\r
787 //\r
788 // This is the Dns cache entry\r
789 //\r
790 if (DeleteFlag) {\r
791 //\r
792 // Delete matching DNS Cache entry\r
793 //\r
794 RemoveEntryList (&Item->AllCacheLink);\r
43d7e607
JW
795\r
796 FreePool (Item->DnsCache.HostName);\r
797 FreePool (Item->DnsCache.IpAddress);\r
798 FreePool (Item);\r
99c048ef 799 \r
800 return EFI_SUCCESS;\r
801 } else if (Override) {\r
802 //\r
803 // Update this one\r
804 //\r
805 Item->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
806 \r
807 return EFI_SUCCESS;\r
808 }else {\r
809 return EFI_ACCESS_DENIED;\r
810 }\r
811 }\r
812 }\r
813\r
814 //\r
815 // Add new one\r
816 //\r
817 NewDnsCache = AllocatePool (sizeof (DNS4_CACHE));\r
818 if (NewDnsCache == NULL) { \r
819 return EFI_OUT_OF_RESOURCES;\r
820 }\r
821 \r
822 InitializeListHead (&NewDnsCache->AllCacheLink);\r
823 \r
824 NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
825 if (NewDnsCache->DnsCache.HostName == NULL) { \r
43d7e607 826 FreePool (NewDnsCache);\r
99c048ef 827 return EFI_OUT_OF_RESOURCES;\r
828 }\r
829 \r
830 CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));\r
831\r
832 NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv4_ADDRESS));\r
43d7e607
JW
833 if (NewDnsCache->DnsCache.IpAddress == NULL) {\r
834 FreePool (NewDnsCache->DnsCache.HostName);\r
835 FreePool (NewDnsCache);\r
99c048ef 836 return EFI_OUT_OF_RESOURCES;\r
837 }\r
838\r
839 CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv4_ADDRESS));\r
840\r
841 NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
842 \r
843 InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);\r
844 \r
845 return EFI_SUCCESS;\r
846}\r
847\r
848/**\r
849 Update Dns6 cache to shared list of caches of all DNSv6 instances. \r
850\r
851 @param Dns6CacheList All Dns6 cache list.\r
852 @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache. \r
853 If TRUE, this function will delete matching DNS Cache entry. \r
854 @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
855 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
856 @param DnsCacheEntry Entry Pointer to DNS Cache entry.\r
857 \r
858 @retval EFI_SUCCESS Update Dns6 cache successfully.\r
859 @retval Others Failed to update Dns6 cache.\r
860**/ \r
861EFI_STATUS\r
862EFIAPI\r
863UpdateDns6Cache (\r
864 IN LIST_ENTRY *Dns6CacheList,\r
865 IN BOOLEAN DeleteFlag,\r
866 IN BOOLEAN Override,\r
867 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry\r
868 )\r
869{\r
870 DNS6_CACHE *NewDnsCache; \r
871 DNS6_CACHE *Item;\r
872 LIST_ENTRY *Entry;\r
873 LIST_ENTRY *Next;\r
874\r
875 NewDnsCache = NULL;\r
876 Item = NULL;\r
877 \r
878 //\r
879 // Search the database for the matching EFI_DNS_CACHE_ENTRY\r
880 //\r
881 NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6CacheList) {\r
882 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
883 if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \\r
884 CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS)) == 0) {\r
885 //\r
886 // This is the Dns cache entry\r
887 //\r
888 if (DeleteFlag) {\r
889 //\r
890 // Delete matching DNS Cache entry\r
891 //\r
892 RemoveEntryList (&Item->AllCacheLink);\r
893 \r
43d7e607
JW
894 FreePool (Item->DnsCache.HostName);\r
895 FreePool (Item->DnsCache.IpAddress);\r
896 FreePool (Item);\r
897 \r
99c048ef 898 return EFI_SUCCESS;\r
899 } else if (Override) {\r
900 //\r
901 // Update this one\r
902 //\r
903 Item->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
904 \r
905 return EFI_SUCCESS;\r
906 }else {\r
907 return EFI_ACCESS_DENIED;\r
908 }\r
909 }\r
910 }\r
911\r
912 //\r
913 // Add new one\r
914 //\r
915 NewDnsCache = AllocatePool (sizeof (DNS6_CACHE));\r
916 if (NewDnsCache == NULL) { \r
917 return EFI_OUT_OF_RESOURCES;\r
918 }\r
919 \r
920 InitializeListHead (&NewDnsCache->AllCacheLink);\r
921 \r
922 NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
923 if (NewDnsCache->DnsCache.HostName == NULL) { \r
43d7e607 924 FreePool (NewDnsCache);\r
99c048ef 925 return EFI_OUT_OF_RESOURCES;\r
926 }\r
927 \r
928 CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));\r
929\r
930 NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv6_ADDRESS));\r
43d7e607
JW
931 if (NewDnsCache->DnsCache.IpAddress == NULL) {\r
932 FreePool (NewDnsCache->DnsCache.HostName);\r
933 FreePool (NewDnsCache);\r
99c048ef 934 return EFI_OUT_OF_RESOURCES;\r
935 }\r
936 \r
937 CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
938\r
939 NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
940 \r
941 InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);\r
942 \r
943 return EFI_SUCCESS;\r
944}\r
945\r
946/**\r
947 Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server. \r
948\r
949 @param Dns4ServerList Common list of addresses of all configured DNSv4 server. \r
950 @param ServerIp DNS server Ip. \r
951\r
952 @retval EFI_SUCCESS Add Dns4 ServerIp to common list successfully.\r
953 @retval Others Failed to add Dns4 ServerIp to common list.\r
954 \r
955**/ \r
956EFI_STATUS\r
957EFIAPI\r
958AddDns4ServerIp (\r
959 IN LIST_ENTRY *Dns4ServerList,\r
960 IN EFI_IPv4_ADDRESS ServerIp\r
961 )\r
962{\r
963 DNS4_SERVER_IP *NewServerIp; \r
964 DNS4_SERVER_IP *Item;\r
965 LIST_ENTRY *Entry;\r
966 LIST_ENTRY *Next;\r
967\r
968 NewServerIp = NULL;\r
969 Item = NULL;\r
970 \r
971 //\r
972 // Search the database for the matching ServerIp\r
973 //\r
974 NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4ServerList) {\r
975 Item = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);\r
976 if (CompareMem (&Item->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS)) == 0) {\r
977 //\r
978 // Already done.\r
979 // \r
980 return EFI_SUCCESS;\r
981 }\r
982 }\r
983\r
984 //\r
985 // Add new one\r
986 //\r
987 NewServerIp = AllocatePool (sizeof (DNS4_SERVER_IP));\r
988 if (NewServerIp == NULL) { \r
989 return EFI_OUT_OF_RESOURCES;\r
990 }\r
991 \r
992 InitializeListHead (&NewServerIp->AllServerLink);\r
993 \r
994 CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
995 \r
996 InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);\r
997 \r
998 return EFI_SUCCESS;\r
999}\r
1000\r
1001/**\r
1002 Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server. \r
1003\r
1004 @param Dns6ServerList Common list of addresses of all configured DNSv6 server. \r
1005 @param ServerIp DNS server Ip. \r
1006\r
1007 @retval EFI_SUCCESS Add Dns6 ServerIp to common list successfully.\r
1008 @retval Others Failed to add Dns6 ServerIp to common list.\r
1009 \r
1010**/ \r
1011EFI_STATUS\r
1012EFIAPI\r
1013AddDns6ServerIp (\r
1014 IN LIST_ENTRY *Dns6ServerList,\r
1015 IN EFI_IPv6_ADDRESS ServerIp\r
1016 )\r
1017{\r
1018 DNS6_SERVER_IP *NewServerIp; \r
1019 DNS6_SERVER_IP *Item;\r
1020 LIST_ENTRY *Entry;\r
1021 LIST_ENTRY *Next;\r
1022\r
1023 NewServerIp = NULL;\r
1024 Item = NULL;\r
1025 \r
1026 //\r
1027 // Search the database for the matching ServerIp\r
1028 //\r
1029 NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6ServerList) {\r
1030 Item = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);\r
1031 if (CompareMem (&Item->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS)) == 0) {\r
1032 //\r
1033 // Already done.\r
1034 // \r
1035 return EFI_SUCCESS;\r
1036 }\r
1037 }\r
1038\r
1039 //\r
1040 // Add new one\r
1041 //\r
1042 NewServerIp = AllocatePool (sizeof (DNS6_SERVER_IP));\r
1043 if (NewServerIp == NULL) { \r
1044 return EFI_OUT_OF_RESOURCES;\r
1045 }\r
1046 \r
1047 InitializeListHead (&NewServerIp->AllServerLink);\r
1048 \r
1049 CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
1050 \r
1051 InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);\r
1052 \r
1053 return EFI_SUCCESS;\r
1054}\r
1055\r
1056/**\r
1057 Find out whether the response is valid or invalid.\r
1058\r
1059 @param TokensMap All DNS transmittal Tokens entry. \r
1060 @param Identification Identification for queried packet. \r
1061 @param Type Type for queried packet.\r
3900a743 1062 @param Class Class for queried packet.\r
99c048ef 1063 @param Item Return corresponding Token entry.\r
1064\r
1065 @retval TRUE The response is valid.\r
1066 @retval FALSE The response is invalid.\r
1067 \r
1068**/ \r
1069BOOLEAN\r
1070IsValidDnsResponse (\r
1071 IN NET_MAP *TokensMap,\r
1072 IN UINT16 Identification,\r
1073 IN UINT16 Type,\r
3900a743 1074 IN UINT16 Class,\r
99c048ef 1075 OUT NET_MAP_ITEM **Item\r
1076 )\r
1077{\r
1078 LIST_ENTRY *Entry;\r
1079\r
1080 NET_BUF *Packet;\r
1081 UINT8 *TxString;\r
1082 DNS_HEADER *DnsHeader;\r
1083 CHAR8 *QueryName;\r
1084 DNS_QUERY_SECTION *QuerySection;\r
1085\r
1086 NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
1087 *Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
1088 Packet = (NET_BUF *) ((*Item)->Value);\r
1089 if (Packet == NULL){\r
1090 \r
1091 continue;\r
1092 } else {\r
1093 TxString = NetbufGetByte (Packet, 0, NULL);\r
3fd7bd08 1094 ASSERT (TxString != NULL);\r
99c048ef 1095 DnsHeader = (DNS_HEADER *) TxString;\r
1096 QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));\r
1097 QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
99c048ef 1098 \r
3900a743
JW
1099 if (NTOHS (DnsHeader->Identification) == Identification &&\r
1100 NTOHS (QuerySection->Type) == Type && \r
1101 NTOHS (QuerySection->Class) == Class) {\r
99c048ef 1102 return TRUE;\r
1103 }\r
1104 } \r
1105 }\r
1106 \r
3900a743 1107 *Item = NULL;\r
99c048ef 1108 \r
1109 return FALSE;\r
1110}\r
1111\r
1112/**\r
1113 Parse Dns Response.\r
1114\r
1115 @param Instance The DNS instance\r
1116 @param RxString Received buffer.\r
1117 @param Completed Flag to indicate that Dns response is valid. \r
1118 \r
1119 @retval EFI_SUCCESS Parse Dns Response successfully.\r
1120 @retval Others Failed to parse Dns Response.\r
1121 \r
1122**/ \r
1123EFI_STATUS\r
1124ParseDnsResponse (\r
1125 IN OUT DNS_INSTANCE *Instance,\r
1126 IN UINT8 *RxString,\r
1127 OUT BOOLEAN *Completed\r
1128 )\r
1129{\r
1130 DNS_HEADER *DnsHeader;\r
1131 \r
1132 CHAR8 *QueryName;\r
1133 DNS_QUERY_SECTION *QuerySection;\r
1134 \r
1135 CHAR8 *AnswerName;\r
1136 DNS_ANSWER_SECTION *AnswerSection;\r
1137 UINT8 *AnswerData;\r
1138\r
1139 NET_MAP_ITEM *Item;\r
1140 DNS4_TOKEN_ENTRY *Dns4TokenEntry;\r
1141 DNS6_TOKEN_ENTRY *Dns6TokenEntry;\r
1142 \r
1143 UINT32 IpCount;\r
fcae1a99 1144 UINT32 RRCount;\r
99c048ef 1145 UINT32 AnswerSectionNum;\r
3093f45c 1146 UINT32 CNameTtl;\r
99c048ef 1147 \r
1148 EFI_IPv4_ADDRESS *HostAddr4;\r
1149 EFI_IPv6_ADDRESS *HostAddr6;\r
1150\r
1151 EFI_DNS4_CACHE_ENTRY *Dns4CacheEntry;\r
1152 EFI_DNS6_CACHE_ENTRY *Dns6CacheEntry;\r
1153\r
fcae1a99
JW
1154 DNS_RESOURCE_RECORD *Dns4RR;\r
1155 DNS6_RESOURCE_RECORD *Dns6RR;\r
1156\r
99c048ef 1157 EFI_STATUS Status;\r
1158\r
1159 EFI_TPL OldTpl;\r
1160 \r
1161 Item = NULL;\r
1162 Dns4TokenEntry = NULL;\r
1163 Dns6TokenEntry = NULL;\r
1164 \r
1165 IpCount = 0;\r
fcae1a99 1166 RRCount = 0;\r
99c048ef 1167 AnswerSectionNum = 0;\r
3093f45c 1168 CNameTtl = 0;\r
99c048ef 1169 \r
1170 HostAddr4 = NULL;\r
1171 HostAddr6 = NULL;\r
1172 \r
1173 Dns4CacheEntry = NULL;\r
1174 Dns6CacheEntry = NULL;\r
fcae1a99
JW
1175 \r
1176 Dns4RR = NULL;\r
1177 Dns6RR = NULL;\r
99c048ef 1178\r
1179 *Completed = TRUE;\r
1180 Status = EFI_SUCCESS;\r
1181 \r
1182 //\r
1183 // Get header\r
1184 //\r
1185 DnsHeader = (DNS_HEADER *) RxString;\r
1186 \r
1187 DnsHeader->Identification = NTOHS (DnsHeader->Identification);\r
1188 DnsHeader->Flags.Uint16 = NTOHS (DnsHeader->Flags.Uint16);\r
1189 DnsHeader->QuestionsNum = NTOHS (DnsHeader->QuestionsNum);\r
1190 DnsHeader->AnswersNum = NTOHS (DnsHeader->AnswersNum);\r
1191 DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum);\r
1192 DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum);\r
1193\r
1194 //\r
1195 // Get Query name\r
1196 //\r
1197 QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));\r
1198\r
1199 //\r
1200 // Get query section\r
1201 //\r
1202 QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
1203 QuerySection->Type = NTOHS (QuerySection->Type);\r
1204 QuerySection->Class = NTOHS (QuerySection->Class);\r
1205\r
1206 //\r
1207 // Get Answer name\r
1208 //\r
1209 AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);\r
1210\r
1211 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1212\r
1213 //\r
1214 // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.\r
1215 //\r
1216 if (Instance->Service->IpVersion == IP_VERSION_4) {\r
3900a743
JW
1217 if (!IsValidDnsResponse (\r
1218 &Instance->Dns4TxTokens, \r
1219 DnsHeader->Identification, \r
1220 QuerySection->Type,\r
1221 QuerySection->Class,\r
1222 &Item\r
1223 )) {\r
99c048ef 1224 *Completed = FALSE;\r
1225 Status = EFI_ABORTED;\r
1226 goto ON_EXIT;\r
1227 }\r
1228 ASSERT (Item != NULL);\r
1229 Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
1230 } else {\r
3900a743
JW
1231 if (!IsValidDnsResponse (\r
1232 &Instance->Dns6TxTokens, \r
1233 DnsHeader->Identification, \r
1234 QuerySection->Type,\r
1235 QuerySection->Class,\r
1236 &Item\r
1237 )) {\r
99c048ef 1238 *Completed = FALSE;\r
1239 Status = EFI_ABORTED;\r
1240 goto ON_EXIT;\r
1241 }\r
1242 ASSERT (Item != NULL);\r
1243 Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);\r
1244 }\r
1245 \r
1246 //\r
1247 // Continue Check Some Errors.\r
1248 //\r
1249 if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \\r
3900a743 1250 DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {\r
0a92ac88
JW
1251 //\r
1252 // The domain name referenced in the query does not exist.\r
1253 //\r
1254 if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {\r
1255 Status = EFI_NOT_FOUND; \r
1256 } else {\r
1257 Status = EFI_DEVICE_ERROR;\r
1258 }\r
1259 \r
1260 goto ON_COMPLETE;\r
99c048ef 1261 }\r
99c048ef 1262 \r
1263 //\r
fcae1a99 1264 // Do some buffer allocations.\r
99c048ef 1265 //\r
00c0c3f2
JW
1266 if (Instance->Service->IpVersion == IP_VERSION_4) {\r
1267 ASSERT (Dns4TokenEntry != NULL);\r
fcae1a99
JW
1268\r
1269 if (Dns4TokenEntry->GeneralLookUp) {\r
1270 //\r
1271 // It's the GeneralLookUp querying.\r
1272 //\r
43d7e607 1273 Dns4TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));\r
fcae1a99
JW
1274 if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {\r
1275 Status = EFI_OUT_OF_RESOURCES;\r
1276 goto ON_EXIT;\r
1277 }\r
43d7e607 1278 Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
fcae1a99
JW
1279 if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
1280 Status = EFI_OUT_OF_RESOURCES;\r
1281 goto ON_EXIT;\r
1282 }\r
00c0c3f2 1283 } else {\r
fcae1a99
JW
1284 //\r
1285 // It's not the GeneralLookUp querying. Check the Query type.\r
1286 //\r
1287 if (QuerySection->Type == DNS_TYPE_A) {\r
43d7e607 1288 Dns4TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
fcae1a99
JW
1289 if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {\r
1290 Status = EFI_OUT_OF_RESOURCES;\r
1291 goto ON_EXIT;\r
1292 }\r
43d7e607 1293 Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
fcae1a99
JW
1294 if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
1295 Status = EFI_OUT_OF_RESOURCES;\r
1296 goto ON_EXIT;\r
1297 }\r
1298 } else {\r
1299 Status = EFI_UNSUPPORTED;\r
1300 goto ON_EXIT;\r
1301 }\r
00c0c3f2 1302 }\r
99c048ef 1303 } else {\r
00c0c3f2 1304 ASSERT (Dns6TokenEntry != NULL);\r
fcae1a99
JW
1305\r
1306 if (Dns6TokenEntry->GeneralLookUp) {\r
1307 //\r
1308 // It's the GeneralLookUp querying.\r
1309 //\r
43d7e607 1310 Dns6TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));\r
fcae1a99 1311 if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {\r
3093f45c 1312 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1313 goto ON_EXIT;\r
1314 }\r
43d7e607 1315 Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
fcae1a99 1316 if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
3093f45c 1317 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1318 goto ON_EXIT;\r
1319 }\r
00c0c3f2 1320 } else {\r
fcae1a99
JW
1321 //\r
1322 // It's not the GeneralLookUp querying. Check the Query type.\r
1323 //\r
1324 if (QuerySection->Type == DNS_TYPE_AAAA) {\r
43d7e607 1325 Dns6TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
fcae1a99 1326 if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {\r
3093f45c 1327 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1328 goto ON_EXIT;\r
1329 }\r
43d7e607 1330 Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
fcae1a99 1331 if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
3093f45c 1332 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1333 goto ON_EXIT;\r
1334 }\r
1335 } else {\r
1336 Status = EFI_UNSUPPORTED;\r
1337 goto ON_EXIT;\r
1338 }\r
00c0c3f2 1339 }\r
99c048ef 1340 }\r
1341\r
3093f45c
JW
1342 Status = EFI_NOT_FOUND;\r
1343\r
99c048ef 1344 //\r
1345 // Processing AnswerSection.\r
1346 //\r
1347 while (AnswerSectionNum < DnsHeader->AnswersNum) {\r
1348 //\r
0e5e7996 1349 // Answer name should be PTR, else EFI_UNSUPPORTED returned.\r
99c048ef 1350 //\r
0e5e7996
JW
1351 if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {\r
1352 Status = EFI_UNSUPPORTED;\r
1353 goto ON_EXIT;\r
1354 }\r
99c048ef 1355 \r
1356 //\r
1357 // Get Answer section.\r
1358 //\r
1359 AnswerSection = (DNS_ANSWER_SECTION *) (AnswerName + sizeof (UINT16));\r
1360 AnswerSection->Type = NTOHS (AnswerSection->Type);\r
1361 AnswerSection->Class = NTOHS (AnswerSection->Class);\r
1362 AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);\r
1363 AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);\r
1364\r
fcae1a99
JW
1365 //\r
1366 // Check whether it's the GeneralLookUp querying.\r
1367 //\r
1368 if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {\r
fcae1a99
JW
1369 Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;\r
1370 AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
1371\r
1372 //\r
1373 // Fill the ResourceRecord.\r
1374 //\r
1375 Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
1376 if (Dns4RR[RRCount].QName == NULL) {\r
3093f45c 1377 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1378 goto ON_EXIT;\r
1379 }\r
1380 CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
1381 Dns4RR[RRCount].QType = AnswerSection->Type;\r
1382 Dns4RR[RRCount].QClass = AnswerSection->Class;\r
1383 Dns4RR[RRCount].TTL = AnswerSection->Ttl;\r
1384 Dns4RR[RRCount].DataLength = AnswerSection->DataLength;\r
1385 Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);\r
1386 if (Dns4RR[RRCount].RData == NULL) {\r
3093f45c 1387 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1388 goto ON_EXIT;\r
1389 }\r
1390 CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);\r
1391 \r
1392 RRCount ++;\r
3093f45c 1393 Status = EFI_SUCCESS;\r
fcae1a99 1394 } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {\r
fcae1a99
JW
1395 Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;\r
1396 AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
99c048ef 1397\r
fcae1a99
JW
1398 //\r
1399 // Fill the ResourceRecord.\r
1400 //\r
1401 Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
1402 if (Dns6RR[RRCount].QName == NULL) {\r
3093f45c 1403 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1404 goto ON_EXIT;\r
1405 }\r
1406 CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
1407 Dns6RR[RRCount].QType = AnswerSection->Type;\r
1408 Dns6RR[RRCount].QClass = AnswerSection->Class;\r
1409 Dns6RR[RRCount].TTL = AnswerSection->Ttl;\r
1410 Dns6RR[RRCount].DataLength = AnswerSection->DataLength;\r
1411 Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);\r
1412 if (Dns6RR[RRCount].RData == NULL) {\r
3093f45c 1413 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1414 goto ON_EXIT;\r
1415 }\r
1416 CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);\r
1417 \r
1418 RRCount ++;\r
3093f45c 1419 Status = EFI_SUCCESS;\r
fcae1a99
JW
1420 } else {\r
1421 //\r
1422 // It's not the GeneralLookUp querying. \r
1423 // Check the Query type, parse the response packet.\r
1424 //\r
99c048ef 1425 switch (AnswerSection->Type) {\r
1426 case DNS_TYPE_A:\r
1427 //\r
1428 // This is address entry, get Data.\r
1429 //\r
0e5e7996
JW
1430 ASSERT (Dns4TokenEntry != NULL);\r
1431\r
1432 if (AnswerSection->DataLength != 4) {\r
1433 Status = EFI_ABORTED;\r
1434 goto ON_EXIT;\r
1435 }\r
99c048ef 1436 \r
1437 HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;\r
1438 AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
1439 CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
1440\r
99c048ef 1441 // \r
0a92ac88 1442 // Allocate new CacheEntry pool to update DNS cache dynamically.\r
99c048ef 1443 //\r
1444 Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));\r
fcae1a99 1445 if (Dns4CacheEntry == NULL) {\r
3093f45c 1446 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1447 goto ON_EXIT;\r
1448 }\r
99c048ef 1449 Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
fcae1a99 1450 if (Dns4CacheEntry->HostName == NULL) {\r
3093f45c 1451 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1452 goto ON_EXIT;\r
1453 }\r
99c048ef 1454 CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
1455 Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));\r
fcae1a99 1456 if (Dns4CacheEntry->IpAddress == NULL) {\r
3093f45c 1457 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1458 goto ON_EXIT;\r
1459 }\r
99c048ef 1460 CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
3093f45c
JW
1461\r
1462 if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
1463 Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
1464 } else {\r
1465 Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
1466 }\r
99c048ef 1467 \r
0a92ac88
JW
1468 UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);\r
1469\r
1470 // \r
1471 // Free allocated CacheEntry pool.\r
1472 //\r
1473 FreePool (Dns4CacheEntry->HostName);\r
1474 Dns4CacheEntry->HostName = NULL;\r
1475 \r
1476 FreePool (Dns4CacheEntry->IpAddress);\r
1477 Dns4CacheEntry->IpAddress = NULL;\r
1478\r
1479 FreePool (Dns4CacheEntry);\r
1480 Dns4CacheEntry = NULL;\r
99c048ef 1481\r
3093f45c
JW
1482 IpCount ++;\r
1483 Status = EFI_SUCCESS;\r
99c048ef 1484 break;\r
1485 case DNS_TYPE_AAAA:\r
1486 //\r
1487 // This is address entry, get Data.\r
1488 //\r
0e5e7996
JW
1489 ASSERT (Dns6TokenEntry != NULL);\r
1490\r
1491 if (AnswerSection->DataLength != 16) {\r
1492 Status = EFI_ABORTED;\r
1493 goto ON_EXIT;\r
1494 }\r
99c048ef 1495 \r
1496 HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;\r
1497 AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
1498 CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
1499\r
99c048ef 1500 // \r
0a92ac88 1501 // Allocate new CacheEntry pool to update DNS cache dynamically.\r
99c048ef 1502 //\r
1503 Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));\r
fcae1a99 1504 if (Dns6CacheEntry == NULL) {\r
3093f45c 1505 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1506 goto ON_EXIT;\r
1507 }\r
99c048ef 1508 Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
fcae1a99 1509 if (Dns6CacheEntry->HostName == NULL) {\r
3093f45c 1510 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1511 goto ON_EXIT;\r
1512 }\r
99c048ef 1513 CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
1514 Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));\r
fcae1a99 1515 if (Dns6CacheEntry->IpAddress == NULL) {\r
3093f45c 1516 Status = EFI_OUT_OF_RESOURCES;\r
fcae1a99
JW
1517 goto ON_EXIT;\r
1518 }\r
99c048ef 1519 CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
3093f45c
JW
1520\r
1521 if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
1522 Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
1523 } else {\r
1524 Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
1525 }\r
99c048ef 1526 \r
0a92ac88
JW
1527 UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);\r
1528\r
1529 // \r
1530 // Free allocated CacheEntry pool.\r
1531 //\r
1532 FreePool (Dns6CacheEntry->HostName);\r
1533 Dns6CacheEntry->HostName = NULL;\r
1534 \r
1535 FreePool (Dns6CacheEntry->IpAddress);\r
1536 Dns6CacheEntry->IpAddress = NULL;\r
1537\r
1538 FreePool (Dns6CacheEntry);\r
1539 Dns6CacheEntry = NULL;\r
99c048ef 1540 \r
1541 IpCount ++;\r
3093f45c
JW
1542 Status = EFI_SUCCESS;\r
1543 break;\r
1544 case DNS_TYPE_CNAME:\r
1545 //\r
1546 // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME \r
1547 // record in the response and restart the query at the domain name specified in the data field of the \r
1548 // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.\r
1549 //\r
1550 CNameTtl = AnswerSection->Ttl;\r
99c048ef 1551 break;\r
1552 default:\r
1553 Status = EFI_UNSUPPORTED;\r
1554 goto ON_EXIT;\r
1555 }\r
1556 }\r
1557 \r
1558 //\r
1559 // Find next one\r
1560 //\r
1561 AnswerName = (CHAR8 *) AnswerSection + sizeof (*AnswerSection) + AnswerSection->DataLength;\r
1562 AnswerSectionNum ++;\r
1563 }\r
1564\r
00c0c3f2
JW
1565 if (Instance->Service->IpVersion == IP_VERSION_4) {\r
1566 ASSERT (Dns4TokenEntry != NULL);\r
fcae1a99
JW
1567 \r
1568 if (Dns4TokenEntry->GeneralLookUp) {\r
1569 Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
00c0c3f2 1570 } else {\r
fcae1a99
JW
1571 if (QuerySection->Type == DNS_TYPE_A) {\r
1572 Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
1573 } else {\r
1574 Status = EFI_UNSUPPORTED;\r
1575 goto ON_EXIT;\r
1576 }\r
00c0c3f2
JW
1577 }\r
1578 } else {\r
1579 ASSERT (Dns6TokenEntry != NULL);\r
fcae1a99
JW
1580\r
1581 if (Dns6TokenEntry->GeneralLookUp) {\r
1582 Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
00c0c3f2 1583 } else {\r
fcae1a99
JW
1584 if (QuerySection->Type == DNS_TYPE_AAAA) {\r
1585 Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
1586 } else {\r
1587 Status = EFI_UNSUPPORTED;\r
1588 goto ON_EXIT;\r
1589 }\r
00c0c3f2 1590 }\r
99c048ef 1591 }\r
0a92ac88
JW
1592 \r
1593ON_COMPLETE:\r
99c048ef 1594 //\r
3093f45c 1595 // Parsing is complete, free the sending packet and signal Event here.\r
99c048ef 1596 //\r
3093f45c
JW
1597 if (Item != NULL && Item->Value != NULL) {\r
1598 NetbufFree ((NET_BUF *) (Item->Value));\r
1599 }\r
1600 \r
99c048ef 1601 if (Instance->Service->IpVersion == IP_VERSION_4) {\r
00c0c3f2 1602 ASSERT (Dns4TokenEntry != NULL);\r
99c048ef 1603 Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);\r
3093f45c 1604 Dns4TokenEntry->Token->Status = Status;\r
99c048ef 1605 if (Dns4TokenEntry->Token->Event != NULL) {\r
1606 gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
1607 DispatchDpc ();\r
1608 }\r
1609 } else {\r
00c0c3f2 1610 ASSERT (Dns6TokenEntry != NULL);\r
99c048ef 1611 Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);\r
3093f45c 1612 Dns6TokenEntry->Token->Status = Status;\r
99c048ef 1613 if (Dns6TokenEntry->Token->Event != NULL) {\r
1614 gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
1615 DispatchDpc ();\r
1616 }\r
1617 }\r
1618\r
99c048ef 1619ON_EXIT:\r
43d7e607
JW
1620 //\r
1621 // Free the allocated buffer if error happen.\r
1622 //\r
1623 if (EFI_ERROR (Status)) {\r
1624 if (Dns4TokenEntry != NULL) {\r
1625 if (Dns4TokenEntry->GeneralLookUp) {\r
1626 if (Dns4TokenEntry->Token->RspData.GLookupData != NULL) {\r
1627 if (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL) {\r
1628 while (RRCount != 0) {\r
1629 RRCount --;\r
1630 if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {\r
1631 FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);\r
1632 }\r
1633\r
1634 if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {\r
1635 FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);\r
1636 }\r
1637 }\r
1638 \r
1639 FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);\r
1640 }\r
1641 \r
1642 FreePool (Dns4TokenEntry->Token->RspData.GLookupData);\r
1643 }\r
1644 } else {\r
1645 if (QuerySection->Type == DNS_TYPE_A && Dns4TokenEntry->Token->RspData.H2AData != NULL) {\r
1646 if (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL) {\r
1647 FreePool (Dns4TokenEntry->Token->RspData.H2AData->IpList);\r
1648 }\r
1649 \r
1650 FreePool (Dns4TokenEntry->Token->RspData.H2AData);\r
1651 }\r
1652 }\r
1653 }\r
1654\r
1655 if (Dns6TokenEntry != NULL) {\r
1656 if (Dns6TokenEntry->GeneralLookUp) {\r
1657 if (Dns6TokenEntry->Token->RspData.GLookupData != NULL) {\r
1658 if (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL) {\r
1659 while (RRCount != 0) {\r
1660 RRCount --;\r
1661 if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {\r
1662 FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);\r
1663 }\r
1664\r
1665 if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {\r
1666 FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);\r
1667 }\r
1668 }\r
1669 \r
1670 FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);\r
1671 }\r
1672 \r
1673 FreePool (Dns6TokenEntry->Token->RspData.GLookupData);\r
1674 }\r
1675 } else {\r
1676 if (QuerySection->Type == DNS_TYPE_AAAA && Dns6TokenEntry->Token->RspData.H2AData != NULL) {\r
1677 if (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL) {\r
1678 FreePool (Dns6TokenEntry->Token->RspData.H2AData->IpList);\r
1679 }\r
1680 \r
1681 FreePool (Dns6TokenEntry->Token->RspData.H2AData);\r
1682 }\r
1683 }\r
1684 }\r
1685\r
1686 if (Dns4CacheEntry != NULL) {\r
1687 if (Dns4CacheEntry->HostName != NULL) {\r
1688 FreePool (Dns4CacheEntry->HostName);\r
1689 }\r
1690\r
1691 if (Dns4CacheEntry->IpAddress != NULL) {\r
1692 FreePool (Dns4CacheEntry->IpAddress);\r
1693 }\r
1694\r
1695 FreePool (Dns4CacheEntry);\r
1696 }\r
1697\r
1698 if (Dns6CacheEntry != NULL) {\r
1699 if (Dns6CacheEntry->HostName != NULL) {\r
1700 FreePool (Dns6CacheEntry->HostName);\r
1701 }\r
1702\r
1703 if (Dns6CacheEntry->IpAddress != NULL) {\r
1704 FreePool (Dns6CacheEntry->IpAddress);\r
1705 }\r
1706\r
1707 FreePool (Dns6CacheEntry);\r
1708 } \r
1709 }\r
1710 \r
99c048ef 1711 gBS->RestoreTPL (OldTpl);\r
1712 return Status;\r
1713}\r
1714\r
1715/**\r
1716 Parse response packet.\r
1717\r
1718 @param Packet The packets received.\r
1719 @param EndPoint The local/remote UDP access point\r
1720 @param IoStatus The status of the UDP receive\r
1721 @param Context The opaque parameter to the function.\r
1722\r
1723**/ \r
1724VOID\r
1725EFIAPI\r
1726DnsOnPacketReceived (\r
1727 NET_BUF *Packet,\r
1728 UDP_END_POINT *EndPoint,\r
1729 EFI_STATUS IoStatus,\r
1730 VOID *Context\r
1731 )\r
1732{\r
1733 DNS_INSTANCE *Instance;\r
1734\r
1735 UINT8 *RcvString;\r
1736\r
1737 BOOLEAN Completed;\r
1738 \r
1739 Instance = (DNS_INSTANCE *) Context;\r
1740 NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);\r
1741\r
1742 RcvString = NULL;\r
1743 Completed = FALSE;\r
1744\r
1745 if (EFI_ERROR (IoStatus)) {\r
1746 goto ON_EXIT;\r
1747 }\r
1748\r
1749 ASSERT (Packet != NULL);\r
37b68011
FS
1750\r
1751 if (Packet->TotalSize <= sizeof (DNS_HEADER)) {\r
1752 goto ON_EXIT;\r
1753 }\r
99c048ef 1754 \r
1755 RcvString = NetbufGetByte (Packet, 0, NULL);\r
3fd7bd08 1756 ASSERT (RcvString != NULL);\r
1757 \r
99c048ef 1758 //\r
1759 // Parse Dns Response\r
1760 //\r
1761 ParseDnsResponse (Instance, RcvString, &Completed);\r
1762\r
37b68011 1763ON_EXIT:\r
99c048ef 1764\r
37b68011
FS
1765 if (Packet != NULL) {\r
1766 NetbufFree (Packet);\r
1767 }\r
99c048ef 1768\r
37b68011
FS
1769 if (!Completed) {\r
1770 UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
1771 }\r
99c048ef 1772}\r
1773\r
1774/**\r
1775 Release the net buffer when packet is sent.\r
1776\r
1777 @param Packet The packets received.\r
1778 @param EndPoint The local/remote UDP access point\r
1779 @param IoStatus The status of the UDP receive\r
1780 @param Context The opaque parameter to the function.\r
1781\r
1782**/\r
1783VOID\r
1784EFIAPI\r
1785DnsOnPacketSent (\r
1786 NET_BUF *Packet,\r
1787 UDP_END_POINT *EndPoint,\r
1788 EFI_STATUS IoStatus,\r
1789 VOID *Context\r
1790 )\r
1791{\r
1792 DNS_INSTANCE *Instance;\r
1793 LIST_ENTRY *Entry;\r
1794 NET_MAP_ITEM *Item;\r
1795 DNS4_TOKEN_ENTRY *Dns4TokenEntry;\r
1796 DNS6_TOKEN_ENTRY *Dns6TokenEntry;\r
1797\r
1798 Dns4TokenEntry = NULL;\r
1799 Dns6TokenEntry = NULL;\r
1800\r
1801 Instance = (DNS_INSTANCE *) Context;\r
1802 NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);\r
1803\r
1804 if (Instance->Service->IpVersion == IP_VERSION_4) {\r
1805 NET_LIST_FOR_EACH (Entry, &Instance->Dns4TxTokens.Used) {\r
1806 Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
1807 if (Packet == (NET_BUF *)(Item->Value)) {\r
1808 Dns4TokenEntry = ((DNS4_TOKEN_ENTRY *)Item->Key);\r
1809 Dns4TokenEntry->PacketToLive = Dns4TokenEntry->Token->RetryInterval;\r
1810 break;\r
1811 }\r
1812 }\r
1813 } else {\r
1814 NET_LIST_FOR_EACH (Entry, &Instance->Dns6TxTokens.Used) {\r
1815 Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
1816 if (Packet == (NET_BUF *)(Item->Value)) {\r
1817 Dns6TokenEntry = ((DNS6_TOKEN_ENTRY *)Item->Key);\r
1818 Dns6TokenEntry->PacketToLive = Dns6TokenEntry->Token->RetryInterval;\r
1819 break;\r
1820 }\r
1821 }\r
1822 }\r
1823 \r
1824 NetbufFree (Packet);\r
1825}\r
1826\r
1827/**\r
1828 Query request information.\r
1829\r
1830 @param Instance The DNS instance\r
1831 @param Packet The packet for querying request information.\r
1832\r
1833 @retval EFI_SUCCESS Query request information successfully.\r
1834 @retval Others Failed to query request information.\r
1835\r
1836**/\r
1837EFI_STATUS\r
1838DoDnsQuery (\r
1839 IN DNS_INSTANCE *Instance,\r
1840 IN NET_BUF *Packet\r
1841 )\r
1842{\r
1843 EFI_STATUS Status;\r
1844\r
1845 //\r
1846 // Ready to receive the DNS response.\r
1847 //\r
1848 if (Instance->UdpIo->RecvRequest == NULL) {\r
1849 Status = UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
1850 if (EFI_ERROR (Status)) {\r
1851 return Status;\r
1852 }\r
1853 }\r
1854 \r
1855 //\r
1856 // Transmit the DNS packet.\r
1857 //\r
1858 NET_GET_REF (Packet);\r
1859\r
1860 Status = UdpIoSendDatagram (Instance->UdpIo, Packet, NULL, NULL, DnsOnPacketSent, Instance);\r
1861 \r
1862 return Status;\r
1863}\r
1864\r
1865/**\r
fcae1a99 1866 Construct the Packet according query section.\r
99c048ef 1867\r
1868 @param Instance The DNS instance\r
fcae1a99
JW
1869 @param QueryName Queried Name \r
1870 @param Type Queried Type \r
1871 @param Class Queried Class \r
1872 @param Packet The packet for query\r
99c048ef 1873\r
1874 @retval EFI_SUCCESS The packet is constructed.\r
1875 @retval Others Failed to construct the Packet.\r
1876\r
1877**/\r
1878EFI_STATUS\r
fcae1a99 1879ConstructDNSQuery (\r
99c048ef 1880 IN DNS_INSTANCE *Instance,\r
fcae1a99 1881 IN CHAR8 *QueryName,\r
99c048ef 1882 IN UINT16 Type,\r
fcae1a99 1883 IN UINT16 Class,\r
99c048ef 1884 OUT NET_BUF **Packet\r
1885 )\r
1886{\r
1887 NET_FRAGMENT Frag;\r
1888 DNS_HEADER *DnsHeader;\r
fcae1a99 1889 DNS_QUERY_SECTION *DnsQuery;\r
3700da73
JW
1890\r
1891 //\r
1892 // Messages carried by UDP are restricted to 512 bytes (not counting the IP\r
1893 // or UDP headers).\r
1894 //\r
1895 Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));\r
99c048ef 1896 if (Frag.Bulk == NULL) {\r
1897 return EFI_OUT_OF_RESOURCES;\r
1898 }\r
1899\r
1900 //\r
1901 // Fill header\r
1902 //\r
5e0cdec1
ZL
1903 DnsHeader = (DNS_HEADER *) Frag.Bulk; \r
1904 DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed());\r
99c048ef 1905 DnsHeader->Flags.Uint16 = 0x0000;\r
1906 DnsHeader->Flags.Bits.RD = 1;\r
1907 DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;\r
1908 DnsHeader->Flags.Bits.QR = DNS_FLAGS_QR_QUERY;\r
1909 DnsHeader->QuestionsNum = 1;\r
1910 DnsHeader->AnswersNum = 0;\r
1911 DnsHeader->AuthorityNum = 0;\r
1912 DnsHeader->AditionalNum = 0;\r
1913\r
5e0cdec1
ZL
1914 DnsHeader->Identification = HTONS (DnsHeader->Identification);\r
1915 DnsHeader->Flags.Uint16 = HTONS (DnsHeader->Flags.Uint16);\r
1916 DnsHeader->QuestionsNum = HTONS (DnsHeader->QuestionsNum);\r
1917 DnsHeader->AnswersNum = HTONS (DnsHeader->AnswersNum);\r
1918 DnsHeader->AuthorityNum = HTONS (DnsHeader->AuthorityNum);\r
1919 DnsHeader->AditionalNum = HTONS (DnsHeader->AditionalNum);\r
99c048ef 1920\r
1921 Frag.Len = sizeof (*DnsHeader);\r
1922\r
1923 //\r
1924 // Fill Query name\r
1925 //\r
fcae1a99
JW
1926 CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));\r
1927 Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));\r
1928 *(Frag.Bulk + Frag.Len) = 0;\r
1929 Frag.Len ++;\r
1930 \r
99c048ef 1931 //\r
1932 // Rest query section\r
1933 //\r
fcae1a99 1934 DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);\r
99c048ef 1935\r
fcae1a99
JW
1936 DnsQuery->Type = HTONS (Type);\r
1937 DnsQuery->Class = HTONS (Class);\r
99c048ef 1938\r
fcae1a99 1939 Frag.Len += sizeof (*DnsQuery);\r
99c048ef 1940\r
1941 //\r
1942 // Wrap the Frag in a net buffer.\r
1943 //\r
1944 *Packet = NetbufFromExt (&Frag, 1, 0, 0, DnsDummyExtFree, NULL);\r
1945 if (*Packet == NULL) {\r
1946 FreePool (Frag.Bulk);\r
1947 return EFI_OUT_OF_RESOURCES;\r
1948 }\r
1949 \r
1950 //\r
1951 // Store the UdpIo in ProtoData.\r
1952 //\r
1953 *((UINTN *) &((*Packet)->ProtoData[0])) = (UINTN) (Instance->UdpIo);\r
1954\r
1955 return EFI_SUCCESS;\r
1956}\r
1957\r
1958/**\r
1959 Retransmit the packet.\r
1960\r
1961 @param Instance The DNS instance\r
1962 @param Packet Retransmit the packet \r
1963\r
1964 @retval EFI_SUCCESS The packet is retransmitted.\r
1965 @retval Others Failed to retransmit.\r
1966\r
1967**/\r
1968EFI_STATUS\r
1969DnsRetransmit (\r
1970 IN DNS_INSTANCE *Instance,\r
1971 IN NET_BUF *Packet\r
1972 )\r
1973{\r
1974 EFI_STATUS Status;\r
1975 \r
1976 UINT8 *Buffer;\r
1977\r
1978 ASSERT (Packet != NULL);\r
1979\r
1980 //\r
1981 // Set the requests to the listening port, other packets to the connected port\r
1982 //\r
1983 Buffer = NetbufGetByte (Packet, 0, NULL);\r
1984 ASSERT (Buffer != NULL);\r
1985\r
1986 NET_GET_REF (Packet);\r
1987\r
1988 Status = UdpIoSendDatagram (\r
1989 Instance->UdpIo,\r
1990 Packet,\r
1991 NULL,\r
1992 NULL,\r
1993 DnsOnPacketSent,\r
1994 Instance\r
1995 );\r
1996\r
1997 if (EFI_ERROR (Status)) {\r
1998 NET_PUT_REF (Packet);\r
1999 }\r
2000\r
2001 return Status;\r
2002}\r
2003\r
2004/**\r
2005 The timer ticking function for the DNS services.\r
2006\r
2007 @param Event The ticking event\r
2008 @param Context The DNS service instance\r
2009\r
2010**/\r
2011VOID\r
2012EFIAPI\r
2013DnsOnTimerRetransmit (\r
2014 IN EFI_EVENT Event,\r
2015 IN VOID *Context\r
2016 )\r
2017{\r
2018 DNS_SERVICE *Service;\r
2019\r
2020 LIST_ENTRY *Entry;\r
2021 LIST_ENTRY *Next;\r
2022\r
2023 DNS_INSTANCE *Instance;\r
2024 LIST_ENTRY *EntryNetMap;\r
2025 NET_MAP_ITEM *ItemNetMap;\r
2026 DNS4_TOKEN_ENTRY *Dns4TokenEntry;\r
2027 DNS6_TOKEN_ENTRY *Dns6TokenEntry;\r
2028\r
2029 Dns4TokenEntry = NULL;\r
2030 Dns6TokenEntry = NULL;\r
2031\r
2032 Service = (DNS_SERVICE *) Context;\r
2033\r
2034\r
2035 if (Service->IpVersion == IP_VERSION_4) {\r
2036 //\r
2037 // Iterate through all the children of the DNS service instance. Time\r
2038 // out the packet. If maximum retries reached, clean the Token up.\r
2039 //\r
2040 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns4ChildrenList) {\r
2041 Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);\r
2042\r
2043 EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;\r
2044 while (EntryNetMap != &Instance->Dns4TxTokens.Used) {\r
2045 ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);\r
2046 Dns4TokenEntry = (DNS4_TOKEN_ENTRY *)(ItemNetMap->Key);\r
2047 if (Dns4TokenEntry->PacketToLive == 0 || (--Dns4TokenEntry->PacketToLive > 0)) {\r
2048 EntryNetMap = EntryNetMap->ForwardLink;\r
2049 continue;\r
2050 }\r
2051\r
2052 //\r
2053 // Retransmit the packet if haven't reach the maxmium retry count,\r
2054 // otherwise exit the transfer.\r
2055 //\r
cd2a6240 2056 if (++Dns4TokenEntry->RetryCounting <= Dns4TokenEntry->Token->RetryCount) {\r
99c048ef 2057 DnsRetransmit (Instance, (NET_BUF *)ItemNetMap->Value);\r
2058 EntryNetMap = EntryNetMap->ForwardLink;\r
2059 } else {\r
2060 //\r
2061 // Maximum retries reached, clean the Token up.\r
2062 //\r
2063 Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);\r
2064 Dns4TokenEntry->Token->Status = EFI_TIMEOUT;\r
2065 gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
2066 DispatchDpc ();\r
2067 \r
2068 //\r
2069 // Free the sending packet.\r
2070 //\r
2071 if (ItemNetMap->Value != NULL) {\r
2072 NetbufFree ((NET_BUF *)(ItemNetMap->Value));\r
2073 }\r
2074\r
2075 EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;\r
2076 }\r
2077 }\r
2078 } \r
2079 }else {\r
2080 //\r
2081 // Iterate through all the children of the DNS service instance. Time\r
2082 // out the packet. If maximum retries reached, clean the Token up.\r
2083 //\r
2084 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns6ChildrenList) {\r
2085 Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);\r
2086 \r
2087 EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;\r
2088 while (EntryNetMap != &Instance->Dns6TxTokens.Used) {\r
2089 ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);\r
2090 Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (ItemNetMap->Key);\r
2091 if (Dns6TokenEntry->PacketToLive == 0 || (--Dns6TokenEntry->PacketToLive > 0)) {\r
2092 EntryNetMap = EntryNetMap->ForwardLink;\r
2093 continue;\r
2094 }\r
2095\r
2096 //\r
2097 // Retransmit the packet if haven't reach the maxmium retry count,\r
2098 // otherwise exit the transfer.\r
2099 //\r
cd2a6240 2100 if (++Dns6TokenEntry->RetryCounting <= Dns6TokenEntry->Token->RetryCount) {\r
99c048ef 2101 DnsRetransmit (Instance, (NET_BUF *) ItemNetMap->Value);\r
2102 EntryNetMap = EntryNetMap->ForwardLink;\r
2103 } else {\r
2104 //\r
2105 // Maximum retries reached, clean the Token up.\r
2106 //\r
2107 Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);\r
2108 Dns6TokenEntry->Token->Status = EFI_TIMEOUT;\r
2109 gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
2110 DispatchDpc ();\r
2111 \r
2112 //\r
2113 // Free the sending packet.\r
2114 //\r
2115 if (ItemNetMap->Value != NULL) {\r
2116 NetbufFree ((NET_BUF *) (ItemNetMap->Value));\r
2117 }\r
2118\r
2119 EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;\r
2120 } \r
2121 }\r
2122 }\r
2123 } \r
2124}\r
2125\r
2126/**\r
2127 The timer ticking function for the DNS driver.\r
2128\r
2129 @param Event The ticking event\r
2130 @param Context NULL\r
2131\r
2132**/\r
2133VOID\r
2134EFIAPI\r
2135DnsOnTimerUpdate (\r
2136 IN EFI_EVENT Event,\r
2137 IN VOID *Context\r
2138 )\r
2139{\r
2140 LIST_ENTRY *Entry;\r
2141 LIST_ENTRY *Next;\r
2142 DNS4_CACHE *Item4;\r
2143 DNS6_CACHE *Item6;\r
2144\r
2145 Item4 = NULL;\r
2146 Item6 = NULL;\r
2147\r
2148 //\r
2149 // Iterate through all the DNS4 cache list.\r
2150 //\r
2151 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
2152 Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
2153 Item4->DnsCache.Timeout--;\r
2154 }\r
2155 \r
2156 Entry = mDriverData->Dns4CacheList.ForwardLink;\r
2157 while (Entry != &mDriverData->Dns4CacheList) {\r
2158 Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
3093f45c 2159 if (Item4->DnsCache.Timeout == 0) {\r
99c048ef 2160 RemoveEntryList (&Item4->AllCacheLink);\r
43d7e607
JW
2161 FreePool (Item4->DnsCache.HostName);\r
2162 FreePool (Item4->DnsCache.IpAddress);\r
2163 FreePool (Item4);\r
99c048ef 2164 Entry = mDriverData->Dns4CacheList.ForwardLink;\r
2165 } else {\r
2166 Entry = Entry->ForwardLink;\r
2167 }\r
2168 }\r
2169 \r
2170 //\r
2171 // Iterate through all the DNS6 cache list.\r
2172 //\r
2173 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
2174 Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
2175 Item6->DnsCache.Timeout--;\r
2176 }\r
2177 \r
2178 Entry = mDriverData->Dns6CacheList.ForwardLink;\r
2179 while (Entry != &mDriverData->Dns6CacheList) {\r
2180 Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
3093f45c 2181 if (Item6->DnsCache.Timeout == 0) {\r
99c048ef 2182 RemoveEntryList (&Item6->AllCacheLink);\r
43d7e607
JW
2183 FreePool (Item6->DnsCache.HostName);\r
2184 FreePool (Item6->DnsCache.IpAddress);\r
2185 FreePool (Item6);\r
99c048ef 2186 Entry = mDriverData->Dns6CacheList.ForwardLink;\r
2187 } else {\r
2188 Entry = Entry->ForwardLink;\r
2189 }\r
2190 }\r
2191}\r
2192\r