]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/DnsDxe/DnsImpl.c
NetworkPkg: Clean up source files
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsImpl.c
CommitLineData
99c048ef 1/** @file\r
2DnsDxe support functions implementation.\r
f75a7f56
LG
3\r
4Copyright (c) 2016 - 2018, 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
f75a7f56 48\r
99c048ef 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
f75a7f56 60\r
99c048ef 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
f75a7f56 83\r
99c048ef 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
f75a7f56 222 IN EFI_DNS4_COMPLETION_TOKEN *Token,\r
99c048ef 223 OUT DNS4_TOKEN_ENTRY **TokenEntry\r
224 )\r
225{\r
226 LIST_ENTRY *Entry;\r
f75a7f56 227\r
99c048ef 228 NET_MAP_ITEM *Item;\r
f75a7f56 229\r
99c048ef 230 NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
231 Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
f75a7f56 232 *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
99c048ef 233 if ((*TokenEntry)->Token == Token) {\r
234 return EFI_SUCCESS;\r
235 }\r
236 }\r
f75a7f56 237\r
99c048ef 238 *TokenEntry = NULL;\r
f75a7f56 239\r
99c048ef 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
f75a7f56 258 IN EFI_DNS6_COMPLETION_TOKEN *Token,\r
99c048ef 259 OUT DNS6_TOKEN_ENTRY **TokenEntry\r
260 )\r
261{\r
262 LIST_ENTRY *Entry;\r
f75a7f56 263\r
99c048ef 264 NET_MAP_ITEM *Item;\r
f75a7f56 265\r
99c048ef 266 NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
267 Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
f75a7f56 268 *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);\r
99c048ef 269 if ((*TokenEntry)->Token == Token) {\r
270 return EFI_SUCCESS;\r
271 }\r
272 }\r
f75a7f56 273\r
99c048ef 274 *TokenEntry =NULL;\r
f75a7f56 275\r
99c048ef 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
f75a7f56 328\r
99c048ef 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
f75a7f56 385\r
99c048ef 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
f75a7f56
LG
529 by DHCP.\r
530\r
531 The default time out value is 5 seconds. If IP has retrieved the default address,\r
99c048ef 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
f75a7f56 660\r
99c048ef 661 @param Instance The DNS session\r
662 @param UdpIo The UDP_IO instance\r
f75a7f56 663\r
99c048ef 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
f75a7f56 702\r
99c048ef 703 return Status;\r
704}\r
705\r
706/**\r
707 Configure the UDP.\r
f75a7f56 708\r
99c048ef 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
f75a7f56 745\r
99c048ef 746 return Status;\r
747}\r
748\r
749/**\r
750 Update Dns4 cache to shared list of caches of all DNSv4 instances.\r
f75a7f56 751\r
99c048ef 752 @param Dns4CacheList All Dns4 cache list.\r
f75a7f56
LG
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
99c048ef 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
f75a7f56
LG
760 @retval Others Failed to update Dns4 cache.\r
761\r
762**/\r
99c048ef 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
f75a7f56 772 DNS4_CACHE *NewDnsCache;\r
99c048ef 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
f75a7f56 779\r
99c048ef 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
f75a7f56 799\r
99c048ef 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
f75a7f56 806\r
99c048ef 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
f75a7f56 818 if (NewDnsCache == NULL) {\r
99c048ef 819 return EFI_OUT_OF_RESOURCES;\r
820 }\r
f75a7f56 821\r
99c048ef 822 InitializeListHead (&NewDnsCache->AllCacheLink);\r
f75a7f56 823\r
99c048ef 824 NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
f75a7f56 825 if (NewDnsCache->DnsCache.HostName == NULL) {\r
43d7e607 826 FreePool (NewDnsCache);\r
99c048ef 827 return EFI_OUT_OF_RESOURCES;\r
828 }\r
f75a7f56 829\r
99c048ef 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
f75a7f56 842\r
99c048ef 843 InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);\r
f75a7f56 844\r
99c048ef 845 return EFI_SUCCESS;\r
846}\r
847\r
848/**\r
f75a7f56 849 Update Dns6 cache to shared list of caches of all DNSv6 instances.\r
99c048ef 850\r
851 @param Dns6CacheList All Dns6 cache list.\r
f75a7f56
LG
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
99c048ef 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
f75a7f56 857\r
99c048ef 858 @retval EFI_SUCCESS Update Dns6 cache successfully.\r
859 @retval Others Failed to update Dns6 cache.\r
f75a7f56 860**/\r
99c048ef 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
f75a7f56 870 DNS6_CACHE *NewDnsCache;\r
99c048ef 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
f75a7f56 877\r
99c048ef 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
f75a7f56 893\r
43d7e607
JW
894 FreePool (Item->DnsCache.HostName);\r
895 FreePool (Item->DnsCache.IpAddress);\r
896 FreePool (Item);\r
f75a7f56 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
f75a7f56 904\r
99c048ef 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
f75a7f56 916 if (NewDnsCache == NULL) {\r
99c048ef 917 return EFI_OUT_OF_RESOURCES;\r
918 }\r
f75a7f56 919\r
99c048ef 920 InitializeListHead (&NewDnsCache->AllCacheLink);\r
f75a7f56 921\r
99c048ef 922 NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
f75a7f56 923 if (NewDnsCache->DnsCache.HostName == NULL) {\r
43d7e607 924 FreePool (NewDnsCache);\r
99c048ef 925 return EFI_OUT_OF_RESOURCES;\r
926 }\r
f75a7f56 927\r
99c048ef 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
f75a7f56 936\r
99c048ef 937 CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
938\r
939 NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
f75a7f56 940\r
99c048ef 941 InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);\r
f75a7f56 942\r
99c048ef 943 return EFI_SUCCESS;\r
944}\r
945\r
946/**\r
f75a7f56 947 Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.\r
99c048ef 948\r
f75a7f56
LG
949 @param Dns4ServerList Common list of addresses of all configured DNSv4 server.\r
950 @param ServerIp DNS server Ip.\r
99c048ef 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
f75a7f56
LG
954\r
955**/\r
99c048ef 956EFI_STATUS\r
957EFIAPI\r
958AddDns4ServerIp (\r
959 IN LIST_ENTRY *Dns4ServerList,\r
960 IN EFI_IPv4_ADDRESS ServerIp\r
961 )\r
962{\r
f75a7f56 963 DNS4_SERVER_IP *NewServerIp;\r
99c048ef 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
f75a7f56 970\r
99c048ef 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
f75a7f56 979 //\r
99c048ef 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
f75a7f56 988 if (NewServerIp == NULL) {\r
99c048ef 989 return EFI_OUT_OF_RESOURCES;\r
990 }\r
f75a7f56 991\r
99c048ef 992 InitializeListHead (&NewServerIp->AllServerLink);\r
f75a7f56 993\r
99c048ef 994 CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
f75a7f56 995\r
99c048ef 996 InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);\r
f75a7f56 997\r
99c048ef 998 return EFI_SUCCESS;\r
999}\r
1000\r
1001/**\r
f75a7f56 1002 Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.\r
99c048ef 1003\r
f75a7f56
LG
1004 @param Dns6ServerList Common list of addresses of all configured DNSv6 server.\r
1005 @param ServerIp DNS server Ip.\r
99c048ef 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
f75a7f56
LG
1009\r
1010**/\r
99c048ef 1011EFI_STATUS\r
1012EFIAPI\r
1013AddDns6ServerIp (\r
1014 IN LIST_ENTRY *Dns6ServerList,\r
1015 IN EFI_IPv6_ADDRESS ServerIp\r
1016 )\r
1017{\r
f75a7f56 1018 DNS6_SERVER_IP *NewServerIp;\r
99c048ef 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
f75a7f56 1025\r
99c048ef 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
f75a7f56 1034 //\r
99c048ef 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
f75a7f56 1043 if (NewServerIp == NULL) {\r
99c048ef 1044 return EFI_OUT_OF_RESOURCES;\r
1045 }\r
f75a7f56 1046\r
99c048ef 1047 InitializeListHead (&NewServerIp->AllServerLink);\r
f75a7f56 1048\r
99c048ef 1049 CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
f75a7f56 1050\r
99c048ef 1051 InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);\r
f75a7f56 1052\r
99c048ef 1053 return EFI_SUCCESS;\r
1054}\r
1055\r
1056/**\r
1057 Find out whether the response is valid or invalid.\r
1058\r
f75a7f56
LG
1059 @param TokensMap All DNS transmittal Tokens entry.\r
1060 @param Identification Identification for queried packet.\r
99c048ef 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
f75a7f56
LG
1067\r
1068**/\r
99c048ef 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
f75a7f56 1090\r
99c048ef 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
f75a7f56 1098\r
3900a743 1099 if (NTOHS (DnsHeader->Identification) == Identification &&\r
f75a7f56 1100 NTOHS (QuerySection->Type) == Type &&\r
3900a743 1101 NTOHS (QuerySection->Class) == Class) {\r
99c048ef 1102 return TRUE;\r
1103 }\r
f75a7f56 1104 }\r
99c048ef 1105 }\r
f75a7f56 1106\r
3900a743 1107 *Item = NULL;\r
f75a7f56 1108\r
99c048ef 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
f75a7f56
LG
1117 @param Completed Flag to indicate that Dns response is valid.\r
1118\r
99c048ef 1119 @retval EFI_SUCCESS Parse Dns Response successfully.\r
1120 @retval Others Failed to parse Dns Response.\r
f75a7f56
LG
1121\r
1122**/\r
99c048ef 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
f75a7f56 1131\r
99c048ef 1132 CHAR8 *QueryName;\r
1133 DNS_QUERY_SECTION *QuerySection;\r
f75a7f56 1134\r
99c048ef 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
f75a7f56 1142\r
99c048ef 1143 UINT32 IpCount;\r
fcae1a99 1144 UINT32 RRCount;\r
99c048ef 1145 UINT32 AnswerSectionNum;\r
3093f45c 1146 UINT32 CNameTtl;\r
f75a7f56 1147\r
99c048ef 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
f75a7f56 1160\r
99c048ef 1161 Item = NULL;\r
1162 Dns4TokenEntry = NULL;\r
1163 Dns6TokenEntry = NULL;\r
f75a7f56 1164\r
99c048ef 1165 IpCount = 0;\r
fcae1a99 1166 RRCount = 0;\r
99c048ef 1167 AnswerSectionNum = 0;\r
3093f45c 1168 CNameTtl = 0;\r
f75a7f56 1169\r
99c048ef 1170 HostAddr4 = NULL;\r
1171 HostAddr6 = NULL;\r
f75a7f56 1172\r
99c048ef 1173 Dns4CacheEntry = NULL;\r
1174 Dns6CacheEntry = NULL;\r
f75a7f56 1175\r
fcae1a99
JW
1176 Dns4RR = NULL;\r
1177 Dns6RR = NULL;\r
99c048ef 1178\r
1179 *Completed = TRUE;\r
1180 Status = EFI_SUCCESS;\r
f75a7f56 1181\r
99c048ef 1182 //\r
1183 // Get header\r
1184 //\r
1185 DnsHeader = (DNS_HEADER *) RxString;\r
f75a7f56 1186\r
99c048ef 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 1217 if (!IsValidDnsResponse (\r
f75a7f56
LG
1218 &Instance->Dns4TxTokens,\r
1219 DnsHeader->Identification,\r
3900a743
JW
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 1231 if (!IsValidDnsResponse (\r
f75a7f56
LG
1232 &Instance->Dns6TxTokens,\r
1233 DnsHeader->Identification,\r
3900a743
JW
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
f75a7f56 1245\r
99c048ef 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
f75a7f56 1255 Status = EFI_NOT_FOUND;\r
0a92ac88
JW
1256 } else {\r
1257 Status = EFI_DEVICE_ERROR;\r
1258 }\r
f75a7f56 1259\r
0a92ac88 1260 goto ON_COMPLETE;\r
99c048ef 1261 }\r
f75a7f56 1262\r
99c048ef 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
f75a7f56 1355\r
99c048ef 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
f75a7f56 1391\r
fcae1a99 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
f75a7f56 1417\r
fcae1a99 1418 RRCount ++;\r
3093f45c 1419 Status = EFI_SUCCESS;\r
fcae1a99
JW
1420 } else {\r
1421 //\r
f75a7f56 1422 // It's not the GeneralLookUp querying.\r
fcae1a99
JW
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
f75a7f56 1436\r
99c048ef 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
f75a7f56 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
f75a7f56 1467\r
0a92ac88
JW
1468 UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);\r
1469\r
f75a7f56 1470 //\r
0a92ac88
JW
1471 // Free allocated CacheEntry pool.\r
1472 //\r
1473 FreePool (Dns4CacheEntry->HostName);\r
1474 Dns4CacheEntry->HostName = NULL;\r
f75a7f56 1475\r
0a92ac88
JW
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
f75a7f56 1495\r
99c048ef 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
f75a7f56 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
f75a7f56 1526\r
0a92ac88
JW
1527 UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);\r
1528\r
f75a7f56 1529 //\r
0a92ac88
JW
1530 // Free allocated CacheEntry pool.\r
1531 //\r
1532 FreePool (Dns6CacheEntry->HostName);\r
1533 Dns6CacheEntry->HostName = NULL;\r
f75a7f56 1534\r
0a92ac88
JW
1535 FreePool (Dns6CacheEntry->IpAddress);\r
1536 Dns6CacheEntry->IpAddress = NULL;\r
1537\r
1538 FreePool (Dns6CacheEntry);\r
1539 Dns6CacheEntry = NULL;\r
f75a7f56 1540\r
99c048ef 1541 IpCount ++;\r
3093f45c
JW
1542 Status = EFI_SUCCESS;\r
1543 break;\r
1544 case DNS_TYPE_CNAME:\r
1545 //\r
f75a7f56
LG
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
3093f45c
JW
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
f75a7f56 1557\r
99c048ef 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
f75a7f56 1567\r
fcae1a99
JW
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
f75a7f56 1592\r
0a92ac88 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
f75a7f56 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
f75a7f56 1638\r
43d7e607
JW
1639 FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);\r
1640 }\r
f75a7f56 1641\r
43d7e607
JW
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
f75a7f56 1649\r
43d7e607
JW
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
f75a7f56 1669\r
43d7e607
JW
1670 FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);\r
1671 }\r
f75a7f56 1672\r
43d7e607
JW
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
f75a7f56 1680\r
43d7e607
JW
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
f75a7f56 1708 }\r
43d7e607 1709 }\r
f75a7f56 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
f75a7f56 1723**/\r
99c048ef 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
f75a7f56 1738\r
99c048ef 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
f75a7f56 1754\r
99c048ef 1755 RcvString = NetbufGetByte (Packet, 0, NULL);\r
3fd7bd08 1756 ASSERT (RcvString != NULL);\r
f75a7f56 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
f75a7f56 1823\r
99c048ef 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
f75a7f56 1854\r
99c048ef 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
f75a7f56 1861\r
99c048ef 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
f75a7f56
LG
1869 @param QueryName Queried Name\r
1870 @param Type Queried Type\r
1871 @param Class Queried Class\r
fcae1a99 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
f75a7f56 1903 DnsHeader = (DNS_HEADER *) Frag.Bulk;\r
5e0cdec1 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
f75a7f56 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
f75a7f56 1949\r
99c048ef 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
f75a7f56 1962 @param Packet Retransmit the packet\r
99c048ef 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
f75a7f56 1975\r
99c048ef 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
f75a7f56 2067\r
99c048ef 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
f75a7f56 2078 }\r
99c048ef 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
f75a7f56 2086\r
99c048ef 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
f75a7f56 2111\r
99c048ef 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
f75a7f56 2120 }\r
99c048ef 2121 }\r
2122 }\r
f75a7f56 2123 }\r
99c048ef 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
f75a7f56 2155\r
99c048ef 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
f75a7f56 2169\r
99c048ef 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
f75a7f56 2177\r
99c048ef 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