]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/DnsDxe/DnsProtocol.c
NetworkPkg: Removing or adding some ASSERT statement
[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
8339166d
JW
465 ASSERT (Packet != NULL);\r
466\r
99c048ef 467 //\r
468 // Save the token into the Dns4TxTokens map.\r
469 //\r
470 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
471 if (EFI_ERROR (Status)) {\r
472 if (TokenEntry != NULL) {\r
473 FreePool (TokenEntry);\r
474 }\r
475 \r
476 NetbufFree (Packet);\r
477 \r
478 goto ON_EXIT;\r
479 }\r
480 \r
481 //\r
482 // Dns Query Ip\r
483 //\r
484 Status = DoDnsQuery (Instance, Packet);\r
485 if (EFI_ERROR (Status)) {\r
486 if (TokenEntry != NULL) {\r
487 FreePool (TokenEntry);\r
488 }\r
489 \r
490 NetbufFree (Packet);\r
491 }\r
492 \r
493ON_EXIT:\r
fcae1a99
JW
494 if (QueryName != NULL) {\r
495 FreePool (QueryName);\r
496 }\r
497 \r
99c048ef 498 gBS->RestoreTPL (OldTpl);\r
499 return Status;\r
500}\r
501\r
502/**\r
503 The function is used to translate the host address to host name. \r
504 A type PTR query is used to get the primary name of the host. \r
505\r
506 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
507 @param[in] IpAddress IP address.\r
508 @param[in] Token Pointer to the caller-allocated completion used token to translate host address to host name.\r
509\r
510 @retval EFI_SUCCESS The operation completed successfully.\r
511 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
512 @retval EFI_INVALID_PARAMETER This is NULL.\r
513 Token is NULL.\r
514 Token.Event is NULL.\r
515 IpAddress is not valid IP address.\r
516 @retval EFI_NO_MAPPING There's no source address is available for use.\r
517 @retval EFI_NOT_STARTED This instance has not been started.\r
518 @retval EFI_UNSUPPORTED This function is not supported.\r
519\r
520**/\r
521EFI_STATUS\r
522EFIAPI\r
523Dns4IpToHostName (\r
524 IN EFI_DNS4_PROTOCOL *This,\r
525 IN EFI_IPv4_ADDRESS IpAddress,\r
526 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
527 )\r
528{\r
529 return EFI_UNSUPPORTED;\r
530}\r
531\r
532/**\r
533 This function retrieves arbitrary information from the DNS. \r
534 The caller supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. \r
535 All RR content (e.g., Ttl) was returned. \r
536 The caller need parse the returned RR to get required information. This function is optional.\r
537\r
538 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
539 @param[in] QName Pointer to Query Name.\r
540 @param[in] QType Query Type.\r
541 @param[in] QClass Query Name.\r
542 @param[in] Token Point to the caller-allocated completion token to retrieve arbitrary information.\r
543\r
544 @retval EFI_SUCCESS The operation completed successfully.\r
545 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
546 @retval EFI_INVALID_PARAMETER This is NULL.\r
547 Token is NULL.\r
548 Token.Event is NULL.\r
549 QName is NULL.\r
550 @retval EFI_NO_MAPPING There's no source address is available for use.\r
551 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
552 @retval EFI_UNSUPPORTED This function is not supported. Or the requested QType is not supported\r
553\r
554**/\r
555EFI_STATUS\r
556EFIAPI\r
557Dns4GeneralLookUp (\r
558 IN EFI_DNS4_PROTOCOL *This,\r
559 IN CHAR8 *QName,\r
560 IN UINT16 QType, \r
561 IN UINT16 QClass,\r
562 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
563 )\r
564{\r
fcae1a99
JW
565 EFI_STATUS Status;\r
566 \r
567 DNS_INSTANCE *Instance;\r
568 \r
569 EFI_DNS4_CONFIG_DATA *ConfigData;\r
570 \r
571 DNS4_TOKEN_ENTRY *TokenEntry;\r
572 NET_BUF *Packet;\r
573 \r
574 EFI_TPL OldTpl;\r
575 \r
576 Status = EFI_SUCCESS;\r
577 TokenEntry = NULL;\r
578 Packet = NULL;\r
579 \r
580 //\r
581 // Validate the parameters\r
582 //\r
583 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
584 return EFI_INVALID_PARAMETER;\r
585 }\r
586 \r
587 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
588 \r
589 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
590 \r
591 ConfigData = &(Instance->Dns4CfgData);\r
592 \r
593 Instance->MaxRetry = ConfigData->RetryCount;\r
594 \r
595 Token->Status = EFI_NOT_READY;\r
596 Token->RetryCount = 0;\r
597 Token->RetryInterval = ConfigData->RetryInterval;\r
598\r
599 if (Instance->State != DNS_STATE_CONFIGED) {\r
600 Status = EFI_NOT_STARTED;\r
601 goto ON_EXIT;\r
602 }\r
603\r
604 //\r
605 // Check the MaxRetry and RetryInterval values.\r
606 //\r
607 if (Instance->MaxRetry == 0) {\r
608 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
609 }\r
610\r
611 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
612 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
613 }\r
614\r
615 //\r
616 // Construct DNS TokenEntry.\r
617 //\r
618 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));\r
619 if (TokenEntry == NULL) {\r
620 Status = EFI_OUT_OF_RESOURCES;\r
621 goto ON_EXIT;\r
622 }\r
623 \r
624 TokenEntry->PacketToLive = Token->RetryInterval;\r
625 TokenEntry->GeneralLookUp = TRUE;\r
626 TokenEntry->Token = Token;\r
627\r
628 //\r
629 // Construct DNS Query Packet.\r
630 //\r
631 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
632 if (EFI_ERROR (Status)) {\r
633 if (TokenEntry != NULL) {\r
634 FreePool (TokenEntry);\r
635 }\r
636 \r
637 goto ON_EXIT;\r
638 }\r
639\r
8339166d
JW
640 ASSERT (Packet != NULL);\r
641\r
fcae1a99
JW
642 //\r
643 // Save the token into the Dns4TxTokens map.\r
644 //\r
645 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
646 if (EFI_ERROR (Status)) {\r
647 if (TokenEntry != NULL) {\r
648 FreePool (TokenEntry);\r
649 }\r
650 \r
651 NetbufFree (Packet);\r
652 \r
653 goto ON_EXIT;\r
654 }\r
655 \r
656 //\r
657 // Dns Query Ip\r
658 //\r
659 Status = DoDnsQuery (Instance, Packet);\r
660 if (EFI_ERROR (Status)) {\r
661 if (TokenEntry != NULL) {\r
662 FreePool (TokenEntry);\r
663 }\r
664 \r
665 NetbufFree (Packet);\r
666 }\r
667 \r
668ON_EXIT:\r
669 gBS->RestoreTPL (OldTpl);\r
670 return Status;\r
99c048ef 671}\r
672\r
673/**\r
674 This function is used to add/delete/modify DNS cache entry. \r
675 DNS cache can be normally dynamically updated after the DNS resolve succeeds. \r
676 This function provided capability to manually add/delete/modify the DNS cache.\r
677\r
678 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
679 @param[in] DeleteFlag If FALSE, this function is to add one entry to the DNS Cache. \r
680 If TRUE, this function will delete matching DNS Cache entry. \r
681 @param[in] Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
682 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
683 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
684\r
685 @retval EFI_SUCCESS The operation completed successfully.\r
686 @retval EFI_INVALID_PARAMETER This is NULL. \r
687 DnsCacheEntry.HostName is NULL.\r
688 DnsCacheEntry.IpAddress is NULL.\r
689 DnsCacheEntry.Timeout is zero.\r
690 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is not TRUE. \r
691\r
692**/\r
693EFI_STATUS\r
694EFIAPI\r
695Dns4UpdateDnsCache (\r
696 IN EFI_DNS4_PROTOCOL *This,\r
697 IN BOOLEAN DeleteFlag,\r
698 IN BOOLEAN Override,\r
699 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry\r
700 )\r
701{\r
702 EFI_STATUS Status; \r
703 EFI_TPL OldTpl;\r
704\r
705 Status = EFI_SUCCESS;\r
706 \r
707 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
708 return EFI_INVALID_PARAMETER; \r
709 }\r
710 \r
711 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
712\r
713 //\r
714 // Update Dns4Cache here.\r
715 //\r
716 Status = UpdateDns4Cache (&mDriverData->Dns4CacheList, DeleteFlag, Override, DnsCacheEntry);\r
717\r
718 gBS->RestoreTPL (OldTpl);\r
719 \r
720 return Status;\r
721}\r
722\r
723/**\r
724 This function can be used by network drivers and applications to increase the rate that data packets are moved between \r
725 the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed \r
726 network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets \r
727 without missing incoming packets or dropping outgoing packets.\r
728\r
729 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
730\r
731 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
732 @retval EFI_INVALID_PARAMETER This is NULL. \r
733 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
734 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. \r
735 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. \r
736 Consider increasing the polling rate.\r
737 \r
738**/\r
739EFI_STATUS\r
740EFIAPI\r
741Dns4Poll (\r
742 IN EFI_DNS4_PROTOCOL *This\r
743 )\r
744{\r
745 DNS_INSTANCE *Instance;\r
746 EFI_UDP4_PROTOCOL *Udp;\r
747\r
748 if (This == NULL) {\r
749 return EFI_INVALID_PARAMETER;\r
750 }\r
751\r
752 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
753\r
754 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
755 return EFI_NOT_STARTED;\r
756 } else if (Instance->State == DNS_STATE_DESTROY) {\r
757 return EFI_DEVICE_ERROR;\r
758 }\r
759\r
760 Udp = Instance->UdpIo->Protocol.Udp4;\r
761 \r
762 return Udp->Poll (Udp);\r
763}\r
764\r
765/**\r
766 This function is used to abort a pending resolution request. \r
767 After calling this function, Token.Status will be set to EFI_ABORTED and then Token.\r
768\r
769 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
770 @param[in] Token Pointer to a token that has been issued by EFI_DNS4_PROTOCOL.HostNameToIp(), \r
771 EFI_DNS4_PROTOCOL.IpToHostName() or EFI_DNS4_PROTOCOL.GeneralLookup(). \r
772 If NULL, all pending tokens are aborted.\r
773\r
774 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
775 @retval EFI_INVALID_PARAMETER This is NULL. \r
776 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
777 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS operation was not found in the transmit queue. \r
778 It was either completed or was not issued by HostNameToIp(), IpToHostName() or GeneralLookup().\r
779 \r
780**/\r
781EFI_STATUS\r
782EFIAPI\r
783Dns4Cancel (\r
784 IN EFI_DNS4_PROTOCOL *This,\r
785 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
786 )\r
787{\r
788 EFI_STATUS Status;\r
789 DNS_INSTANCE *Instance;\r
790 EFI_TPL OldTpl;\r
791\r
792 if (This == NULL) {\r
793 return EFI_INVALID_PARAMETER;\r
794 }\r
795\r
796 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
797\r
798 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
799 return EFI_NOT_STARTED;\r
800 }\r
801\r
802 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
803\r
804 //\r
805 // Cancle the tokens specified by Token for this instance.\r
806 //\r
807 Status = Dns4InstanceCancelToken (Instance, Token);\r
808\r
809 //\r
810 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
811 //\r
812 DispatchDpc ();\r
813\r
814 gBS->RestoreTPL (OldTpl);\r
815\r
816 return Status;\r
817}\r
818\r
819/**\r
820 This function is used to retrieve DNS mode data for this DNS instance.\r
821\r
822 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
823 @param[out] DnsModeData Pointer to the caller-allocated storage for the EFI_DNS6_MODE_DATA structure.\r
824\r
825 @retval EFI_SUCCESS The operation completed successfully.\r
826 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data is \r
827 available because this instance has not been configured.\r
828 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
829 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.\r
830\r
831**/\r
832EFI_STATUS\r
833EFIAPI\r
834Dns6GetModeData (\r
835 IN EFI_DNS6_PROTOCOL *This,\r
836 OUT EFI_DNS6_MODE_DATA *DnsModeData\r
837 )\r
838{\r
839 DNS_INSTANCE *Instance;\r
840 \r
841 EFI_TPL OldTpl;\r
842\r
843 UINTN Index;\r
844 \r
845 LIST_ENTRY *Entry;\r
846 LIST_ENTRY *Next;\r
847\r
848 DNS6_SERVER_IP *ServerItem;\r
849 EFI_IPv6_ADDRESS *ServerList;\r
850 DNS6_CACHE *CacheItem;\r
851 EFI_DNS6_CACHE_ENTRY *CacheList;\r
852 EFI_STATUS Status;\r
853\r
854 ServerItem = NULL;\r
855 ServerList = NULL;\r
856 CacheItem = NULL;\r
857 CacheList = NULL;\r
858 Status = EFI_SUCCESS;\r
859\r
860 if ((This == NULL) || (DnsModeData == NULL)) {\r
861 return EFI_INVALID_PARAMETER;\r
862 }\r
863\r
864 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
865 \r
866 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
867 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
868 gBS->RestoreTPL (OldTpl);\r
869 return EFI_NOT_STARTED;\r
870 }\r
871\r
872 ZeroMem (DnsModeData, sizeof (EFI_DNS6_MODE_DATA));\r
873\r
874 //\r
875 // Get the current configuration data of this instance. \r
876 //\r
877 Status = Dns6CopyConfigure(&DnsModeData->DnsConfigData, &Instance->Dns6CfgData);\r
878 if (EFI_ERROR (Status)) {\r
879 gBS->RestoreTPL (OldTpl);\r
880 return Status;\r
881 }\r
882 \r
883 //\r
884 // Get the DnsServerCount and DnsServerList\r
885 //\r
886 Index = 0;\r
887 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
888 Index++;\r
889 }\r
890 DnsModeData->DnsServerCount = (UINT32) Index;\r
891 ServerList = AllocatePool (sizeof(EFI_IPv6_ADDRESS) * DnsModeData->DnsServerCount);\r
892 ASSERT (ServerList != NULL);\r
893 Index = 0;\r
894 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
895 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);\r
896 CopyMem (ServerList + Index, &ServerItem->Dns6ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
897 Index++;\r
898 }\r
899 DnsModeData->DnsServerList = ServerList;\r
900\r
901 //\r
902 // Get the DnsCacheCount and DnsCacheList\r
903 //\r
904 Index =0;\r
905 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
906 Index++;\r
907 }\r
908 DnsModeData->DnsCacheCount = (UINT32) Index;\r
909 CacheList = AllocatePool (sizeof(EFI_DNS6_CACHE_ENTRY) * DnsModeData->DnsCacheCount);\r
910 ASSERT (CacheList != NULL);\r
911 Index =0;\r
912 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
913 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
914 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS6_CACHE_ENTRY));\r
915 Index++;\r
916 }\r
917 DnsModeData->DnsCacheList = CacheList;\r
918\r
919 gBS->RestoreTPL (OldTpl);\r
920 \r
921 return EFI_SUCCESS;\r
922}\r
923\r
924/**\r
925 The function is used to set and change the configuration data for this EFI DNSv6 Protocol driver instance. \r
926 Reset the DNS instance if DnsConfigData is NULL.\r
927\r
928 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
929 @param[in] DnsConfigData Pointer to the configuration data structure. \r
930 All associated storage to be allocated and released by caller.\r
931\r
932 @retval EFI_SUCCESS The operation completed successfully.\r
933 @retval EFI_UNSUPPORTED The designated protocol is not supported.\r
934 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
935 @retval EFI_INVALID_PARAMETER This is NULL.\r
936 The StationIp address provided in DnsConfigData is not a valid unicast.\r
937 DnsServerList is NULL while DnsServerListCount is not equal to Zero.\r
938 DnsServerListCount is Zero while DnsServerList is not equal to NULL.\r
939 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI DNSv6 Protocol instance is not configured.\r
940\r
941**/\r
942EFI_STATUS\r
943EFIAPI\r
944Dns6Configure (\r
945 IN EFI_DNS6_PROTOCOL *This,\r
946 IN EFI_DNS6_CONFIG_DATA *DnsConfigData\r
947 )\r
948{\r
949 EFI_STATUS Status;\r
950 DNS_INSTANCE *Instance;\r
951 \r
952 EFI_TPL OldTpl;\r
953\r
954 UINT32 ServerListCount;\r
955 EFI_IPv6_ADDRESS *ServerList; \r
956\r
957 Status = EFI_SUCCESS;\r
958 ServerList = NULL;\r
959\r
960 if (This == NULL || \r
961 (DnsConfigData != NULL && ((DnsConfigData->DnsServerCount != 0 && DnsConfigData->DnsServerList == NULL) || \r
962 (DnsConfigData->DnsServerCount == 0 && DnsConfigData->DnsServerList != NULL)))) {\r
963 return EFI_INVALID_PARAMETER;\r
964 }\r
965\r
966 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {\r
967 return EFI_UNSUPPORTED;\r
968 }\r
969\r
970 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
971\r
972 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
973\r
974 if (DnsConfigData == NULL) {\r
975 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));\r
976\r
977 //\r
978 // Reset the Instance if ConfigData is NULL\r
979 //\r
980 if (!NetMapIsEmpty(&Instance->Dns6TxTokens)) {\r
981 Dns6InstanceCancelToken(Instance, NULL);\r
982 }\r
983\r
984 Instance->MaxRetry = 0;\r
985\r
986 if (Instance->UdpIo != NULL){\r
987 UdpIoCleanIo (Instance->UdpIo);\r
988 }\r
989\r
990 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
991 FreePool (Instance->Dns6CfgData.DnsServerList);\r
992 }\r
993 ZeroMem (&Instance->Dns6CfgData, sizeof (EFI_DNS6_CONFIG_DATA));\r
994 \r
995 Instance->State = DNS_STATE_UNCONFIGED;\r
996 } else {\r
997 //\r
998 // Configure the parameters for new operation.\r
999 //\r
90ae1f02 1000 if (!NetIp6IsUnspecifiedAddr (&DnsConfigData->StationIp) && !NetIp6IsValidUnicast (&DnsConfigData->StationIp)) {\r
99c048ef 1001 Status = EFI_INVALID_PARAMETER;\r
1002 goto ON_EXIT;\r
1003 }\r
1004\r
1005 Status = Dns6CopyConfigure (&Instance->Dns6CfgData, DnsConfigData);\r
1006 if (EFI_ERROR (Status)) {\r
1007 goto ON_EXIT;\r
1008 }\r
1009\r
1010 if (DnsConfigData->DnsServerCount == 0 || DnsConfigData->DnsServerList == NULL) {\r
1011 gBS->RestoreTPL (OldTpl);\r
1012\r
1013 //\r
1014 //The DNS instance will retrieve DNS server from DHCP Server.\r
1015 //\r
1016 Status = GetDns6ServerFromDhcp6 (\r
1017 Instance->Service->ImageHandle,\r
1018 Instance->Service->ControllerHandle, \r
1019 &ServerListCount, \r
1020 &ServerList\r
1021 );\r
1022 if (EFI_ERROR (Status)) {\r
1023 goto ON_EXIT;\r
1024 }\r
1025 \r
1026 ASSERT(ServerList != NULL);\r
1027\r
1028 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1029\r
1030 CopyMem (&Instance->SessionDnsServer.v6, &ServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1031 } else {\r
1032 CopyMem (&Instance->SessionDnsServer.v6, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1033 }\r
1034\r
1035 //\r
1036 // Config UDP\r
1037 //\r
1038 Status = Dns6ConfigUdp (Instance, Instance->UdpIo);\r
1039 if (EFI_ERROR (Status)) {\r
1040 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1041 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1042 }\r
1043 goto ON_EXIT;\r
1044 }\r
1045\r
1046 //\r
1047 // Add configured DNS server used by this instance to ServerList.\r
1048 //\r
1049 Status = AddDns6ServerIp (&mDriverData->Dns6ServerList, Instance->SessionDnsServer.v6);\r
1050 if (EFI_ERROR (Status)) {\r
1051 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1052 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1053 }\r
1054 goto ON_EXIT;\r
1055 }\r
1056 \r
1057 Instance->State = DNS_STATE_CONFIGED;\r
1058 }\r
1059\r
1060ON_EXIT:\r
1061 gBS->RestoreTPL (OldTpl);\r
1062 return Status;\r
1063}\r
1064\r
1065/**\r
1066 The function is used to translate the host name to host IP address. \r
1067 A type AAAA query is used to get the one or more IPv6 addresses for this host. \r
1068\r
1069 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1070 @param[in] HostName Pointer to caller-supplied buffer containing Host name to be translated. \r
1071 This buffer contains 16 bit characters but these are translated to ASCII for use with \r
1072 DNSv4 server and there is no requirement for driver to support non-ASCII Unicode characters.\r
1073 @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
1074\r
1075 @retval EFI_SUCCESS The operation completed successfully.\r
1076 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
1077 @retval EFI_INVALID_PARAMETER This is NULL.\r
1078 Token is NULL.\r
1079 Token.Event is.NULL\r
1080 HostName is NULL\r
1081 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1082 @retval EFI_NOT_STARTED This instance has not been started.\r
1083\r
1084**/\r
1085EFI_STATUS\r
1086EFIAPI\r
1087Dns6HostNameToIp (\r
1088 IN EFI_DNS6_PROTOCOL *This,\r
1089 IN CHAR16 *HostName,\r
1090 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1091 )\r
1092{\r
1093 EFI_STATUS Status;\r
1094 \r
1095 DNS_INSTANCE *Instance;\r
1096\r
1097 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1098 \r
1099 UINTN Index; \r
1100 DNS6_CACHE *Item;\r
1101 LIST_ENTRY *Entry;\r
1102 LIST_ENTRY *Next;\r
1103 \r
fcae1a99
JW
1104 CHAR8 *QueryName;\r
1105 \r
99c048ef 1106 DNS6_TOKEN_ENTRY *TokenEntry;\r
1107 NET_BUF *Packet;\r
1108 \r
1109 EFI_TPL OldTpl;\r
1110 \r
1111 Status = EFI_SUCCESS;\r
1112 Item = NULL;\r
fcae1a99 1113 QueryName = NULL;\r
99c048ef 1114 TokenEntry = NULL;\r
1115 Packet = NULL;\r
1116\r
1117 //\r
1118 // Validate the parameters\r
1119 //\r
1120 if ((This == NULL) || (HostName == NULL) || Token == NULL) {\r
1121 return EFI_INVALID_PARAMETER;\r
1122 }\r
1123\r
1124 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1125 \r
1126 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1127 \r
1128 ConfigData = &(Instance->Dns6CfgData);\r
1129 \r
1130 Instance->MaxRetry = ConfigData->RetryCount;\r
1131\r
1132 Token->Status = EFI_NOT_READY;\r
1133 Token->RetryCount = 0;\r
1134 Token->RetryInterval = ConfigData->RetryInterval;\r
1135\r
1136 if (Instance->State != DNS_STATE_CONFIGED) {\r
1137 Status = EFI_NOT_STARTED;\r
1138 goto ON_EXIT;\r
1139 }\r
1140\r
1141 //\r
1142 // Check the MaxRetry and RetryInterval values.\r
1143 //\r
1144 if (Instance->MaxRetry == 0) {\r
1145 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1146 }\r
1147\r
1148 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1149 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1150 } \r
1151\r
1152 //\r
1153 // Check cache\r
1154 //\r
1155 if (ConfigData->EnableDnsCache) {\r
1156 Index = 0;\r
1157 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1158 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1159 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1160 Index++;\r
1161 }\r
1162 }\r
1163\r
1164 if (Index != 0) {\r
1165 Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
1166 if (Token->RspData.H2AData == NULL) {\r
1167 Status = EFI_OUT_OF_RESOURCES;\r
1168 goto ON_EXIT;\r
1169 }\r
1170\r
1171 Token->RspData.H2AData->IpCount = (UINT32)Index;\r
1172 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * Index);\r
1173 if (Token->RspData.H2AData->IpList == NULL) {\r
1174 if (Token->RspData.H2AData != NULL) {\r
1175 FreePool (Token->RspData.H2AData);\r
1176 }\r
1177 \r
1178 Status = EFI_OUT_OF_RESOURCES;\r
1179 goto ON_EXIT;\r
1180 }\r
1181\r
1182 Index = 0;\r
1183 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1184 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1185 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1186 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
1187 Index++;\r
1188 }\r
1189 }\r
1190 \r
1191 Token->Status = EFI_SUCCESS;\r
1192 \r
1193 if (Token->Event != NULL) {\r
1194 gBS->SignalEvent (Token->Event);\r
1195 DispatchDpc ();\r
1196 }\r
1197 \r
1198 Status = Token->Status;\r
1199 goto ON_EXIT;\r
1200 } \r
1201 }\r
1202\r
1203 //\r
1204 // Construct DNS TokenEntry.\r
1205 //\r
1206 TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));\r
1207 if (TokenEntry == NULL) {\r
1208 Status = EFI_OUT_OF_RESOURCES;\r
1209 goto ON_EXIT;\r
1210 }\r
1211 \r
1212 TokenEntry->PacketToLive = Token->RetryInterval;\r
1213 TokenEntry->QueryHostName = HostName;\r
1214 TokenEntry->Token = Token;\r
1215\r
fcae1a99
JW
1216\r
1217 //\r
1218 // Construct QName.\r
1219 //\r
1220 QueryName = DnsFillinQNameForQueryIp (TokenEntry->QueryHostName);\r
1221 if (QueryName == NULL) {\r
1222 Status = EFI_OUT_OF_RESOURCES;\r
1223 goto ON_EXIT;\r
1224 }\r
1225 \r
99c048ef 1226 //\r
1227 // Construct DNS Query Packet.\r
1228 //\r
fcae1a99 1229 Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_AAAA, DNS_CLASS_INET, &Packet);\r
99c048ef 1230 if (EFI_ERROR (Status)) {\r
1231 if (TokenEntry != NULL) {\r
1232 FreePool (TokenEntry);\r
1233 }\r
1234 \r
1235 goto ON_EXIT;\r
1236 }\r
1237\r
8339166d
JW
1238 ASSERT (Packet != NULL);\r
1239\r
99c048ef 1240 //\r
1241 // Save the token into the Dns6TxTokens map.\r
1242 //\r
1243 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1244 if (EFI_ERROR (Status)) {\r
1245 if (TokenEntry != NULL) {\r
1246 FreePool (TokenEntry);\r
1247 }\r
1248 \r
1249 NetbufFree (Packet);\r
1250 \r
1251 goto ON_EXIT;\r
1252 }\r
1253 \r
1254 //\r
1255 // Dns Query Ip\r
1256 //\r
1257 Status = DoDnsQuery (Instance, Packet);\r
1258 if (EFI_ERROR (Status)) {\r
1259 if (TokenEntry != NULL) {\r
1260 FreePool (TokenEntry);\r
1261 }\r
1262 \r
1263 NetbufFree (Packet);\r
1264 }\r
1265 \r
1266ON_EXIT:\r
fcae1a99
JW
1267 if (QueryName != NULL) {\r
1268 FreePool (QueryName);\r
1269 }\r
1270 \r
99c048ef 1271 gBS->RestoreTPL (OldTpl);\r
1272 return Status;\r
1273}\r
1274\r
1275/**\r
1276 The function is used to translate the host address to host name. \r
1277 A type PTR query is used to get the primary name of the host. \r
1278\r
1279 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1280 @param[in] IpAddress IP address.\r
1281 @param[in] Token Pointer to the caller-allocated completion used token to translate host address to host name.\r
1282\r
1283 @retval EFI_SUCCESS The operation completed successfully.\r
1284 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
1285 @retval EFI_INVALID_PARAMETER This is NULL.\r
1286 Token is NULL.\r
1287 Token.Event is NULL.\r
1288 IpAddress is not valid IP address.\r
1289 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1290 @retval EFI_NOT_STARTED This instance has not been started.\r
1291 @retval EFI_UNSUPPORTED This function is not supported.\r
1292\r
1293**/\r
1294EFI_STATUS\r
1295EFIAPI\r
1296Dns6IpToHostName (\r
1297 IN EFI_DNS6_PROTOCOL *This,\r
1298 IN EFI_IPv6_ADDRESS IpAddress,\r
1299 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1300 )\r
1301{\r
1302 return EFI_UNSUPPORTED;\r
1303}\r
1304\r
1305/**\r
1306 This function retrieves arbitrary information from the DNS. \r
1307 The caller supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. \r
1308 All RR content (e.g., Ttl) was returned. \r
1309 The caller need parse the returned RR to get required information. This function is optional.\r
1310\r
1311 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1312 @param[in] QName Pointer to Query Name.\r
1313 @param[in] QType Query Type.\r
1314 @param[in] QClass Query Name.\r
1315 @param[in] Token Point to the caller-allocated completion token to retrieve arbitrary information.\r
1316\r
1317 @retval EFI_SUCCESS The operation completed successfully.\r
1318 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
1319 @retval EFI_INVALID_PARAMETER This is NULL.\r
1320 Token is NULL.\r
1321 Token.Event is NULL.\r
1322 QName is NULL.\r
1323 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1324 @retval EFI_NOT_STARTED This instance has not been started.\r
1325 @retval EFI_UNSUPPORTED This function is not supported. Or the requested QType is not supported\r
1326\r
1327**/\r
1328EFI_STATUS\r
1329EFIAPI\r
1330Dns6GeneralLookUp (\r
1331 IN EFI_DNS6_PROTOCOL *This,\r
1332 IN CHAR8 *QName,\r
1333 IN UINT16 QType, \r
1334 IN UINT16 QClass,\r
1335 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1336 )\r
1337{\r
fcae1a99
JW
1338 EFI_STATUS Status;\r
1339 \r
1340 DNS_INSTANCE *Instance;\r
1341 \r
1342 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1343 \r
1344 DNS6_TOKEN_ENTRY *TokenEntry;\r
1345 NET_BUF *Packet;\r
1346 \r
1347 EFI_TPL OldTpl;\r
1348 \r
1349 Status = EFI_SUCCESS;\r
1350 TokenEntry = NULL;\r
1351 Packet = NULL;\r
1352 \r
1353 //\r
1354 // Validate the parameters\r
1355 //\r
1356 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
1357 return EFI_INVALID_PARAMETER;\r
1358 }\r
1359 \r
1360 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1361 \r
1362 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1363 \r
1364 ConfigData = &(Instance->Dns6CfgData);\r
1365 \r
1366 Instance->MaxRetry = ConfigData->RetryCount;\r
1367 \r
1368 Token->Status = EFI_NOT_READY;\r
1369 Token->RetryCount = 0;\r
1370 Token->RetryInterval = ConfigData->RetryInterval;\r
1371\r
1372 if (Instance->State != DNS_STATE_CONFIGED) {\r
1373 Status = EFI_NOT_STARTED;\r
1374 goto ON_EXIT;\r
1375 }\r
1376\r
1377 //\r
1378 // Check the MaxRetry and RetryInterval values.\r
1379 //\r
1380 if (Instance->MaxRetry == 0) {\r
1381 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1382 }\r
1383\r
1384 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1385 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1386 }\r
1387\r
1388 //\r
1389 // Construct DNS TokenEntry.\r
1390 //\r
1391 TokenEntry = AllocateZeroPool (sizeof(DNS6_TOKEN_ENTRY));\r
1392 if (TokenEntry == NULL) {\r
1393 Status = EFI_OUT_OF_RESOURCES;\r
1394 goto ON_EXIT;\r
1395 }\r
1396 \r
1397 TokenEntry->PacketToLive = Token->RetryInterval;\r
1398 TokenEntry->GeneralLookUp = TRUE;\r
1399 TokenEntry->Token = Token;\r
1400\r
1401 //\r
1402 // Construct DNS Query Packet.\r
1403 //\r
1404 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
1405 if (EFI_ERROR (Status)) {\r
1406 if (TokenEntry != NULL) {\r
1407 FreePool (TokenEntry);\r
1408 }\r
1409 \r
1410 goto ON_EXIT;\r
1411 }\r
1412\r
8339166d
JW
1413 ASSERT (Packet != NULL);\r
1414\r
fcae1a99
JW
1415 //\r
1416 // Save the token into the Dns6TxTokens map.\r
1417 //\r
1418 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1419 if (EFI_ERROR (Status)) {\r
1420 if (TokenEntry != NULL) {\r
1421 FreePool (TokenEntry);\r
1422 }\r
1423 \r
1424 NetbufFree (Packet);\r
1425 \r
1426 goto ON_EXIT;\r
1427 }\r
1428 \r
1429 //\r
1430 // Dns Query Ip\r
1431 //\r
1432 Status = DoDnsQuery (Instance, Packet);\r
1433 if (EFI_ERROR (Status)) {\r
1434 if (TokenEntry != NULL) {\r
1435 FreePool (TokenEntry);\r
1436 }\r
1437 \r
1438 NetbufFree (Packet);\r
1439 }\r
1440 \r
1441ON_EXIT:\r
1442 gBS->RestoreTPL (OldTpl);\r
1443 return Status;\r
99c048ef 1444}\r
1445\r
1446/**\r
1447 This function is used to add/delete/modify DNS cache entry. \r
1448 DNS cache can be normally dynamically updated after the DNS resolve succeeds. \r
1449 This function provided capability to manually add/delete/modify the DNS cache.\r
1450\r
1451 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1452 @param[in] DeleteFlag If FALSE, this function is to add one entry to the DNS Cache. \r
1453 If TRUE, this function will delete matching DNS Cache entry. \r
1454 @param[in] Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
1455 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
1456 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
1457\r
1458 @retval EFI_SUCCESS The operation completed successfully.\r
1459 @retval EFI_INVALID_PARAMETER This is NULL. \r
1460 DnsCacheEntry.HostName is NULL.\r
1461 DnsCacheEntry.IpAddress is NULL.\r
1462 DnsCacheEntry.Timeout is zero.\r
1463 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is not TRUE. \r
1464\r
1465**/\r
1466EFI_STATUS\r
1467EFIAPI\r
1468Dns6UpdateDnsCache (\r
1469 IN EFI_DNS6_PROTOCOL *This,\r
1470 IN BOOLEAN DeleteFlag,\r
1471 IN BOOLEAN Override,\r
1472 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry\r
1473 )\r
1474{\r
1475 EFI_STATUS Status; \r
1476 EFI_TPL OldTpl;\r
1477\r
1478 Status = EFI_SUCCESS;\r
1479 \r
1480 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
1481 return EFI_INVALID_PARAMETER; \r
1482 }\r
1483 \r
1484 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1485\r
1486 //\r
1487 // Update Dns6Cache here.\r
1488 //\r
1489 Status = UpdateDns6Cache (&mDriverData->Dns6CacheList, DeleteFlag, Override, DnsCacheEntry);\r
1490 \r
1491 gBS->RestoreTPL (OldTpl);\r
1492 \r
1493 return Status;\r
1494}\r
1495\r
1496/**\r
1497 This function can be used by network drivers and applications to increase the rate that data packets are moved between \r
1498 the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed \r
1499 network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets \r
1500 without missing incoming packets or dropping outgoing packets.\r
1501\r
1502 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1503\r
1504 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1505 @retval EFI_INVALID_PARAMETER This is NULL. \r
1506 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
1507 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. \r
1508 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. \r
1509 Consider increasing the polling rate.\r
1510 \r
1511**/\r
1512EFI_STATUS\r
1513EFIAPI\r
1514Dns6Poll (\r
1515 IN EFI_DNS6_PROTOCOL *This\r
1516 )\r
1517{\r
1518 DNS_INSTANCE *Instance;\r
1519 EFI_UDP6_PROTOCOL *Udp;\r
1520\r
1521 if (This == NULL) {\r
1522 return EFI_INVALID_PARAMETER;\r
1523 }\r
1524\r
1525 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1526\r
1527 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1528 return EFI_NOT_STARTED;\r
1529 } else if (Instance->State == DNS_STATE_DESTROY) {\r
1530 return EFI_DEVICE_ERROR;\r
1531 }\r
1532\r
1533 Udp = Instance->UdpIo->Protocol.Udp6;\r
1534 \r
1535 return Udp->Poll (Udp);\r
1536}\r
1537\r
1538/**\r
1539 This function is used to abort a pending resolution request. \r
1540 After calling this function, Token.Status will be set to EFI_ABORTED and then Token.\r
1541\r
1542 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1543 @param[in] Token Pointer to a token that has been issued by EFI_DNS6_PROTOCOL.HostNameToIp(), \r
1544 EFI_DNS6_PROTOCOL.IpToHostName() or EFI_DNS6_PROTOCOL.GeneralLookup(). \r
1545 If NULL, all pending tokens are aborted.\r
1546\r
1547 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1548 @retval EFI_INVALID_PARAMETER This is NULL. \r
1549 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started. \r
1550 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS operation was not found in the transmit queue. \r
1551 It was either completed or was not issued by HostNameToIp(), IpToHostName() or GeneralLookup().\r
1552 \r
1553**/\r
1554EFI_STATUS\r
1555EFIAPI\r
1556Dns6Cancel (\r
1557 IN EFI_DNS6_PROTOCOL *This,\r
1558 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1559 )\r
1560{\r
1561 EFI_STATUS Status;\r
1562 DNS_INSTANCE *Instance;\r
1563 EFI_TPL OldTpl;\r
1564\r
1565 if (This == NULL) {\r
1566 return EFI_INVALID_PARAMETER;\r
1567 }\r
1568\r
1569 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1570\r
1571 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1572 return EFI_NOT_STARTED;\r
1573 }\r
1574\r
1575 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1576\r
1577 //\r
1578 // Cancle the tokens specified by Token for this instance.\r
1579 //\r
1580 Status = Dns6InstanceCancelToken (Instance, Token);\r
1581\r
1582 //\r
1583 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
1584 //\r
1585 DispatchDpc ();\r
1586\r
1587 gBS->RestoreTPL (OldTpl);\r
1588\r
1589 return Status;\r
1590}\r
1591\r