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