]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/DnsDxe/DnsProtocol.c
NetworkPkg: Support DNS4/6 GeneralLookUp feature
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsProtocol.c
CommitLineData
99c048ef 1/** @file\r
2Implementation of EFI_DNS4_PROTOCOL and EFI_DNS6_PROTOCOL interfaces.\r
3\r
4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
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
17EFI_DNS4_PROTOCOL mDns4Protocol = {\r
18 Dns4GetModeData,\r
19 Dns4Configure,\r
20 Dns4HostNameToIp,\r
21 Dns4IpToHostName,\r
22 Dns4GeneralLookUp,\r
23 Dns4UpdateDnsCache,\r
24 Dns4Poll,\r
25 Dns4Cancel\r
26};\r
27\r
28EFI_DNS6_PROTOCOL mDns6Protocol = {\r
29 Dns6GetModeData,\r
30 Dns6Configure,\r
31 Dns6HostNameToIp,\r
32 Dns6IpToHostName,\r
33 Dns6GeneralLookUp,\r
34 Dns6UpdateDnsCache,\r
35 Dns6Poll,\r
36 Dns6Cancel\r
37};\r
38\r
39/**\r
40 This function is used to retrieve DNS mode data for this DNS instance.\r
41\r
42 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
43 @param[out] DnsModeData Pointer to the caller-allocated storage for the EFI_DNS4_MODE_DATA structure.\r
44\r
45 @retval EFI_SUCCESS The operation completed successfully.\r
46 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data is \r
47 available because this instance has not been configured.\r
48 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
49 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.\r
50\r
51**/\r
52EFI_STATUS\r
53EFIAPI\r
54Dns4GetModeData (\r
55 IN EFI_DNS4_PROTOCOL *This,\r
56 OUT EFI_DNS4_MODE_DATA *DnsModeData\r
57 )\r
58{\r
59 DNS_INSTANCE *Instance;\r
60 \r
61 EFI_TPL OldTpl;\r
62\r
63 UINTN Index;\r
64 \r
65 LIST_ENTRY *Entry;\r
66 LIST_ENTRY *Next;\r
67 \r
68 DNS4_SERVER_IP *ServerItem;\r
69 EFI_IPv4_ADDRESS *ServerList;\r
70 DNS4_CACHE *CacheItem;\r
71 EFI_DNS4_CACHE_ENTRY *CacheList;\r
72 EFI_STATUS Status;\r
73\r
74 ServerItem = NULL;\r
75 ServerList = NULL;\r
76 CacheItem = NULL;\r
77 CacheList = NULL;\r
78 Status = EFI_SUCCESS;\r
79 \r
80 \r
81 if ((This == NULL) || (DnsModeData == NULL)) {\r
82 return EFI_INVALID_PARAMETER;\r
83 }\r
84\r
85 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
86 \r
87 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
88 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
89 gBS->RestoreTPL (OldTpl);\r
90 return EFI_NOT_STARTED;\r
91 }\r
92 \r
93 ZeroMem (DnsModeData, sizeof (EFI_DNS4_MODE_DATA));\r
94\r
95 //\r
96 // Get the current configuration data of this instance. \r
97 //\r
98 Status = Dns4CopyConfigure (&DnsModeData->DnsConfigData, &Instance->Dns4CfgData);\r
99 if (EFI_ERROR (Status)) {\r
100 gBS->RestoreTPL (OldTpl);\r
101 return Status;\r
102 }\r
103\r
104 //\r
105 // Get the DnsServerCount and DnsServerList\r
106 //\r
107 Index = 0;\r
108 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4ServerList) {\r
109 Index++;\r
110 }\r
111 DnsModeData->DnsServerCount = (UINT32) Index;\r
112 ServerList = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * DnsModeData->DnsServerCount);\r
113 ASSERT (ServerList != NULL);\r
114 Index = 0;\r
115 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4ServerList) {\r
116 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);\r
117 CopyMem (ServerList + Index, &ServerItem->Dns4ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
118 Index++;\r
119 }\r
120 DnsModeData->DnsServerList = ServerList;\r
121\r
122 //\r
123 // Get the DnsCacheCount and DnsCacheList\r
124 //\r
125 Index =0;\r
126 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
127 Index++;\r
128 }\r
129 DnsModeData->DnsCacheCount = (UINT32) Index;\r
130 CacheList = AllocatePool (sizeof (EFI_DNS4_CACHE_ENTRY) * DnsModeData->DnsCacheCount);\r
131 ASSERT (CacheList != NULL);\r
132 Index =0;\r
133 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
134 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
135 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS4_CACHE_ENTRY));\r
136 Index++;\r
137 }\r
138 DnsModeData->DnsCacheList = CacheList;\r
139\r
140 gBS->RestoreTPL (OldTpl);\r
141 \r
142 return EFI_SUCCESS;\r
143}\r
144\r
145/**\r
146 This function is used to configure DNS configuration data for this DNS instance.\r
147\r
148 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
149 @param[in] DnsConfigData Pointer to caller-allocated buffer containing EFI_DNS4_CONFIG_DATA structure. \r
150 If NULL, the driver will reinitialize the protocol instance to the unconfigured state.\r
151\r
152 @retval EFI_SUCCESS The operation completed successfully.\r
153 @retval EFI_UNSUPPORTED The designated protocol is not supported.\r
154 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
155 @retval EFI_INVALID_PARAMETER This is NULL.\r
156 The StationIp address provided in DnsConfigData is not a valid unicast.\r
157 DnsServerList is NULL while DnsServerListCount is not equal to Zero.\r
158 DnsServerListCount is Zero while DnsServerListCount is not equal to NULL.\r
159 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI DNSv4 Protocol instance is not configured.\r
160\r
161**/\r
162EFI_STATUS\r
163EFIAPI\r
164Dns4Configure (\r
165 IN EFI_DNS4_PROTOCOL *This,\r
166 IN EFI_DNS4_CONFIG_DATA *DnsConfigData\r
167 )\r
168{\r
169 EFI_STATUS Status;\r
170 DNS_INSTANCE *Instance;\r
171 \r
172 EFI_TPL OldTpl;\r
173 IP4_ADDR Ip;\r
174 IP4_ADDR Netmask;\r
175\r
176 UINT32 ServerListCount;\r
177 EFI_IPv4_ADDRESS *ServerList; \r
178\r
179 Status = EFI_SUCCESS;\r
180 ServerList = NULL;\r
181 \r
182 if (This == NULL || \r
183 (DnsConfigData != NULL && ((DnsConfigData->DnsServerListCount != 0 && DnsConfigData->DnsServerList == NULL) || \r
184 (DnsConfigData->DnsServerListCount == 0 && DnsConfigData->DnsServerList != NULL)))) {\r
185 return EFI_INVALID_PARAMETER;\r
186 }\r
187\r
188 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {\r
189 return EFI_UNSUPPORTED;\r
190 }\r
191\r
192 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
193\r
194 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
195\r
196 if (DnsConfigData == NULL) {\r
197 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));\r
198 \r
199 //\r
200 // Reset the Instance if ConfigData is NULL\r
201 //\r
202 if (!NetMapIsEmpty(&Instance->Dns4TxTokens)) {\r
203 Dns4InstanceCancelToken(Instance, NULL);\r
204 }\r
205\r
206 Instance->MaxRetry = 0;\r
207\r
208 if (Instance->UdpIo != NULL){\r
209 UdpIoCleanIo (Instance->UdpIo);\r
210 }\r
211 \r
212 if (Instance->Dns4CfgData.DnsServerList != NULL) {\r
213 FreePool (Instance->Dns4CfgData.DnsServerList);\r
214 }\r
215 ZeroMem (&Instance->Dns4CfgData, sizeof (EFI_DNS4_CONFIG_DATA));\r
216 \r
217 Instance->State = DNS_STATE_UNCONFIGED;\r
218 } else {\r
219 //\r
220 // Configure the parameters for new operation.\r
221 //\r
222 CopyMem (&Ip, &DnsConfigData->StationIp, sizeof (IP4_ADDR));\r
223 CopyMem (&Netmask, &DnsConfigData->SubnetMask, sizeof (IP4_ADDR));\r
224\r
225 Ip = NTOHL (Ip);\r
226 Netmask = NTOHL (Netmask);\r
227\r
228 if (!DnsConfigData->UseDefaultSetting &&\r
229 ((!IP4_IS_VALID_NETMASK (Netmask) || !NetIp4IsUnicast (Ip, Netmask)))) {\r
230 Status = EFI_INVALID_PARAMETER;\r
231 goto ON_EXIT;\r
232 }\r
233\r
234 Status = Dns4CopyConfigure (&Instance->Dns4CfgData, DnsConfigData);\r
235 if (EFI_ERROR (Status)) {\r
236 goto ON_EXIT;\r
237 }\r
238\r
239 if (DnsConfigData->DnsServerListCount == 0 || DnsConfigData->DnsServerList == NULL) {\r
240 gBS->RestoreTPL (OldTpl); \r
241 \r
242 //\r
243 // The DNS instance will retrieve DNS server from DHCP Server\r
244 //\r
245 Status = GetDns4ServerFromDhcp4 (\r
246 Instance,\r
247 &ServerListCount, \r
248 &ServerList\r
249 );\r
250 if (EFI_ERROR (Status)) {\r
251 return Status;\r
252 }\r
253\r
254 ASSERT(ServerList != NULL);\r
255 \r
256 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
257\r
258 CopyMem (&Instance->SessionDnsServer.v4, &ServerList[0], sizeof (EFI_IPv4_ADDRESS));\r
259 } else {\r
260 CopyMem (&Instance->SessionDnsServer.v4, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv4_ADDRESS));\r
261 }\r
262\r
263 //\r
264 // Config UDP\r
265 //\r
266 Status = Dns4ConfigUdp (Instance, Instance->UdpIo);\r
267 if (EFI_ERROR (Status)) {\r
268 if (Instance->Dns4CfgData.DnsServerList != NULL) {\r
269 FreePool (Instance->Dns4CfgData.DnsServerList);\r
270 }\r
271 goto ON_EXIT;\r
272 }\r
273\r
274 //\r
275 // Add configured DNS server used by this instance to ServerList.\r
276 //\r
277 Status = AddDns4ServerIp (&mDriverData->Dns4ServerList, Instance->SessionDnsServer.v4);\r
278 if (EFI_ERROR (Status)) {\r
279 if (Instance->Dns4CfgData.DnsServerList != NULL) {\r
280 FreePool (Instance->Dns4CfgData.DnsServerList);\r
281 }\r
282 goto ON_EXIT;\r
283 }\r
284 \r
285 Instance->State = DNS_STATE_CONFIGED;\r
286 }\r
287\r
288ON_EXIT:\r
289 gBS->RestoreTPL (OldTpl);\r
290 return Status;\r
291}\r
292\r
293/**\r
294 The function is used to translate the host name to host IP address. \r
295 A type A query is used to get the one or more IP addresses for this host. \r
296\r
297 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
298 @param[in] HostName Pointer to caller-supplied buffer containing Host name to be translated. \r
299 This buffer contains 16 bit characters but these are translated to ASCII for use with \r
300 DNSv4 server and there is no requirement for driver to support non-ASCII Unicode characters.\r
301 @param[in] Token Pointer to the caller-allocated completion token to return at the completion of the process to translate host name to host address. \r
302\r
303 @retval EFI_SUCCESS The operation completed successfully.\r
304 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
305 @retval EFI_INVALID_PARAMETER This is NULL.\r
306 Token is NULL.\r
307 Token.Event is.NULL\r
308 HostName is NULL\r
309 @retval EFI_NO_MAPPING There's no source address is available for use.\r
310 @retval EFI_NOT_STARTED This instance has not been started.\r
311\r
312**/\r
313EFI_STATUS\r
314EFIAPI\r
315Dns4HostNameToIp (\r
316 IN EFI_DNS4_PROTOCOL *This,\r
317 IN CHAR16 *HostName,\r
318 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
319 )\r
320{\r
321 EFI_STATUS Status;\r
322 \r
323 DNS_INSTANCE *Instance;\r
324 \r
325 EFI_DNS4_CONFIG_DATA *ConfigData;\r
326 \r
327 UINTN Index;\r
328 DNS4_CACHE *Item;\r
329 LIST_ENTRY *Entry;\r
330 LIST_ENTRY *Next;\r
331 \r
fcae1a99
JW
332 CHAR8 *QueryName;\r
333 \r
99c048ef 334 DNS4_TOKEN_ENTRY *TokenEntry;\r
335 NET_BUF *Packet;\r
336 \r
337 EFI_TPL OldTpl;\r
338 \r
339 Status = EFI_SUCCESS;\r
340 Item = NULL;\r
fcae1a99 341 QueryName = NULL;\r
99c048ef 342 TokenEntry = NULL;\r
343 Packet = NULL;\r
344 \r
345 //\r
346 // Validate the parameters\r
347 //\r
348 if ((This == NULL) || (HostName == NULL) || Token == NULL) {\r
349 return EFI_INVALID_PARAMETER;\r
350 }\r
351 \r
352 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
353 \r
354 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
355 \r
356 ConfigData = &(Instance->Dns4CfgData);\r
357 \r
358 Instance->MaxRetry = ConfigData->RetryCount;\r
359 \r
360 Token->Status = EFI_NOT_READY;\r
361 Token->RetryCount = 0;\r
362 Token->RetryInterval = ConfigData->RetryInterval;\r
363\r
364 if (Instance->State != DNS_STATE_CONFIGED) {\r
365 Status = EFI_NOT_STARTED;\r
366 goto ON_EXIT;\r
367 }\r
368\r
369 //\r
370 // Check the MaxRetry and RetryInterval values.\r
371 //\r
372 if (Instance->MaxRetry == 0) {\r
373 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
374 }\r
375\r
376 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
377 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
378 }\r
379\r
380 //\r
381 // Check cache\r
382 //\r
383 if (ConfigData->EnableDnsCache) {\r
384 Index = 0;\r
385 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
386 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
387 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
388 Index++;\r
389 }\r
390 }\r
391\r
392 if (Index != 0) {\r
393 Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
394 if (Token->RspData.H2AData == NULL) {\r
395 Status = EFI_OUT_OF_RESOURCES;\r
396 goto ON_EXIT;\r
397 }\r
398\r
399 Token->RspData.H2AData->IpCount = (UINT32)Index;\r
400 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * Index);\r
401 if (Token->RspData.H2AData->IpList == NULL) {\r
402 if (Token->RspData.H2AData != NULL) {\r
403 FreePool (Token->RspData.H2AData);\r
404 }\r
405 \r
406 Status = EFI_OUT_OF_RESOURCES;\r
407 goto ON_EXIT;\r
408 }\r
409\r
410 Index = 0;\r
411 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
412 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
413 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
414 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS));\r
415 Index++; \r
416 }\r
417 }\r
418 \r
419 Token->Status = EFI_SUCCESS;\r
420 \r
421 if (Token->Event != NULL) {\r
422 gBS->SignalEvent (Token->Event);\r
423 DispatchDpc ();\r
424 }\r
425\r
426 Status = Token->Status;\r
427 goto ON_EXIT;\r
428 } \r
429 }\r
430\r
431 //\r
432 // Construct DNS TokenEntry.\r
433 //\r
434 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));\r
435 if (TokenEntry == NULL) {\r
436 Status = EFI_OUT_OF_RESOURCES;\r
437 goto ON_EXIT;\r
438 }\r
439 \r
440 TokenEntry->PacketToLive = Token->RetryInterval;\r
441 TokenEntry->QueryHostName = HostName;\r
442 TokenEntry->Token = Token;\r
443\r
fcae1a99
JW
444 //\r
445 // Construct QName.\r
446 //\r
447 QueryName = DnsFillinQNameForQueryIp (TokenEntry->QueryHostName);\r
448 if (QueryName == NULL) {\r
449 Status = EFI_OUT_OF_RESOURCES;\r
450 goto ON_EXIT;\r
451 }\r
452 \r
99c048ef 453 //\r
454 // Construct DNS Query Packet.\r
455 //\r
fcae1a99 456 Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_A, DNS_CLASS_INET, &Packet);\r
99c048ef 457 if (EFI_ERROR (Status)) {\r
458 if (TokenEntry != NULL) {\r
459 FreePool (TokenEntry);\r
460 }\r
461 \r
462 goto ON_EXIT;\r
463 }\r
464\r
465 //\r
466 // Save the token into the Dns4TxTokens map.\r
467 //\r
468 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
469 if (EFI_ERROR (Status)) {\r
470 if (TokenEntry != NULL) {\r
471 FreePool (TokenEntry);\r
472 }\r
473 \r
474 NetbufFree (Packet);\r
475 \r
476 goto ON_EXIT;\r
477 }\r
478 \r
479 //\r
480 // Dns Query Ip\r
481 //\r
482 Status = DoDnsQuery (Instance, Packet);\r
483 if (EFI_ERROR (Status)) {\r
484 if (TokenEntry != NULL) {\r
485 FreePool (TokenEntry);\r
486 }\r
487 \r
488 NetbufFree (Packet);\r
489 }\r
490 \r
491ON_EXIT:\r
fcae1a99
JW
492 if (QueryName != NULL) {\r
493 FreePool (QueryName);\r
494 }\r
495 \r
99c048ef 496 gBS->RestoreTPL (OldTpl);\r
497 return Status;\r
498}\r
499\r
500/**\r
501 The function is used to translate the host address to host name. \r
502 A type PTR query is used to get the primary name of the host. \r
503\r
504 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
505 @param[in] IpAddress IP address.\r
506 @param[in] Token Pointer to the caller-allocated completion used token to translate host address to host name.\r
507\r
508 @retval EFI_SUCCESS The operation completed successfully.\r
509 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
510 @retval EFI_INVALID_PARAMETER This is NULL.\r
511 Token is NULL.\r
512 Token.Event is NULL.\r
513 IpAddress is not valid IP address.\r
514 @retval EFI_NO_MAPPING There's no source address is available for use.\r
515 @retval EFI_NOT_STARTED This instance has not been started.\r
516 @retval EFI_UNSUPPORTED This function is not supported.\r
517\r
518**/\r
519EFI_STATUS\r
520EFIAPI\r
521Dns4IpToHostName (\r
522 IN EFI_DNS4_PROTOCOL *This,\r
523 IN EFI_IPv4_ADDRESS IpAddress,\r
524 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
525 )\r
526{\r
527 return EFI_UNSUPPORTED;\r
528}\r
529\r
530/**\r
531 This function retrieves arbitrary information from the DNS. \r
532 The caller supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. \r
533 All RR content (e.g., Ttl) was returned. \r
534 The caller need parse the returned RR to get required information. This function is optional.\r
535\r
536 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
537 @param[in] QName Pointer to Query Name.\r
538 @param[in] QType Query Type.\r
539 @param[in] QClass Query Name.\r
540 @param[in] Token Point to the caller-allocated completion token to retrieve arbitrary information.\r
541\r
542 @retval EFI_SUCCESS The operation completed successfully.\r
543 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
544 @retval EFI_INVALID_PARAMETER This is NULL.\r
545 Token is NULL.\r
546 Token.Event is NULL.\r
547 QName is NULL.\r
548 @retval EFI_NO_MAPPING There's no source address is available for use.\r
549 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
550 @retval EFI_UNSUPPORTED This function is not supported. Or the requested QType is not supported\r
551\r
552**/\r
553EFI_STATUS\r
554EFIAPI\r
555Dns4GeneralLookUp (\r
556 IN EFI_DNS4_PROTOCOL *This,\r
557 IN CHAR8 *QName,\r
558 IN UINT16 QType, \r
559 IN UINT16 QClass,\r
560 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
561 )\r
562{\r
fcae1a99
JW
563 EFI_STATUS Status;\r
564 \r
565 DNS_INSTANCE *Instance;\r
566 \r
567 EFI_DNS4_CONFIG_DATA *ConfigData;\r
568 \r
569 DNS4_TOKEN_ENTRY *TokenEntry;\r
570 NET_BUF *Packet;\r
571 \r
572 EFI_TPL OldTpl;\r
573 \r
574 Status = EFI_SUCCESS;\r
575 TokenEntry = NULL;\r
576 Packet = NULL;\r
577 \r
578 //\r
579 // Validate the parameters\r
580 //\r
581 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
582 return EFI_INVALID_PARAMETER;\r
583 }\r
584 \r
585 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
586 \r
587 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
588 \r
589 ConfigData = &(Instance->Dns4CfgData);\r
590 \r
591 Instance->MaxRetry = ConfigData->RetryCount;\r
592 \r
593 Token->Status = EFI_NOT_READY;\r
594 Token->RetryCount = 0;\r
595 Token->RetryInterval = ConfigData->RetryInterval;\r
596\r
597 if (Instance->State != DNS_STATE_CONFIGED) {\r
598 Status = EFI_NOT_STARTED;\r
599 goto ON_EXIT;\r
600 }\r
601\r
602 //\r
603 // Check the MaxRetry and RetryInterval values.\r
604 //\r
605 if (Instance->MaxRetry == 0) {\r
606 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
607 }\r
608\r
609 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
610 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
611 }\r
612\r
613 //\r
614 // Construct DNS TokenEntry.\r
615 //\r
616 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));\r
617 if (TokenEntry == NULL) {\r
618 Status = EFI_OUT_OF_RESOURCES;\r
619 goto ON_EXIT;\r
620 }\r
621 \r
622 TokenEntry->PacketToLive = Token->RetryInterval;\r
623 TokenEntry->GeneralLookUp = TRUE;\r
624 TokenEntry->Token = Token;\r
625\r
626 //\r
627 // Construct DNS Query Packet.\r
628 //\r
629 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
630 if (EFI_ERROR (Status)) {\r
631 if (TokenEntry != NULL) {\r
632 FreePool (TokenEntry);\r
633 }\r
634 \r
635 goto ON_EXIT;\r
636 }\r
637\r
638 //\r
639 // Save the token into the Dns4TxTokens map.\r
640 //\r
641 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
642 if (EFI_ERROR (Status)) {\r
643 if (TokenEntry != NULL) {\r
644 FreePool (TokenEntry);\r
645 }\r
646 \r
647 NetbufFree (Packet);\r
648 \r
649 goto ON_EXIT;\r
650 }\r
651 \r
652 //\r
653 // Dns Query Ip\r
654 //\r
655 Status = DoDnsQuery (Instance, Packet);\r
656 if (EFI_ERROR (Status)) {\r
657 if (TokenEntry != NULL) {\r
658 FreePool (TokenEntry);\r
659 }\r
660 \r
661 NetbufFree (Packet);\r
662 }\r
663 \r
664ON_EXIT:\r
665 gBS->RestoreTPL (OldTpl);\r
666 return Status;\r
99c048ef 667}\r
668\r
669/**\r
670 This function is used to add/delete/modify DNS cache entry. \r
671 DNS cache can be normally dynamically updated after the DNS resolve succeeds. \r
672 This function provided capability to manually add/delete/modify the DNS cache.\r
673\r
674 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
675 @param[in] DeleteFlag If FALSE, this function is to add one entry to the DNS Cache. \r
676 If TRUE, this function will delete matching DNS Cache entry. \r
677 @param[in] Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
678 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
679 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
680\r
681 @retval EFI_SUCCESS The operation completed successfully.\r
682 @retval EFI_INVALID_PARAMETER This is NULL. \r
683 DnsCacheEntry.HostName is NULL.\r
684 DnsCacheEntry.IpAddress is NULL.\r
685 DnsCacheEntry.Timeout is zero.\r
686 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is not TRUE. \r
687\r
688**/\r
689EFI_STATUS\r
690EFIAPI\r
691Dns4UpdateDnsCache (\r
692 IN EFI_DNS4_PROTOCOL *This,\r
693 IN BOOLEAN DeleteFlag,\r
694 IN BOOLEAN Override,\r
695 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry\r
696 )\r
697{\r
698 EFI_STATUS Status; \r
699 EFI_TPL OldTpl;\r
700\r
701 Status = EFI_SUCCESS;\r
702 \r
703 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
704 return EFI_INVALID_PARAMETER; \r
705 }\r
706 \r
707 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
708\r
709 //\r
710 // Update Dns4Cache here.\r
711 //\r
712 Status = UpdateDns4Cache (&mDriverData->Dns4CacheList, DeleteFlag, Override, DnsCacheEntry);\r
713\r
714 gBS->RestoreTPL (OldTpl);\r
715 \r
716 return Status;\r
717}\r
718\r
719/**\r
720 This function can be used by network drivers and applications to increase the rate that data packets are moved between \r
721 the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed \r
722 network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets \r
723 without missing incoming packets or dropping outgoing packets.\r
724\r
725 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
726\r
727 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
728 @retval EFI_INVALID_PARAMETER This is NULL. \r
729 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
730 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. \r
731 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. \r
732 Consider increasing the polling rate.\r
733 \r
734**/\r
735EFI_STATUS\r
736EFIAPI\r
737Dns4Poll (\r
738 IN EFI_DNS4_PROTOCOL *This\r
739 )\r
740{\r
741 DNS_INSTANCE *Instance;\r
742 EFI_UDP4_PROTOCOL *Udp;\r
743\r
744 if (This == NULL) {\r
745 return EFI_INVALID_PARAMETER;\r
746 }\r
747\r
748 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
749\r
750 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
751 return EFI_NOT_STARTED;\r
752 } else if (Instance->State == DNS_STATE_DESTROY) {\r
753 return EFI_DEVICE_ERROR;\r
754 }\r
755\r
756 Udp = Instance->UdpIo->Protocol.Udp4;\r
757 \r
758 return Udp->Poll (Udp);\r
759}\r
760\r
761/**\r
762 This function is used to abort a pending resolution request. \r
763 After calling this function, Token.Status will be set to EFI_ABORTED and then Token.\r
764\r
765 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
766 @param[in] Token Pointer to a token that has been issued by EFI_DNS4_PROTOCOL.HostNameToIp(), \r
767 EFI_DNS4_PROTOCOL.IpToHostName() or EFI_DNS4_PROTOCOL.GeneralLookup(). \r
768 If NULL, all pending tokens are aborted.\r
769\r
770 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
771 @retval EFI_INVALID_PARAMETER This is NULL. \r
772 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
773 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS operation was not found in the transmit queue. \r
774 It was either completed or was not issued by HostNameToIp(), IpToHostName() or GeneralLookup().\r
775 \r
776**/\r
777EFI_STATUS\r
778EFIAPI\r
779Dns4Cancel (\r
780 IN EFI_DNS4_PROTOCOL *This,\r
781 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
782 )\r
783{\r
784 EFI_STATUS Status;\r
785 DNS_INSTANCE *Instance;\r
786 EFI_TPL OldTpl;\r
787\r
788 if (This == NULL) {\r
789 return EFI_INVALID_PARAMETER;\r
790 }\r
791\r
792 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
793\r
794 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
795 return EFI_NOT_STARTED;\r
796 }\r
797\r
798 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
799\r
800 //\r
801 // Cancle the tokens specified by Token for this instance.\r
802 //\r
803 Status = Dns4InstanceCancelToken (Instance, Token);\r
804\r
805 //\r
806 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
807 //\r
808 DispatchDpc ();\r
809\r
810 gBS->RestoreTPL (OldTpl);\r
811\r
812 return Status;\r
813}\r
814\r
815/**\r
816 This function is used to retrieve DNS mode data for this DNS instance.\r
817\r
818 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
819 @param[out] DnsModeData Pointer to the caller-allocated storage for the EFI_DNS6_MODE_DATA structure.\r
820\r
821 @retval EFI_SUCCESS The operation completed successfully.\r
822 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data is \r
823 available because this instance has not been configured.\r
824 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
825 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.\r
826\r
827**/\r
828EFI_STATUS\r
829EFIAPI\r
830Dns6GetModeData (\r
831 IN EFI_DNS6_PROTOCOL *This,\r
832 OUT EFI_DNS6_MODE_DATA *DnsModeData\r
833 )\r
834{\r
835 DNS_INSTANCE *Instance;\r
836 \r
837 EFI_TPL OldTpl;\r
838\r
839 UINTN Index;\r
840 \r
841 LIST_ENTRY *Entry;\r
842 LIST_ENTRY *Next;\r
843\r
844 DNS6_SERVER_IP *ServerItem;\r
845 EFI_IPv6_ADDRESS *ServerList;\r
846 DNS6_CACHE *CacheItem;\r
847 EFI_DNS6_CACHE_ENTRY *CacheList;\r
848 EFI_STATUS Status;\r
849\r
850 ServerItem = NULL;\r
851 ServerList = NULL;\r
852 CacheItem = NULL;\r
853 CacheList = NULL;\r
854 Status = EFI_SUCCESS;\r
855\r
856 if ((This == NULL) || (DnsModeData == NULL)) {\r
857 return EFI_INVALID_PARAMETER;\r
858 }\r
859\r
860 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
861 \r
862 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
863 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
864 gBS->RestoreTPL (OldTpl);\r
865 return EFI_NOT_STARTED;\r
866 }\r
867\r
868 ZeroMem (DnsModeData, sizeof (EFI_DNS6_MODE_DATA));\r
869\r
870 //\r
871 // Get the current configuration data of this instance. \r
872 //\r
873 Status = Dns6CopyConfigure(&DnsModeData->DnsConfigData, &Instance->Dns6CfgData);\r
874 if (EFI_ERROR (Status)) {\r
875 gBS->RestoreTPL (OldTpl);\r
876 return Status;\r
877 }\r
878 \r
879 //\r
880 // Get the DnsServerCount and DnsServerList\r
881 //\r
882 Index = 0;\r
883 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
884 Index++;\r
885 }\r
886 DnsModeData->DnsServerCount = (UINT32) Index;\r
887 ServerList = AllocatePool (sizeof(EFI_IPv6_ADDRESS) * DnsModeData->DnsServerCount);\r
888 ASSERT (ServerList != NULL);\r
889 Index = 0;\r
890 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
891 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);\r
892 CopyMem (ServerList + Index, &ServerItem->Dns6ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
893 Index++;\r
894 }\r
895 DnsModeData->DnsServerList = ServerList;\r
896\r
897 //\r
898 // Get the DnsCacheCount and DnsCacheList\r
899 //\r
900 Index =0;\r
901 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
902 Index++;\r
903 }\r
904 DnsModeData->DnsCacheCount = (UINT32) Index;\r
905 CacheList = AllocatePool (sizeof(EFI_DNS6_CACHE_ENTRY) * DnsModeData->DnsCacheCount);\r
906 ASSERT (CacheList != NULL);\r
907 Index =0;\r
908 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
909 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
910 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS6_CACHE_ENTRY));\r
911 Index++;\r
912 }\r
913 DnsModeData->DnsCacheList = CacheList;\r
914\r
915 gBS->RestoreTPL (OldTpl);\r
916 \r
917 return EFI_SUCCESS;\r
918}\r
919\r
920/**\r
921 The function is used to set and change the configuration data for this EFI DNSv6 Protocol driver instance. \r
922 Reset the DNS instance if DnsConfigData is NULL.\r
923\r
924 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
925 @param[in] DnsConfigData Pointer to the configuration data structure. \r
926 All associated storage to be allocated and released by caller.\r
927\r
928 @retval EFI_SUCCESS The operation completed successfully.\r
929 @retval EFI_UNSUPPORTED The designated protocol is not supported.\r
930 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
931 @retval EFI_INVALID_PARAMETER This is NULL.\r
932 The StationIp address provided in DnsConfigData is not a valid unicast.\r
933 DnsServerList is NULL while DnsServerListCount is not equal to Zero.\r
934 DnsServerListCount is Zero while DnsServerList is not equal to NULL.\r
935 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI DNSv6 Protocol instance is not configured.\r
936\r
937**/\r
938EFI_STATUS\r
939EFIAPI\r
940Dns6Configure (\r
941 IN EFI_DNS6_PROTOCOL *This,\r
942 IN EFI_DNS6_CONFIG_DATA *DnsConfigData\r
943 )\r
944{\r
945 EFI_STATUS Status;\r
946 DNS_INSTANCE *Instance;\r
947 \r
948 EFI_TPL OldTpl;\r
949\r
950 UINT32 ServerListCount;\r
951 EFI_IPv6_ADDRESS *ServerList; \r
952\r
953 Status = EFI_SUCCESS;\r
954 ServerList = NULL;\r
955\r
956 if (This == NULL || \r
957 (DnsConfigData != NULL && ((DnsConfigData->DnsServerCount != 0 && DnsConfigData->DnsServerList == NULL) || \r
958 (DnsConfigData->DnsServerCount == 0 && DnsConfigData->DnsServerList != NULL)))) {\r
959 return EFI_INVALID_PARAMETER;\r
960 }\r
961\r
962 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {\r
963 return EFI_UNSUPPORTED;\r
964 }\r
965\r
966 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
967\r
968 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
969\r
970 if (DnsConfigData == NULL) {\r
971 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));\r
972\r
973 //\r
974 // Reset the Instance if ConfigData is NULL\r
975 //\r
976 if (!NetMapIsEmpty(&Instance->Dns6TxTokens)) {\r
977 Dns6InstanceCancelToken(Instance, NULL);\r
978 }\r
979\r
980 Instance->MaxRetry = 0;\r
981\r
982 if (Instance->UdpIo != NULL){\r
983 UdpIoCleanIo (Instance->UdpIo);\r
984 }\r
985\r
986 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
987 FreePool (Instance->Dns6CfgData.DnsServerList);\r
988 }\r
989 ZeroMem (&Instance->Dns6CfgData, sizeof (EFI_DNS6_CONFIG_DATA));\r
990 \r
991 Instance->State = DNS_STATE_UNCONFIGED;\r
992 } else {\r
993 //\r
994 // Configure the parameters for new operation.\r
995 //\r
90ae1f02 996 if (!NetIp6IsUnspecifiedAddr (&DnsConfigData->StationIp) && !NetIp6IsValidUnicast (&DnsConfigData->StationIp)) {\r
99c048ef 997 Status = EFI_INVALID_PARAMETER;\r
998 goto ON_EXIT;\r
999 }\r
1000\r
1001 Status = Dns6CopyConfigure (&Instance->Dns6CfgData, DnsConfigData);\r
1002 if (EFI_ERROR (Status)) {\r
1003 goto ON_EXIT;\r
1004 }\r
1005\r
1006 if (DnsConfigData->DnsServerCount == 0 || DnsConfigData->DnsServerList == NULL) {\r
1007 gBS->RestoreTPL (OldTpl);\r
1008\r
1009 //\r
1010 //The DNS instance will retrieve DNS server from DHCP Server.\r
1011 //\r
1012 Status = GetDns6ServerFromDhcp6 (\r
1013 Instance->Service->ImageHandle,\r
1014 Instance->Service->ControllerHandle, \r
1015 &ServerListCount, \r
1016 &ServerList\r
1017 );\r
1018 if (EFI_ERROR (Status)) {\r
1019 goto ON_EXIT;\r
1020 }\r
1021 \r
1022 ASSERT(ServerList != NULL);\r
1023\r
1024 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1025\r
1026 CopyMem (&Instance->SessionDnsServer.v6, &ServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1027 } else {\r
1028 CopyMem (&Instance->SessionDnsServer.v6, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1029 }\r
1030\r
1031 //\r
1032 // Config UDP\r
1033 //\r
1034 Status = Dns6ConfigUdp (Instance, Instance->UdpIo);\r
1035 if (EFI_ERROR (Status)) {\r
1036 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1037 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1038 }\r
1039 goto ON_EXIT;\r
1040 }\r
1041\r
1042 //\r
1043 // Add configured DNS server used by this instance to ServerList.\r
1044 //\r
1045 Status = AddDns6ServerIp (&mDriverData->Dns6ServerList, Instance->SessionDnsServer.v6);\r
1046 if (EFI_ERROR (Status)) {\r
1047 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1048 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1049 }\r
1050 goto ON_EXIT;\r
1051 }\r
1052 \r
1053 Instance->State = DNS_STATE_CONFIGED;\r
1054 }\r
1055\r
1056ON_EXIT:\r
1057 gBS->RestoreTPL (OldTpl);\r
1058 return Status;\r
1059}\r
1060\r
1061/**\r
1062 The function is used to translate the host name to host IP address. \r
1063 A type AAAA query is used to get the one or more IPv6 addresses for this host. \r
1064\r
1065 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1066 @param[in] HostName Pointer to caller-supplied buffer containing Host name to be translated. \r
1067 This buffer contains 16 bit characters but these are translated to ASCII for use with \r
1068 DNSv4 server and there is no requirement for driver to support non-ASCII Unicode characters.\r
1069 @param[in] Token Pointer to the caller-allocated completion token to return at the completion of the process to translate host name to host address. \r
1070\r
1071 @retval EFI_SUCCESS The operation completed successfully.\r
1072 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
1073 @retval EFI_INVALID_PARAMETER This is NULL.\r
1074 Token is NULL.\r
1075 Token.Event is.NULL\r
1076 HostName is NULL\r
1077 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1078 @retval EFI_NOT_STARTED This instance has not been started.\r
1079\r
1080**/\r
1081EFI_STATUS\r
1082EFIAPI\r
1083Dns6HostNameToIp (\r
1084 IN EFI_DNS6_PROTOCOL *This,\r
1085 IN CHAR16 *HostName,\r
1086 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1087 )\r
1088{\r
1089 EFI_STATUS Status;\r
1090 \r
1091 DNS_INSTANCE *Instance;\r
1092\r
1093 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1094 \r
1095 UINTN Index; \r
1096 DNS6_CACHE *Item;\r
1097 LIST_ENTRY *Entry;\r
1098 LIST_ENTRY *Next;\r
1099 \r
fcae1a99
JW
1100 CHAR8 *QueryName;\r
1101 \r
99c048ef 1102 DNS6_TOKEN_ENTRY *TokenEntry;\r
1103 NET_BUF *Packet;\r
1104 \r
1105 EFI_TPL OldTpl;\r
1106 \r
1107 Status = EFI_SUCCESS;\r
1108 Item = NULL;\r
fcae1a99 1109 QueryName = NULL;\r
99c048ef 1110 TokenEntry = NULL;\r
1111 Packet = NULL;\r
1112\r
1113 //\r
1114 // Validate the parameters\r
1115 //\r
1116 if ((This == NULL) || (HostName == NULL) || Token == NULL) {\r
1117 return EFI_INVALID_PARAMETER;\r
1118 }\r
1119\r
1120 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1121 \r
1122 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1123 \r
1124 ConfigData = &(Instance->Dns6CfgData);\r
1125 \r
1126 Instance->MaxRetry = ConfigData->RetryCount;\r
1127\r
1128 Token->Status = EFI_NOT_READY;\r
1129 Token->RetryCount = 0;\r
1130 Token->RetryInterval = ConfigData->RetryInterval;\r
1131\r
1132 if (Instance->State != DNS_STATE_CONFIGED) {\r
1133 Status = EFI_NOT_STARTED;\r
1134 goto ON_EXIT;\r
1135 }\r
1136\r
1137 //\r
1138 // Check the MaxRetry and RetryInterval values.\r
1139 //\r
1140 if (Instance->MaxRetry == 0) {\r
1141 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1142 }\r
1143\r
1144 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1145 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1146 } \r
1147\r
1148 //\r
1149 // Check cache\r
1150 //\r
1151 if (ConfigData->EnableDnsCache) {\r
1152 Index = 0;\r
1153 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1154 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1155 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1156 Index++;\r
1157 }\r
1158 }\r
1159\r
1160 if (Index != 0) {\r
1161 Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
1162 if (Token->RspData.H2AData == NULL) {\r
1163 Status = EFI_OUT_OF_RESOURCES;\r
1164 goto ON_EXIT;\r
1165 }\r
1166\r
1167 Token->RspData.H2AData->IpCount = (UINT32)Index;\r
1168 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * Index);\r
1169 if (Token->RspData.H2AData->IpList == NULL) {\r
1170 if (Token->RspData.H2AData != NULL) {\r
1171 FreePool (Token->RspData.H2AData);\r
1172 }\r
1173 \r
1174 Status = EFI_OUT_OF_RESOURCES;\r
1175 goto ON_EXIT;\r
1176 }\r
1177\r
1178 Index = 0;\r
1179 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1180 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1181 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1182 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
1183 Index++;\r
1184 }\r
1185 }\r
1186 \r
1187 Token->Status = EFI_SUCCESS;\r
1188 \r
1189 if (Token->Event != NULL) {\r
1190 gBS->SignalEvent (Token->Event);\r
1191 DispatchDpc ();\r
1192 }\r
1193 \r
1194 Status = Token->Status;\r
1195 goto ON_EXIT;\r
1196 } \r
1197 }\r
1198\r
1199 //\r
1200 // Construct DNS TokenEntry.\r
1201 //\r
1202 TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));\r
1203 if (TokenEntry == NULL) {\r
1204 Status = EFI_OUT_OF_RESOURCES;\r
1205 goto ON_EXIT;\r
1206 }\r
1207 \r
1208 TokenEntry->PacketToLive = Token->RetryInterval;\r
1209 TokenEntry->QueryHostName = HostName;\r
1210 TokenEntry->Token = Token;\r
1211\r
fcae1a99
JW
1212\r
1213 //\r
1214 // Construct QName.\r
1215 //\r
1216 QueryName = DnsFillinQNameForQueryIp (TokenEntry->QueryHostName);\r
1217 if (QueryName == NULL) {\r
1218 Status = EFI_OUT_OF_RESOURCES;\r
1219 goto ON_EXIT;\r
1220 }\r
1221 \r
99c048ef 1222 //\r
1223 // Construct DNS Query Packet.\r
1224 //\r
fcae1a99 1225 Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_AAAA, DNS_CLASS_INET, &Packet);\r
99c048ef 1226 if (EFI_ERROR (Status)) {\r
1227 if (TokenEntry != NULL) {\r
1228 FreePool (TokenEntry);\r
1229 }\r
1230 \r
1231 goto ON_EXIT;\r
1232 }\r
1233\r
1234 //\r
1235 // Save the token into the Dns6TxTokens map.\r
1236 //\r
1237 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1238 if (EFI_ERROR (Status)) {\r
1239 if (TokenEntry != NULL) {\r
1240 FreePool (TokenEntry);\r
1241 }\r
1242 \r
1243 NetbufFree (Packet);\r
1244 \r
1245 goto ON_EXIT;\r
1246 }\r
1247 \r
1248 //\r
1249 // Dns Query Ip\r
1250 //\r
1251 Status = DoDnsQuery (Instance, Packet);\r
1252 if (EFI_ERROR (Status)) {\r
1253 if (TokenEntry != NULL) {\r
1254 FreePool (TokenEntry);\r
1255 }\r
1256 \r
1257 NetbufFree (Packet);\r
1258 }\r
1259 \r
1260ON_EXIT:\r
fcae1a99
JW
1261 if (QueryName != NULL) {\r
1262 FreePool (QueryName);\r
1263 }\r
1264 \r
99c048ef 1265 gBS->RestoreTPL (OldTpl);\r
1266 return Status;\r
1267}\r
1268\r
1269/**\r
1270 The function is used to translate the host address to host name. \r
1271 A type PTR query is used to get the primary name of the host. \r
1272\r
1273 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1274 @param[in] IpAddress IP address.\r
1275 @param[in] Token Pointer to the caller-allocated completion used token to translate host address to host name.\r
1276\r
1277 @retval EFI_SUCCESS The operation completed successfully.\r
1278 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
1279 @retval EFI_INVALID_PARAMETER This is NULL.\r
1280 Token is NULL.\r
1281 Token.Event is NULL.\r
1282 IpAddress is not valid IP address.\r
1283 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1284 @retval EFI_NOT_STARTED This instance has not been started.\r
1285 @retval EFI_UNSUPPORTED This function is not supported.\r
1286\r
1287**/\r
1288EFI_STATUS\r
1289EFIAPI\r
1290Dns6IpToHostName (\r
1291 IN EFI_DNS6_PROTOCOL *This,\r
1292 IN EFI_IPv6_ADDRESS IpAddress,\r
1293 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1294 )\r
1295{\r
1296 return EFI_UNSUPPORTED;\r
1297}\r
1298\r
1299/**\r
1300 This function retrieves arbitrary information from the DNS. \r
1301 The caller supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. \r
1302 All RR content (e.g., Ttl) was returned. \r
1303 The caller need parse the returned RR to get required information. This function is optional.\r
1304\r
1305 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1306 @param[in] QName Pointer to Query Name.\r
1307 @param[in] QType Query Type.\r
1308 @param[in] QClass Query Name.\r
1309 @param[in] Token Point to the caller-allocated completion token to retrieve arbitrary information.\r
1310\r
1311 @retval EFI_SUCCESS The operation completed successfully.\r
1312 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
1313 @retval EFI_INVALID_PARAMETER This is NULL.\r
1314 Token is NULL.\r
1315 Token.Event is NULL.\r
1316 QName is NULL.\r
1317 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1318 @retval EFI_NOT_STARTED This instance has not been started.\r
1319 @retval EFI_UNSUPPORTED This function is not supported. Or the requested QType is not supported\r
1320\r
1321**/\r
1322EFI_STATUS\r
1323EFIAPI\r
1324Dns6GeneralLookUp (\r
1325 IN EFI_DNS6_PROTOCOL *This,\r
1326 IN CHAR8 *QName,\r
1327 IN UINT16 QType, \r
1328 IN UINT16 QClass,\r
1329 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1330 )\r
1331{\r
fcae1a99
JW
1332 EFI_STATUS Status;\r
1333 \r
1334 DNS_INSTANCE *Instance;\r
1335 \r
1336 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1337 \r
1338 DNS6_TOKEN_ENTRY *TokenEntry;\r
1339 NET_BUF *Packet;\r
1340 \r
1341 EFI_TPL OldTpl;\r
1342 \r
1343 Status = EFI_SUCCESS;\r
1344 TokenEntry = NULL;\r
1345 Packet = NULL;\r
1346 \r
1347 //\r
1348 // Validate the parameters\r
1349 //\r
1350 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
1351 return EFI_INVALID_PARAMETER;\r
1352 }\r
1353 \r
1354 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1355 \r
1356 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1357 \r
1358 ConfigData = &(Instance->Dns6CfgData);\r
1359 \r
1360 Instance->MaxRetry = ConfigData->RetryCount;\r
1361 \r
1362 Token->Status = EFI_NOT_READY;\r
1363 Token->RetryCount = 0;\r
1364 Token->RetryInterval = ConfigData->RetryInterval;\r
1365\r
1366 if (Instance->State != DNS_STATE_CONFIGED) {\r
1367 Status = EFI_NOT_STARTED;\r
1368 goto ON_EXIT;\r
1369 }\r
1370\r
1371 //\r
1372 // Check the MaxRetry and RetryInterval values.\r
1373 //\r
1374 if (Instance->MaxRetry == 0) {\r
1375 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1376 }\r
1377\r
1378 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1379 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1380 }\r
1381\r
1382 //\r
1383 // Construct DNS TokenEntry.\r
1384 //\r
1385 TokenEntry = AllocateZeroPool (sizeof(DNS6_TOKEN_ENTRY));\r
1386 if (TokenEntry == NULL) {\r
1387 Status = EFI_OUT_OF_RESOURCES;\r
1388 goto ON_EXIT;\r
1389 }\r
1390 \r
1391 TokenEntry->PacketToLive = Token->RetryInterval;\r
1392 TokenEntry->GeneralLookUp = TRUE;\r
1393 TokenEntry->Token = Token;\r
1394\r
1395 //\r
1396 // Construct DNS Query Packet.\r
1397 //\r
1398 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
1399 if (EFI_ERROR (Status)) {\r
1400 if (TokenEntry != NULL) {\r
1401 FreePool (TokenEntry);\r
1402 }\r
1403 \r
1404 goto ON_EXIT;\r
1405 }\r
1406\r
1407 //\r
1408 // Save the token into the Dns6TxTokens map.\r
1409 //\r
1410 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1411 if (EFI_ERROR (Status)) {\r
1412 if (TokenEntry != NULL) {\r
1413 FreePool (TokenEntry);\r
1414 }\r
1415 \r
1416 NetbufFree (Packet);\r
1417 \r
1418 goto ON_EXIT;\r
1419 }\r
1420 \r
1421 //\r
1422 // Dns Query Ip\r
1423 //\r
1424 Status = DoDnsQuery (Instance, Packet);\r
1425 if (EFI_ERROR (Status)) {\r
1426 if (TokenEntry != NULL) {\r
1427 FreePool (TokenEntry);\r
1428 }\r
1429 \r
1430 NetbufFree (Packet);\r
1431 }\r
1432 \r
1433ON_EXIT:\r
1434 gBS->RestoreTPL (OldTpl);\r
1435 return Status;\r
99c048ef 1436}\r
1437\r
1438/**\r
1439 This function is used to add/delete/modify DNS cache entry. \r
1440 DNS cache can be normally dynamically updated after the DNS resolve succeeds. \r
1441 This function provided capability to manually add/delete/modify the DNS cache.\r
1442\r
1443 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1444 @param[in] DeleteFlag If FALSE, this function is to add one entry to the DNS Cache. \r
1445 If TRUE, this function will delete matching DNS Cache entry. \r
1446 @param[in] Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
1447 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
1448 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
1449\r
1450 @retval EFI_SUCCESS The operation completed successfully.\r
1451 @retval EFI_INVALID_PARAMETER This is NULL. \r
1452 DnsCacheEntry.HostName is NULL.\r
1453 DnsCacheEntry.IpAddress is NULL.\r
1454 DnsCacheEntry.Timeout is zero.\r
1455 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is not TRUE. \r
1456\r
1457**/\r
1458EFI_STATUS\r
1459EFIAPI\r
1460Dns6UpdateDnsCache (\r
1461 IN EFI_DNS6_PROTOCOL *This,\r
1462 IN BOOLEAN DeleteFlag,\r
1463 IN BOOLEAN Override,\r
1464 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry\r
1465 )\r
1466{\r
1467 EFI_STATUS Status; \r
1468 EFI_TPL OldTpl;\r
1469\r
1470 Status = EFI_SUCCESS;\r
1471 \r
1472 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
1473 return EFI_INVALID_PARAMETER; \r
1474 }\r
1475 \r
1476 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1477\r
1478 //\r
1479 // Update Dns6Cache here.\r
1480 //\r
1481 Status = UpdateDns6Cache (&mDriverData->Dns6CacheList, DeleteFlag, Override, DnsCacheEntry);\r
1482 \r
1483 gBS->RestoreTPL (OldTpl);\r
1484 \r
1485 return Status;\r
1486}\r
1487\r
1488/**\r
1489 This function can be used by network drivers and applications to increase the rate that data packets are moved between \r
1490 the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed \r
1491 network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets \r
1492 without missing incoming packets or dropping outgoing packets.\r
1493\r
1494 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1495\r
1496 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1497 @retval EFI_INVALID_PARAMETER This is NULL. \r
1498 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
1499 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. \r
1500 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. \r
1501 Consider increasing the polling rate.\r
1502 \r
1503**/\r
1504EFI_STATUS\r
1505EFIAPI\r
1506Dns6Poll (\r
1507 IN EFI_DNS6_PROTOCOL *This\r
1508 )\r
1509{\r
1510 DNS_INSTANCE *Instance;\r
1511 EFI_UDP6_PROTOCOL *Udp;\r
1512\r
1513 if (This == NULL) {\r
1514 return EFI_INVALID_PARAMETER;\r
1515 }\r
1516\r
1517 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1518\r
1519 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1520 return EFI_NOT_STARTED;\r
1521 } else if (Instance->State == DNS_STATE_DESTROY) {\r
1522 return EFI_DEVICE_ERROR;\r
1523 }\r
1524\r
1525 Udp = Instance->UdpIo->Protocol.Udp6;\r
1526 \r
1527 return Udp->Poll (Udp);\r
1528}\r
1529\r
1530/**\r
1531 This function is used to abort a pending resolution request. \r
1532 After calling this function, Token.Status will be set to EFI_ABORTED and then Token.\r
1533\r
1534 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1535 @param[in] Token Pointer to a token that has been issued by EFI_DNS6_PROTOCOL.HostNameToIp(), \r
1536 EFI_DNS6_PROTOCOL.IpToHostName() or EFI_DNS6_PROTOCOL.GeneralLookup(). \r
1537 If NULL, all pending tokens are aborted.\r
1538\r
1539 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1540 @retval EFI_INVALID_PARAMETER This is NULL. \r
1541 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
1542 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS operation was not found in the transmit queue. \r
1543 It was either completed or was not issued by HostNameToIp(), IpToHostName() or GeneralLookup().\r
1544 \r
1545**/\r
1546EFI_STATUS\r
1547EFIAPI\r
1548Dns6Cancel (\r
1549 IN EFI_DNS6_PROTOCOL *This,\r
1550 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1551 )\r
1552{\r
1553 EFI_STATUS Status;\r
1554 DNS_INSTANCE *Instance;\r
1555 EFI_TPL OldTpl;\r
1556\r
1557 if (This == NULL) {\r
1558 return EFI_INVALID_PARAMETER;\r
1559 }\r
1560\r
1561 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1562\r
1563 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1564 return EFI_NOT_STARTED;\r
1565 }\r
1566\r
1567 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1568\r
1569 //\r
1570 // Cancle the tokens specified by Token for this instance.\r
1571 //\r
1572 Status = Dns6InstanceCancelToken (Instance, Token);\r
1573\r
1574 //\r
1575 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
1576 //\r
1577 DispatchDpc ();\r
1578\r
1579 gBS->RestoreTPL (OldTpl);\r
1580\r
1581 return Status;\r
1582}\r
1583\r