2 DnsDxe support functions implementation.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Remove TokenEntry from TokenMap.
20 @param[in] TokenMap All DNSv4 Token entrys.
21 @param[in] TokenEntry TokenEntry need to be removed.
23 @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.
24 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
28 Dns4RemoveTokenEntry (
30 IN DNS4_TOKEN_ENTRY
*TokenEntry
36 // Find the TokenEntry first.
38 Item
= NetMapFindKey (TokenMap
, (VOID
*) TokenEntry
);
42 // Remove the TokenEntry if it's found in the map.
44 NetMapRemoveItem (TokenMap
, Item
, NULL
);
53 Remove TokenEntry from TokenMap.
55 @param[in] TokenMap All DNSv6 Token entrys.
56 @param[in] TokenEntry TokenEntry need to be removed.
58 @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.
59 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
63 Dns6RemoveTokenEntry (
65 IN DNS6_TOKEN_ENTRY
*TokenEntry
71 // Find the TokenEntry first.
73 Item
= NetMapFindKey (TokenMap
, (VOID
*) TokenEntry
);
77 // Remove the TokenEntry if it's found in the map.
79 NetMapRemoveItem (TokenMap
, Item
, NULL
);
88 This function cancle the token specified by Arg in the Map.
90 @param[in] Map Pointer to the NET_MAP.
91 @param[in] Item Pointer to the NET_MAP_ITEM.
92 @param[in] Arg Pointer to the token to be cancelled. If NULL, all
93 the tokens in this Map will be cancelled.
94 This parameter is optional and may be NULL.
96 @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token
97 is not the same as that in the Item, if Arg is not
99 @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is
107 IN NET_MAP_ITEM
*Item
,
108 IN VOID
*Arg OPTIONAL
111 DNS4_TOKEN_ENTRY
*TokenEntry
;
115 if ((Arg
!= NULL
) && (Item
->Key
!= Arg
)) {
119 if (Item
->Value
!= NULL
) {
121 // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
124 Packet
= (NET_BUF
*) (Item
->Value
);
125 UdpIo
= (UDP_IO
*) (*((UINTN
*) &Packet
->ProtoData
[0]));
127 UdpIoCancelSentDatagram (UdpIo
, Packet
);
131 // Remove TokenEntry from Dns4TxTokens.
133 TokenEntry
= (DNS4_TOKEN_ENTRY
*) Item
->Key
;
134 if (Dns4RemoveTokenEntry (Map
, TokenEntry
) == EFI_SUCCESS
) {
135 TokenEntry
->Token
->Status
= EFI_ABORTED
;
136 gBS
->SignalEvent (TokenEntry
->Token
->Event
);
148 This function cancle the token specified by Arg in the Map.
150 @param[in] Map Pointer to the NET_MAP.
151 @param[in] Item Pointer to the NET_MAP_ITEM.
152 @param[in] Arg Pointer to the token to be cancelled. If NULL, all
153 the tokens in this Map will be cancelled.
154 This parameter is optional and may be NULL.
156 @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token
157 is not the same as that in the Item, if Arg is not
159 @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is
167 IN NET_MAP_ITEM
*Item
,
168 IN VOID
*Arg OPTIONAL
171 DNS6_TOKEN_ENTRY
*TokenEntry
;
175 if ((Arg
!= NULL
) && (Item
->Key
!= Arg
)) {
179 if (Item
->Value
!= NULL
) {
181 // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
184 Packet
= (NET_BUF
*) (Item
->Value
);
185 UdpIo
= (UDP_IO
*) (*((UINTN
*) &Packet
->ProtoData
[0]));
187 UdpIoCancelSentDatagram (UdpIo
, Packet
);
191 // Remove TokenEntry from Dns6TxTokens.
193 TokenEntry
= (DNS6_TOKEN_ENTRY
*) Item
->Key
;
194 if (Dns6RemoveTokenEntry (Map
, TokenEntry
) == EFI_SUCCESS
) {
195 TokenEntry
->Token
->Status
= EFI_ABORTED
;
196 gBS
->SignalEvent (TokenEntry
->Token
->Event
);
208 Get the TokenEntry from the TokensMap.
210 @param[in] TokensMap All DNSv4 Token entrys
211 @param[in] Token Pointer to the token to be get.
212 @param[out] TokenEntry Pointer to TokenEntry corresponding Token.
214 @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.
215 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
221 IN NET_MAP
*TokensMap
,
222 IN EFI_DNS4_COMPLETION_TOKEN
*Token
,
223 OUT DNS4_TOKEN_ENTRY
**TokenEntry
230 NET_LIST_FOR_EACH (Entry
, &TokensMap
->Used
) {
231 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
232 *TokenEntry
= (DNS4_TOKEN_ENTRY
*) (Item
->Key
);
233 if ((*TokenEntry
)->Token
== Token
) {
240 return EFI_NOT_FOUND
;
244 Get the TokenEntry from the TokensMap.
246 @param[in] TokensMap All DNSv6 Token entrys
247 @param[in] Token Pointer to the token to be get.
248 @param[out] TokenEntry Pointer to TokenEntry corresponding Token.
250 @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.
251 @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
257 IN NET_MAP
*TokensMap
,
258 IN EFI_DNS6_COMPLETION_TOKEN
*Token
,
259 OUT DNS6_TOKEN_ENTRY
**TokenEntry
266 NET_LIST_FOR_EACH (Entry
, &TokensMap
->Used
) {
267 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
268 *TokenEntry
= (DNS6_TOKEN_ENTRY
*) (Item
->Key
);
269 if ((*TokenEntry
)->Token
== Token
) {
276 return EFI_NOT_FOUND
;
280 Cancel DNS4 tokens from the DNS4 instance.
282 @param[in] Instance Pointer to the DNS instance context data.
283 @param[in] Token Pointer to the token to be canceled. If NULL, all
284 tokens in this instance will be cancelled.
285 This parameter is optional and may be NULL.
287 @retval EFI_SUCCESS The Token is cancelled.
288 @retval EFI_NOT_FOUND The Token is not found.
292 Dns4InstanceCancelToken (
293 IN DNS_INSTANCE
*Instance
,
294 IN EFI_DNS4_COMPLETION_TOKEN
*Token
298 DNS4_TOKEN_ENTRY
*TokenEntry
;
303 Status
= GetDns4TokenEntry (&Instance
->Dns4TxTokens
, Token
, &TokenEntry
);
304 if (EFI_ERROR (Status
)) {
312 // Cancel this TokenEntry from the Dns4TxTokens map.
314 Status
= NetMapIterate (&Instance
->Dns4TxTokens
, Dns4CancelTokens
, TokenEntry
);
316 if ((TokenEntry
!= NULL
) && (Status
== EFI_ABORTED
)) {
318 // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
319 // the Dns4TxTokens and returns success.
321 if (NetMapIsEmpty (&Instance
->Dns4TxTokens
)) {
322 Instance
->UdpIo
->Protocol
.Udp4
->Cancel (Instance
->UdpIo
->Protocol
.Udp4
, &Instance
->UdpIo
->RecvRequest
->Token
.Udp4
);
327 ASSERT ((TokenEntry
!= NULL
) || (0 == NetMapGetCount (&Instance
->Dns4TxTokens
)));
329 if (NetMapIsEmpty (&Instance
->Dns4TxTokens
)) {
330 Instance
->UdpIo
->Protocol
.Udp4
->Cancel (Instance
->UdpIo
->Protocol
.Udp4
, &Instance
->UdpIo
->RecvRequest
->Token
.Udp4
);
337 Cancel DNS6 tokens from the DNS6 instance.
339 @param[in] Instance Pointer to the DNS instance context data.
340 @param[in] Token Pointer to the token to be canceled. If NULL, all
341 tokens in this instance will be cancelled.
342 This parameter is optional and may be NULL.
344 @retval EFI_SUCCESS The Token is cancelled.
345 @retval EFI_NOT_FOUND The Token is not found.
349 Dns6InstanceCancelToken (
350 IN DNS_INSTANCE
*Instance
,
351 IN EFI_DNS6_COMPLETION_TOKEN
*Token
355 DNS6_TOKEN_ENTRY
*TokenEntry
;
360 Status
= GetDns6TokenEntry (&Instance
->Dns6TxTokens
, Token
, &TokenEntry
);
361 if (EFI_ERROR (Status
)) {
369 // Cancel this TokenEntry from the Dns6TxTokens map.
371 Status
= NetMapIterate (&Instance
->Dns6TxTokens
, Dns6CancelTokens
, TokenEntry
);
373 if ((TokenEntry
!= NULL
) && (Status
== EFI_ABORTED
)) {
375 // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
376 // the Dns6TxTokens and returns success.
378 if (NetMapIsEmpty (&Instance
->Dns6TxTokens
)) {
379 Instance
->UdpIo
->Protocol
.Udp6
->Cancel (Instance
->UdpIo
->Protocol
.Udp6
, &Instance
->UdpIo
->RecvRequest
->Token
.Udp6
);
384 ASSERT ((TokenEntry
!= NULL
) || (0 == NetMapGetCount (&Instance
->Dns6TxTokens
)));
386 if (NetMapIsEmpty (&Instance
->Dns6TxTokens
)) {
387 Instance
->UdpIo
->Protocol
.Udp6
->Cancel (Instance
->UdpIo
->Protocol
.Udp6
, &Instance
->UdpIo
->RecvRequest
->Token
.Udp6
);
394 Free the resource related to the configure parameters.
396 @param Config The DNS configure data
401 IN OUT EFI_DNS4_CONFIG_DATA
*Config
404 if (Config
->DnsServerList
!= NULL
) {
405 FreePool (Config
->DnsServerList
);
408 ZeroMem (Config
, sizeof (EFI_DNS4_CONFIG_DATA
));
412 Free the resource related to the configure parameters.
414 @param Config The DNS configure data
419 IN OUT EFI_DNS6_CONFIG_DATA
*Config
422 if (Config
->DnsServerList
!= NULL
) {
423 FreePool (Config
->DnsServerList
);
426 ZeroMem (Config
, sizeof (EFI_DNS6_CONFIG_DATA
));
430 Allocate memory for configure parameter such as timeout value for Dst,
431 then copy the configure parameter from Src to Dst.
433 @param[out] Dst The destination DHCP configure data.
434 @param[in] Src The source DHCP configure data.
436 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
437 @retval EFI_SUCCESS The configure is copied.
442 OUT EFI_DNS4_CONFIG_DATA
*Dst
,
443 IN EFI_DNS4_CONFIG_DATA
*Src
449 CopyMem (Dst
, Src
, sizeof (*Dst
));
450 Dst
->DnsServerList
= NULL
;
453 // Allocate a memory then copy DnsServerList to it
455 if (Src
->DnsServerList
!= NULL
) {
456 Len
= Src
->DnsServerListCount
* sizeof (EFI_IPv4_ADDRESS
);
457 Dst
->DnsServerList
= AllocatePool (Len
);
458 if (Dst
->DnsServerList
== NULL
) {
459 Dns4CleanConfigure (Dst
);
460 return EFI_OUT_OF_RESOURCES
;
463 for (Index
= 0; Index
< Src
->DnsServerListCount
; Index
++) {
464 CopyMem (&Dst
->DnsServerList
[Index
], &Src
->DnsServerList
[Index
], sizeof (EFI_IPv4_ADDRESS
));
472 Allocate memory for configure parameter such as timeout value for Dst,
473 then copy the configure parameter from Src to Dst.
475 @param[out] Dst The destination DHCP configure data.
476 @param[in] Src The source DHCP configure data.
478 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
479 @retval EFI_SUCCESS The configure is copied.
484 OUT EFI_DNS6_CONFIG_DATA
*Dst
,
485 IN EFI_DNS6_CONFIG_DATA
*Src
491 CopyMem (Dst
, Src
, sizeof (*Dst
));
492 Dst
->DnsServerList
= NULL
;
495 // Allocate a memory then copy DnsServerList to it
497 if (Src
->DnsServerList
!= NULL
) {
498 Len
= Src
->DnsServerCount
* sizeof (EFI_IPv6_ADDRESS
);
499 Dst
->DnsServerList
= AllocatePool (Len
);
500 if (Dst
->DnsServerList
== NULL
) {
501 Dns6CleanConfigure (Dst
);
502 return EFI_OUT_OF_RESOURCES
;
505 for (Index
= 0; Index
< Src
->DnsServerCount
; Index
++) {
506 CopyMem (&Dst
->DnsServerList
[Index
], &Src
->DnsServerList
[Index
], sizeof (EFI_IPv6_ADDRESS
));
514 Callback of Dns packet. Does nothing.
516 @param Arg The context.
528 Poll the UDP to get the IP4 default address, which may be retrieved
531 The default time out value is 5 seconds. If IP has retrieved the default address,
532 the UDP is reconfigured.
534 @param Instance The DNS instance
535 @param UdpIo The UDP_IO to poll
536 @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
538 @retval TRUE The default address is retrieved and UDP is reconfigured.
539 @retval FALSE Some error occured.
544 IN DNS_INSTANCE
*Instance
,
546 IN EFI_UDP4_CONFIG_DATA
*UdpCfgData
549 DNS_SERVICE
*Service
;
550 EFI_IP4_MODE_DATA Ip4Mode
;
551 EFI_UDP4_PROTOCOL
*Udp
;
554 ASSERT (Instance
->Dns4CfgData
.UseDefaultSetting
);
556 Service
= Instance
->Service
;
557 Udp
= UdpIo
->Protocol
.Udp4
;
559 Status
= gBS
->SetTimer (
560 Service
->TimerToGetMap
,
562 DNS_TIME_TO_GETMAP
* TICKS_PER_SECOND
564 if (EFI_ERROR (Status
)) {
568 while (!EFI_ERROR (gBS
->CheckEvent (Service
->TimerToGetMap
))) {
571 if (!EFI_ERROR (Udp
->GetModeData (Udp
, NULL
, &Ip4Mode
, NULL
, NULL
)) &&
572 Ip4Mode
.IsConfigured
) {
574 Udp
->Configure (Udp
, NULL
);
575 return (BOOLEAN
) (Udp
->Configure (Udp
, UdpCfgData
) == EFI_SUCCESS
);
583 Configure the opened Udp6 instance until the corresponding Ip6 instance
586 @param Instance The DNS instance
587 @param UdpIo The UDP_IO to poll
588 @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
590 @retval TRUE Configure the Udp6 instance successfully.
591 @retval FALSE Some error occured.
596 IN DNS_INSTANCE
*Instance
,
598 IN EFI_UDP6_CONFIG_DATA
*UdpCfgData
601 DNS_SERVICE
*Service
;
602 EFI_IP6_MODE_DATA Ip6Mode
;
603 EFI_UDP6_PROTOCOL
*Udp
;
606 Service
= Instance
->Service
;
607 Udp
= UdpIo
->Protocol
.Udp6
;
609 Status
= gBS
->SetTimer (
610 Service
->TimerToGetMap
,
612 DNS_TIME_TO_GETMAP
* TICKS_PER_SECOND
614 if (EFI_ERROR (Status
)) {
618 while (!EFI_ERROR (gBS
->CheckEvent (Service
->TimerToGetMap
))) {
621 if (!EFI_ERROR (Udp
->GetModeData (Udp
, NULL
, &Ip6Mode
, NULL
, NULL
)) &&
622 Ip6Mode
.IsConfigured
) {
624 Udp
->Configure (Udp
, NULL
);
625 return (BOOLEAN
) (Udp
->Configure (Udp
, UdpCfgData
) == EFI_SUCCESS
);
635 @param Instance The DNS session
636 @param UdpIo The UDP_IO instance
638 @retval EFI_SUCCESS The UDP is successfully configured for the
644 IN DNS_INSTANCE
*Instance
,
648 EFI_DNS4_CONFIG_DATA
*Config
;
649 EFI_UDP4_CONFIG_DATA UdpConfig
;
652 Config
= &Instance
->Dns4CfgData
;
654 UdpConfig
.AcceptBroadcast
= FALSE
;
655 UdpConfig
.AcceptPromiscuous
= FALSE
;
656 UdpConfig
.AcceptAnyPort
= FALSE
;
657 UdpConfig
.AllowDuplicatePort
= FALSE
;
658 UdpConfig
.TypeOfService
= 0;
659 UdpConfig
.TimeToLive
= 128;
660 UdpConfig
.DoNotFragment
= FALSE
;
661 UdpConfig
.ReceiveTimeout
= 0;
662 UdpConfig
.TransmitTimeout
= 0;
663 UdpConfig
.UseDefaultAddress
= Config
->UseDefaultSetting
;
664 UdpConfig
.SubnetMask
= Config
->SubnetMask
;
665 UdpConfig
.StationPort
= Config
->LocalPort
;
666 UdpConfig
.RemotePort
= DNS_SERVER_PORT
;
668 CopyMem (&UdpConfig
.StationAddress
, &Config
->StationIp
, sizeof (EFI_IPv4_ADDRESS
));
669 CopyMem (&UdpConfig
.RemoteAddress
, &Instance
->SessionDnsServer
.v4
, sizeof (EFI_IPv4_ADDRESS
));
671 Status
= UdpIo
->Protocol
.Udp4
->Configure (UdpIo
->Protocol
.Udp4
, &UdpConfig
);
673 if ((Status
== EFI_NO_MAPPING
) && Dns4GetMapping (Instance
, UdpIo
, &UdpConfig
)) {
683 @param Instance The DNS session
684 @param UdpIo The UDP_IO instance
686 @retval EFI_SUCCESS The UDP is successfully configured for the
692 IN DNS_INSTANCE
*Instance
,
696 EFI_DNS6_CONFIG_DATA
*Config
;
697 EFI_UDP6_CONFIG_DATA UdpConfig
;
700 Config
= &Instance
->Dns6CfgData
;
702 UdpConfig
.AcceptPromiscuous
= FALSE
;
703 UdpConfig
.AcceptAnyPort
= FALSE
;
704 UdpConfig
.AllowDuplicatePort
= FALSE
;
705 UdpConfig
.TrafficClass
= 0;
706 UdpConfig
.HopLimit
= 128;
707 UdpConfig
.ReceiveTimeout
= 0;
708 UdpConfig
.TransmitTimeout
= 0;
709 UdpConfig
.StationPort
= Config
->LocalPort
;
710 UdpConfig
.RemotePort
= DNS_SERVER_PORT
;
711 CopyMem (&UdpConfig
.StationAddress
, &Config
->StationIp
, sizeof (EFI_IPv6_ADDRESS
));
712 CopyMem (&UdpConfig
.RemoteAddress
, &Instance
->SessionDnsServer
.v6
, sizeof (EFI_IPv6_ADDRESS
));
714 Status
= UdpIo
->Protocol
.Udp6
->Configure (UdpIo
->Protocol
.Udp6
, &UdpConfig
);
716 if ((Status
== EFI_NO_MAPPING
) && Dns6GetMapping (Instance
, UdpIo
, &UdpConfig
)) {
724 Update Dns4 cache to shared list of caches of all DNSv4 instances.
726 @param Dns4CacheList All Dns4 cache list.
727 @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
728 If TRUE, this function will delete matching DNS Cache entry.
729 @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
730 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
731 @param DnsCacheEntry Entry Pointer to DNS Cache entry.
733 @retval EFI_SUCCESS Update Dns4 cache successfully.
734 @retval Others Failed to update Dns4 cache.
740 IN LIST_ENTRY
*Dns4CacheList
,
741 IN BOOLEAN DeleteFlag
,
743 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry
746 DNS4_CACHE
*NewDnsCache
;
755 // Search the database for the matching EFI_DNS_CACHE_ENTRY
757 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns4CacheList
) {
758 Item
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
759 if (StrCmp (DnsCacheEntry
.HostName
, Item
->DnsCache
.HostName
) == 0 && \
760 CompareMem (DnsCacheEntry
.IpAddress
, Item
->DnsCache
.IpAddress
, sizeof (EFI_IPv4_ADDRESS
)) == 0) {
762 // This is the Dns cache entry
766 // Delete matching DNS Cache entry
768 RemoveEntryList (&Item
->AllCacheLink
);
771 } else if (Override
) {
775 Item
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
779 return EFI_ACCESS_DENIED
;
787 NewDnsCache
= AllocatePool (sizeof (DNS4_CACHE
));
788 if (NewDnsCache
== NULL
) {
789 return EFI_OUT_OF_RESOURCES
;
792 InitializeListHead (&NewDnsCache
->AllCacheLink
);
794 NewDnsCache
->DnsCache
.HostName
= AllocatePool (StrSize (DnsCacheEntry
.HostName
));
795 if (NewDnsCache
->DnsCache
.HostName
== NULL
) {
796 return EFI_OUT_OF_RESOURCES
;
799 CopyMem (NewDnsCache
->DnsCache
.HostName
, DnsCacheEntry
.HostName
, StrSize (DnsCacheEntry
.HostName
));
801 NewDnsCache
->DnsCache
.IpAddress
= AllocatePool (sizeof (EFI_IPv4_ADDRESS
));
802 if (NewDnsCache
->DnsCache
.IpAddress
== NULL
) {
803 return EFI_OUT_OF_RESOURCES
;
806 CopyMem (NewDnsCache
->DnsCache
.IpAddress
, DnsCacheEntry
.IpAddress
, sizeof (EFI_IPv4_ADDRESS
));
808 NewDnsCache
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
810 InsertTailList (Dns4CacheList
, &NewDnsCache
->AllCacheLink
);
816 Update Dns6 cache to shared list of caches of all DNSv6 instances.
818 @param Dns6CacheList All Dns6 cache list.
819 @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
820 If TRUE, this function will delete matching DNS Cache entry.
821 @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
822 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
823 @param DnsCacheEntry Entry Pointer to DNS Cache entry.
825 @retval EFI_SUCCESS Update Dns6 cache successfully.
826 @retval Others Failed to update Dns6 cache.
831 IN LIST_ENTRY
*Dns6CacheList
,
832 IN BOOLEAN DeleteFlag
,
834 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry
837 DNS6_CACHE
*NewDnsCache
;
846 // Search the database for the matching EFI_DNS_CACHE_ENTRY
848 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns6CacheList
) {
849 Item
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
850 if (StrCmp (DnsCacheEntry
.HostName
, Item
->DnsCache
.HostName
) == 0 && \
851 CompareMem (DnsCacheEntry
.IpAddress
, Item
->DnsCache
.IpAddress
, sizeof (EFI_IPv6_ADDRESS
)) == 0) {
853 // This is the Dns cache entry
857 // Delete matching DNS Cache entry
859 RemoveEntryList (&Item
->AllCacheLink
);
862 } else if (Override
) {
866 Item
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
870 return EFI_ACCESS_DENIED
;
878 NewDnsCache
= AllocatePool (sizeof (DNS6_CACHE
));
879 if (NewDnsCache
== NULL
) {
880 return EFI_OUT_OF_RESOURCES
;
883 InitializeListHead (&NewDnsCache
->AllCacheLink
);
885 NewDnsCache
->DnsCache
.HostName
= AllocatePool (StrSize (DnsCacheEntry
.HostName
));
886 if (NewDnsCache
->DnsCache
.HostName
== NULL
) {
887 return EFI_OUT_OF_RESOURCES
;
890 CopyMem (NewDnsCache
->DnsCache
.HostName
, DnsCacheEntry
.HostName
, StrSize (DnsCacheEntry
.HostName
));
892 NewDnsCache
->DnsCache
.IpAddress
= AllocatePool (sizeof (EFI_IPv6_ADDRESS
));
893 if (NewDnsCache
->DnsCache
.IpAddress
== NULL
) {
894 return EFI_OUT_OF_RESOURCES
;
897 CopyMem (NewDnsCache
->DnsCache
.IpAddress
, DnsCacheEntry
.IpAddress
, sizeof (EFI_IPv6_ADDRESS
));
899 NewDnsCache
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
901 InsertTailList (Dns6CacheList
, &NewDnsCache
->AllCacheLink
);
907 Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.
909 @param Dns4ServerList Common list of addresses of all configured DNSv4 server.
910 @param ServerIp DNS server Ip.
912 @retval EFI_SUCCESS Add Dns4 ServerIp to common list successfully.
913 @retval Others Failed to add Dns4 ServerIp to common list.
919 IN LIST_ENTRY
*Dns4ServerList
,
920 IN EFI_IPv4_ADDRESS ServerIp
923 DNS4_SERVER_IP
*NewServerIp
;
924 DNS4_SERVER_IP
*Item
;
932 // Search the database for the matching ServerIp
934 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns4ServerList
) {
935 Item
= NET_LIST_USER_STRUCT (Entry
, DNS4_SERVER_IP
, AllServerLink
);
936 if (CompareMem (&Item
->Dns4ServerIp
, &ServerIp
, sizeof (EFI_IPv4_ADDRESS
)) == 0) {
947 NewServerIp
= AllocatePool (sizeof (DNS4_SERVER_IP
));
948 if (NewServerIp
== NULL
) {
949 return EFI_OUT_OF_RESOURCES
;
952 InitializeListHead (&NewServerIp
->AllServerLink
);
954 CopyMem (&NewServerIp
->Dns4ServerIp
, &ServerIp
, sizeof (EFI_IPv4_ADDRESS
));
956 InsertTailList (Dns4ServerList
, &NewServerIp
->AllServerLink
);
962 Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.
964 @param Dns6ServerList Common list of addresses of all configured DNSv6 server.
965 @param ServerIp DNS server Ip.
967 @retval EFI_SUCCESS Add Dns6 ServerIp to common list successfully.
968 @retval Others Failed to add Dns6 ServerIp to common list.
974 IN LIST_ENTRY
*Dns6ServerList
,
975 IN EFI_IPv6_ADDRESS ServerIp
978 DNS6_SERVER_IP
*NewServerIp
;
979 DNS6_SERVER_IP
*Item
;
987 // Search the database for the matching ServerIp
989 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns6ServerList
) {
990 Item
= NET_LIST_USER_STRUCT (Entry
, DNS6_SERVER_IP
, AllServerLink
);
991 if (CompareMem (&Item
->Dns6ServerIp
, &ServerIp
, sizeof (EFI_IPv6_ADDRESS
)) == 0) {
1002 NewServerIp
= AllocatePool (sizeof (DNS6_SERVER_IP
));
1003 if (NewServerIp
== NULL
) {
1004 return EFI_OUT_OF_RESOURCES
;
1007 InitializeListHead (&NewServerIp
->AllServerLink
);
1009 CopyMem (&NewServerIp
->Dns6ServerIp
, &ServerIp
, sizeof (EFI_IPv6_ADDRESS
));
1011 InsertTailList (Dns6ServerList
, &NewServerIp
->AllServerLink
);
1017 Fill QName for IP querying. QName is a domain name represented as
1018 a sequence of labels, where each label consists of a length octet
1019 followed by that number of octets. The domain name terminates with
1020 the zero length octet for the null label of the root. Caller should
1021 take responsibility to the buffer in QName.
1023 @param HostName Queried HostName
1025 @retval NULL Failed to fill QName.
1026 @return QName filled successfully.
1031 DnsFillinQNameForQueryIp (
1045 QueryName
= AllocateZeroPool (DNS_DEFAULT_BLKSIZE
);
1046 if (QueryName
== NULL
) {
1053 for (Index
= 0; HostName
[Index
] != 0; Index
++) {
1054 *Tail
= (CHAR8
) HostName
[Index
];
1056 *Header
= (CHAR8
) Len
;
1065 *Header
= (CHAR8
) Len
;
1072 Find out whether the response is valid or invalid.
1074 @param TokensMap All DNS transmittal Tokens entry.
1075 @param Identification Identification for queried packet.
1076 @param Type Type for queried packet.
1077 @param Item Return corresponding Token entry.
1079 @retval TRUE The response is valid.
1080 @retval FALSE The response is invalid.
1084 IsValidDnsResponse (
1085 IN NET_MAP
*TokensMap
,
1086 IN UINT16 Identification
,
1088 OUT NET_MAP_ITEM
**Item
1095 DNS_HEADER
*DnsHeader
;
1097 DNS_QUERY_SECTION
*QuerySection
;
1099 NET_LIST_FOR_EACH (Entry
, &TokensMap
->Used
) {
1100 *Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
1101 Packet
= (NET_BUF
*) ((*Item
)->Value
);
1102 if (Packet
== NULL
){
1106 TxString
= NetbufGetByte (Packet
, 0, NULL
);
1107 ASSERT (TxString
!= NULL
);
1108 DnsHeader
= (DNS_HEADER
*) TxString
;
1109 QueryName
= (CHAR8
*) (TxString
+ sizeof (*DnsHeader
));
1110 QuerySection
= (DNS_QUERY_SECTION
*) (QueryName
+ AsciiStrLen (QueryName
) + 1);
1112 DnsHeader
->Identification
= NTOHS (DnsHeader
->Identification
);
1113 QuerySection
->Type
= NTOHS (QuerySection
->Type
);
1115 if (DnsHeader
->Identification
== Identification
&& QuerySection
->Type
== Type
) {
1129 @param Instance The DNS instance
1130 @param RxString Received buffer.
1131 @param Completed Flag to indicate that Dns response is valid.
1133 @retval EFI_SUCCESS Parse Dns Response successfully.
1134 @retval Others Failed to parse Dns Response.
1139 IN OUT DNS_INSTANCE
*Instance
,
1141 OUT BOOLEAN
*Completed
1144 DNS_HEADER
*DnsHeader
;
1147 DNS_QUERY_SECTION
*QuerySection
;
1150 DNS_ANSWER_SECTION
*AnswerSection
;
1154 DNS4_TOKEN_ENTRY
*Dns4TokenEntry
;
1155 DNS6_TOKEN_ENTRY
*Dns6TokenEntry
;
1159 UINT32 AnswerSectionNum
;
1161 EFI_IPv4_ADDRESS
*HostAddr4
;
1162 EFI_IPv6_ADDRESS
*HostAddr6
;
1164 EFI_DNS4_CACHE_ENTRY
*Dns4CacheEntry
;
1165 EFI_DNS6_CACHE_ENTRY
*Dns6CacheEntry
;
1167 DNS_RESOURCE_RECORD
*Dns4RR
;
1168 DNS6_RESOURCE_RECORD
*Dns6RR
;
1175 Dns4TokenEntry
= NULL
;
1176 Dns6TokenEntry
= NULL
;
1180 AnswerSectionNum
= 0;
1185 Dns4CacheEntry
= NULL
;
1186 Dns6CacheEntry
= NULL
;
1192 Status
= EFI_SUCCESS
;
1197 DnsHeader
= (DNS_HEADER
*) RxString
;
1199 DnsHeader
->Identification
= NTOHS (DnsHeader
->Identification
);
1200 DnsHeader
->Flags
.Uint16
= NTOHS (DnsHeader
->Flags
.Uint16
);
1201 DnsHeader
->QuestionsNum
= NTOHS (DnsHeader
->QuestionsNum
);
1202 DnsHeader
->AnswersNum
= NTOHS (DnsHeader
->AnswersNum
);
1203 DnsHeader
->AuthorityNum
= NTOHS (DnsHeader
->AuthorityNum
);
1204 DnsHeader
->AditionalNum
= NTOHS (DnsHeader
->AditionalNum
);
1209 QueryName
= (CHAR8
*) (RxString
+ sizeof (*DnsHeader
));
1212 // Get query section
1214 QuerySection
= (DNS_QUERY_SECTION
*) (QueryName
+ AsciiStrLen (QueryName
) + 1);
1215 QuerySection
->Type
= NTOHS (QuerySection
->Type
);
1216 QuerySection
->Class
= NTOHS (QuerySection
->Class
);
1221 AnswerName
= (CHAR8
*) QuerySection
+ sizeof (*QuerySection
);
1223 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1226 // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.
1228 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1229 if (!IsValidDnsResponse (&Instance
->Dns4TxTokens
, DnsHeader
->Identification
, QuerySection
->Type
, &Item
)) {
1231 Status
= EFI_ABORTED
;
1234 ASSERT (Item
!= NULL
);
1235 Dns4TokenEntry
= (DNS4_TOKEN_ENTRY
*) (Item
->Key
);
1237 if (!IsValidDnsResponse (&Instance
->Dns6TxTokens
, DnsHeader
->Identification
, QuerySection
->Type
, &Item
)) {
1239 Status
= EFI_ABORTED
;
1242 ASSERT (Item
!= NULL
);
1243 Dns6TokenEntry
= (DNS6_TOKEN_ENTRY
*) (Item
->Key
);
1247 // Continue Check Some Errors.
1249 if (DnsHeader
->Flags
.Bits
.RCode
!= DNS_FLAGS_RCODE_NO_ERROR
|| DnsHeader
->AnswersNum
< 1 || \
1250 DnsHeader
->Flags
.Bits
.QR
!= DNS_FLAGS_QR_RESPONSE
|| QuerySection
->Class
!= DNS_CLASS_INET
) {
1251 Status
= EFI_ABORTED
;
1256 // Free the sending packet.
1258 if (Item
->Value
!= NULL
) {
1259 NetbufFree ((NET_BUF
*) (Item
->Value
));
1263 // Do some buffer allocations.
1265 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1266 ASSERT (Dns4TokenEntry
!= NULL
);
1268 if (Dns4TokenEntry
->GeneralLookUp
) {
1270 // It's the GeneralLookUp querying.
1272 Dns4TokenEntry
->Token
->RspData
.GLookupData
= AllocatePool (sizeof (DNS_RESOURCE_RECORD
));
1273 if (Dns4TokenEntry
->Token
->RspData
.GLookupData
== NULL
) {
1274 Status
= EFI_OUT_OF_RESOURCES
;
1277 Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (DNS_RESOURCE_RECORD
));
1278 if (Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRList
== NULL
) {
1279 Status
= EFI_OUT_OF_RESOURCES
;
1284 // It's not the GeneralLookUp querying. Check the Query type.
1286 if (QuerySection
->Type
== DNS_TYPE_A
) {
1287 Dns4TokenEntry
->Token
->RspData
.H2AData
= AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA
));
1288 if (Dns4TokenEntry
->Token
->RspData
.H2AData
== NULL
) {
1289 Status
= EFI_OUT_OF_RESOURCES
;
1292 Dns4TokenEntry
->Token
->RspData
.H2AData
->IpList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (EFI_IPv4_ADDRESS
));
1293 if (Dns4TokenEntry
->Token
->RspData
.H2AData
->IpList
== NULL
) {
1294 Status
= EFI_OUT_OF_RESOURCES
;
1298 Status
= EFI_UNSUPPORTED
;
1303 ASSERT (Dns6TokenEntry
!= NULL
);
1305 if (Dns6TokenEntry
->GeneralLookUp
) {
1307 // It's the GeneralLookUp querying.
1309 Dns6TokenEntry
->Token
->RspData
.GLookupData
= AllocatePool (sizeof (DNS_RESOURCE_RECORD
));
1310 if (Dns6TokenEntry
->Token
->RspData
.GLookupData
== NULL
) {
1311 Status
= EFI_UNSUPPORTED
;
1314 Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (DNS_RESOURCE_RECORD
));
1315 if (Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRList
== NULL
) {
1316 Status
= EFI_UNSUPPORTED
;
1321 // It's not the GeneralLookUp querying. Check the Query type.
1323 if (QuerySection
->Type
== DNS_TYPE_AAAA
) {
1324 Dns6TokenEntry
->Token
->RspData
.H2AData
= AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA
));
1325 if (Dns6TokenEntry
->Token
->RspData
.H2AData
== NULL
) {
1326 Status
= EFI_UNSUPPORTED
;
1329 Dns6TokenEntry
->Token
->RspData
.H2AData
->IpList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (EFI_IPv6_ADDRESS
));
1330 if (Dns6TokenEntry
->Token
->RspData
.H2AData
->IpList
== NULL
) {
1331 Status
= EFI_UNSUPPORTED
;
1335 Status
= EFI_UNSUPPORTED
;
1342 // Processing AnswerSection.
1344 while (AnswerSectionNum
< DnsHeader
->AnswersNum
) {
1346 // Answer name should be PTR.
1348 ASSERT ((*(UINT8
*) AnswerName
& 0xC0) == 0xC0);
1351 // Get Answer section.
1353 AnswerSection
= (DNS_ANSWER_SECTION
*) (AnswerName
+ sizeof (UINT16
));
1354 AnswerSection
->Type
= NTOHS (AnswerSection
->Type
);
1355 AnswerSection
->Class
= NTOHS (AnswerSection
->Class
);
1356 AnswerSection
->Ttl
= NTOHL (AnswerSection
->Ttl
);
1357 AnswerSection
->DataLength
= NTOHS (AnswerSection
->DataLength
);
1360 // Check whether it's the GeneralLookUp querying.
1362 if (Instance
->Service
->IpVersion
== IP_VERSION_4
&& Dns4TokenEntry
->GeneralLookUp
) {
1363 ASSERT (Dns4TokenEntry
!= NULL
);
1365 Dns4RR
= Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRList
;
1366 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1369 // Fill the ResourceRecord.
1371 Dns4RR
[RRCount
].QName
= AllocateZeroPool (AsciiStrLen (QueryName
) + 1);
1372 if (Dns4RR
[RRCount
].QName
== NULL
) {
1373 Status
= EFI_UNSUPPORTED
;
1376 CopyMem (Dns4RR
[RRCount
].QName
, QueryName
, AsciiStrLen (QueryName
));
1377 Dns4RR
[RRCount
].QType
= AnswerSection
->Type
;
1378 Dns4RR
[RRCount
].QClass
= AnswerSection
->Class
;
1379 Dns4RR
[RRCount
].TTL
= AnswerSection
->Ttl
;
1380 Dns4RR
[RRCount
].DataLength
= AnswerSection
->DataLength
;
1381 Dns4RR
[RRCount
].RData
= AllocateZeroPool (Dns4RR
[RRCount
].DataLength
);
1382 if (Dns4RR
[RRCount
].RData
== NULL
) {
1383 Status
= EFI_UNSUPPORTED
;
1386 CopyMem (Dns4RR
[RRCount
].RData
, AnswerData
, Dns4RR
[RRCount
].DataLength
);
1389 } else if (Instance
->Service
->IpVersion
== IP_VERSION_6
&& Dns6TokenEntry
->GeneralLookUp
) {
1390 ASSERT (Dns6TokenEntry
!= NULL
);
1392 Dns6RR
= Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRList
;
1393 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1396 // Fill the ResourceRecord.
1398 Dns6RR
[RRCount
].QName
= AllocateZeroPool (AsciiStrLen (QueryName
) + 1);
1399 if (Dns6RR
[RRCount
].QName
== NULL
) {
1400 Status
= EFI_UNSUPPORTED
;
1403 CopyMem (Dns6RR
[RRCount
].QName
, QueryName
, AsciiStrLen (QueryName
));
1404 Dns6RR
[RRCount
].QType
= AnswerSection
->Type
;
1405 Dns6RR
[RRCount
].QClass
= AnswerSection
->Class
;
1406 Dns6RR
[RRCount
].TTL
= AnswerSection
->Ttl
;
1407 Dns6RR
[RRCount
].DataLength
= AnswerSection
->DataLength
;
1408 Dns6RR
[RRCount
].RData
= AllocateZeroPool (Dns6RR
[RRCount
].DataLength
);
1409 if (Dns6RR
[RRCount
].RData
== NULL
) {
1410 Status
= EFI_UNSUPPORTED
;
1413 CopyMem (Dns6RR
[RRCount
].RData
, AnswerData
, Dns6RR
[RRCount
].DataLength
);
1418 // It's not the GeneralLookUp querying.
1419 // Check the Query type, parse the response packet.
1421 switch (AnswerSection
->Type
) {
1424 // This is address entry, get Data.
1426 ASSERT (Dns4TokenEntry
!= NULL
&& AnswerSection
->DataLength
== 4);
1428 HostAddr4
= Dns4TokenEntry
->Token
->RspData
.H2AData
->IpList
;
1429 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1430 CopyMem (&HostAddr4
[IpCount
], AnswerData
, sizeof (EFI_IPv4_ADDRESS
));
1433 // Update DNS cache dynamically.
1435 if (Dns4CacheEntry
!= NULL
) {
1436 if (Dns4CacheEntry
->HostName
!= NULL
) {
1437 FreePool (Dns4CacheEntry
->HostName
);
1440 if (Dns4CacheEntry
->IpAddress
!= NULL
) {
1441 FreePool (Dns4CacheEntry
->IpAddress
);
1444 FreePool (Dns4CacheEntry
);
1448 // Allocate new CacheEntry pool.
1450 Dns4CacheEntry
= AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY
));
1451 if (Dns4CacheEntry
== NULL
) {
1452 Status
= EFI_UNSUPPORTED
;
1455 Dns4CacheEntry
->HostName
= AllocateZeroPool (2 * (StrLen(Dns4TokenEntry
->QueryHostName
) + 1));
1456 if (Dns4CacheEntry
->HostName
== NULL
) {
1457 Status
= EFI_UNSUPPORTED
;
1460 CopyMem (Dns4CacheEntry
->HostName
, Dns4TokenEntry
->QueryHostName
, 2 * (StrLen(Dns4TokenEntry
->QueryHostName
) + 1));
1461 Dns4CacheEntry
->IpAddress
= AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS
));
1462 if (Dns4CacheEntry
->IpAddress
== NULL
) {
1463 Status
= EFI_UNSUPPORTED
;
1466 CopyMem (Dns4CacheEntry
->IpAddress
, AnswerData
, sizeof (EFI_IPv4_ADDRESS
));
1467 Dns4CacheEntry
->Timeout
= AnswerSection
->Ttl
;
1469 UpdateDns4Cache (&mDriverData
->Dns4CacheList
, FALSE
, TRUE
, *Dns4CacheEntry
);
1475 // This is address entry, get Data.
1477 ASSERT (Dns6TokenEntry
!= NULL
&& AnswerSection
->DataLength
== 16);
1479 HostAddr6
= Dns6TokenEntry
->Token
->RspData
.H2AData
->IpList
;
1480 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1481 CopyMem (&HostAddr6
[IpCount
], AnswerData
, sizeof (EFI_IPv6_ADDRESS
));
1484 // Update DNS cache dynamically.
1486 if (Dns6CacheEntry
!= NULL
) {
1487 if (Dns6CacheEntry
->HostName
!= NULL
) {
1488 FreePool (Dns6CacheEntry
->HostName
);
1491 if (Dns6CacheEntry
->IpAddress
!= NULL
) {
1492 FreePool (Dns6CacheEntry
->IpAddress
);
1495 FreePool (Dns6CacheEntry
);
1499 // Allocate new CacheEntry pool.
1501 Dns6CacheEntry
= AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY
));
1502 if (Dns6CacheEntry
== NULL
) {
1503 Status
= EFI_UNSUPPORTED
;
1506 Dns6CacheEntry
->HostName
= AllocateZeroPool (2 * (StrLen(Dns6TokenEntry
->QueryHostName
) + 1));
1507 if (Dns6CacheEntry
->HostName
== NULL
) {
1508 Status
= EFI_UNSUPPORTED
;
1511 CopyMem (Dns6CacheEntry
->HostName
, Dns6TokenEntry
->QueryHostName
, 2 * (StrLen(Dns6TokenEntry
->QueryHostName
) + 1));
1512 Dns6CacheEntry
->IpAddress
= AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS
));
1513 if (Dns6CacheEntry
->IpAddress
== NULL
) {
1514 Status
= EFI_UNSUPPORTED
;
1517 CopyMem (Dns6CacheEntry
->IpAddress
, AnswerData
, sizeof (EFI_IPv6_ADDRESS
));
1518 Dns6CacheEntry
->Timeout
= AnswerSection
->Ttl
;
1520 UpdateDns6Cache (&mDriverData
->Dns6CacheList
, FALSE
, TRUE
, *Dns6CacheEntry
);
1525 Status
= EFI_UNSUPPORTED
;
1533 AnswerName
= (CHAR8
*) AnswerSection
+ sizeof (*AnswerSection
) + AnswerSection
->DataLength
;
1534 AnswerSectionNum
++;
1537 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1538 ASSERT (Dns4TokenEntry
!= NULL
);
1540 if (Dns4TokenEntry
->GeneralLookUp
) {
1541 Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRCount
= RRCount
;
1543 if (QuerySection
->Type
== DNS_TYPE_A
) {
1544 Dns4TokenEntry
->Token
->RspData
.H2AData
->IpCount
= IpCount
;
1546 Status
= EFI_UNSUPPORTED
;
1551 ASSERT (Dns6TokenEntry
!= NULL
);
1553 if (Dns6TokenEntry
->GeneralLookUp
) {
1554 Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRCount
= RRCount
;
1556 if (QuerySection
->Type
== DNS_TYPE_AAAA
) {
1557 Dns6TokenEntry
->Token
->RspData
.H2AData
->IpCount
= IpCount
;
1559 Status
= EFI_UNSUPPORTED
;
1566 // Parsing is complete, SignalEvent here.
1568 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1569 ASSERT (Dns4TokenEntry
!= NULL
);
1570 Dns4RemoveTokenEntry (&Instance
->Dns4TxTokens
, Dns4TokenEntry
);
1571 Dns4TokenEntry
->Token
->Status
= EFI_SUCCESS
;
1572 if (Dns4TokenEntry
->Token
->Event
!= NULL
) {
1573 gBS
->SignalEvent (Dns4TokenEntry
->Token
->Event
);
1577 ASSERT (Dns6TokenEntry
!= NULL
);
1578 Dns6RemoveTokenEntry (&Instance
->Dns6TxTokens
, Dns6TokenEntry
);
1579 Dns6TokenEntry
->Token
->Status
= EFI_SUCCESS
;
1580 if (Dns6TokenEntry
->Token
->Event
!= NULL
) {
1581 gBS
->SignalEvent (Dns6TokenEntry
->Token
->Event
);
1587 // Free allocated CacheEntry pool.
1589 if (Dns4CacheEntry
!= NULL
) {
1590 if (Dns4CacheEntry
->HostName
!= NULL
) {
1591 FreePool (Dns4CacheEntry
->HostName
);
1594 if (Dns4CacheEntry
->IpAddress
!= NULL
) {
1595 FreePool (Dns4CacheEntry
->IpAddress
);
1598 FreePool (Dns4CacheEntry
);
1601 if (Dns6CacheEntry
!= NULL
) {
1602 if (Dns6CacheEntry
->HostName
!= NULL
) {
1603 FreePool (Dns6CacheEntry
->HostName
);
1606 if (Dns6CacheEntry
->IpAddress
!= NULL
) {
1607 FreePool (Dns6CacheEntry
->IpAddress
);
1610 FreePool (Dns6CacheEntry
);
1614 gBS
->RestoreTPL (OldTpl
);
1619 Parse response packet.
1621 @param Packet The packets received.
1622 @param EndPoint The local/remote UDP access point
1623 @param IoStatus The status of the UDP receive
1624 @param Context The opaque parameter to the function.
1629 DnsOnPacketReceived (
1631 UDP_END_POINT
*EndPoint
,
1632 EFI_STATUS IoStatus
,
1636 DNS_INSTANCE
*Instance
;
1642 Instance
= (DNS_INSTANCE
*) Context
;
1643 NET_CHECK_SIGNATURE (Instance
, DNS_INSTANCE_SIGNATURE
);
1648 if (EFI_ERROR (IoStatus
)) {
1652 ASSERT (Packet
!= NULL
);
1654 RcvString
= NetbufGetByte (Packet
, 0, NULL
);
1655 ASSERT (RcvString
!= NULL
);
1658 // Parse Dns Response
1660 ParseDnsResponse (Instance
, RcvString
, &Completed
);
1664 if (Packet
!= NULL
) {
1665 NetbufFree (Packet
);
1669 UdpIoRecvDatagram (Instance
->UdpIo
, DnsOnPacketReceived
, Instance
, 0);
1674 Release the net buffer when packet is sent.
1676 @param Packet The packets received.
1677 @param EndPoint The local/remote UDP access point
1678 @param IoStatus The status of the UDP receive
1679 @param Context The opaque parameter to the function.
1686 UDP_END_POINT
*EndPoint
,
1687 EFI_STATUS IoStatus
,
1691 DNS_INSTANCE
*Instance
;
1694 DNS4_TOKEN_ENTRY
*Dns4TokenEntry
;
1695 DNS6_TOKEN_ENTRY
*Dns6TokenEntry
;
1697 Dns4TokenEntry
= NULL
;
1698 Dns6TokenEntry
= NULL
;
1700 Instance
= (DNS_INSTANCE
*) Context
;
1701 NET_CHECK_SIGNATURE (Instance
, DNS_INSTANCE_SIGNATURE
);
1703 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1704 NET_LIST_FOR_EACH (Entry
, &Instance
->Dns4TxTokens
.Used
) {
1705 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
1706 if (Packet
== (NET_BUF
*)(Item
->Value
)) {
1707 Dns4TokenEntry
= ((DNS4_TOKEN_ENTRY
*)Item
->Key
);
1708 Dns4TokenEntry
->PacketToLive
= Dns4TokenEntry
->Token
->RetryInterval
;
1713 NET_LIST_FOR_EACH (Entry
, &Instance
->Dns6TxTokens
.Used
) {
1714 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
1715 if (Packet
== (NET_BUF
*)(Item
->Value
)) {
1716 Dns6TokenEntry
= ((DNS6_TOKEN_ENTRY
*)Item
->Key
);
1717 Dns6TokenEntry
->PacketToLive
= Dns6TokenEntry
->Token
->RetryInterval
;
1723 NetbufFree (Packet
);
1727 Query request information.
1729 @param Instance The DNS instance
1730 @param Packet The packet for querying request information.
1732 @retval EFI_SUCCESS Query request information successfully.
1733 @retval Others Failed to query request information.
1738 IN DNS_INSTANCE
*Instance
,
1745 // Ready to receive the DNS response.
1747 if (Instance
->UdpIo
->RecvRequest
== NULL
) {
1748 Status
= UdpIoRecvDatagram (Instance
->UdpIo
, DnsOnPacketReceived
, Instance
, 0);
1749 if (EFI_ERROR (Status
)) {
1755 // Transmit the DNS packet.
1757 NET_GET_REF (Packet
);
1759 Status
= UdpIoSendDatagram (Instance
->UdpIo
, Packet
, NULL
, NULL
, DnsOnPacketSent
, Instance
);
1765 Construct the Packet according query section.
1767 @param Instance The DNS instance
1768 @param QueryName Queried Name
1769 @param Type Queried Type
1770 @param Class Queried Class
1771 @param Packet The packet for query
1773 @retval EFI_SUCCESS The packet is constructed.
1774 @retval Others Failed to construct the Packet.
1779 IN DNS_INSTANCE
*Instance
,
1780 IN CHAR8
*QueryName
,
1783 OUT NET_BUF
**Packet
1787 DNS_HEADER
*DnsHeader
;
1788 DNS_QUERY_SECTION
*DnsQuery
;
1790 Frag
.Bulk
= AllocatePool (DNS_DEFAULT_BLKSIZE
* sizeof (UINT8
));
1791 if (Frag
.Bulk
== NULL
) {
1792 return EFI_OUT_OF_RESOURCES
;
1798 DnsHeader
= (DNS_HEADER
*) Frag
.Bulk
;
1799 DnsHeader
->Identification
= (UINT16
)NET_RANDOM (NetRandomInitSeed());
1800 DnsHeader
->Flags
.Uint16
= 0x0000;
1801 DnsHeader
->Flags
.Bits
.RD
= 1;
1802 DnsHeader
->Flags
.Bits
.OpCode
= DNS_FLAGS_OPCODE_STANDARD
;
1803 DnsHeader
->Flags
.Bits
.QR
= DNS_FLAGS_QR_QUERY
;
1804 DnsHeader
->QuestionsNum
= 1;
1805 DnsHeader
->AnswersNum
= 0;
1806 DnsHeader
->AuthorityNum
= 0;
1807 DnsHeader
->AditionalNum
= 0;
1809 DnsHeader
->Identification
= HTONS (DnsHeader
->Identification
);
1810 DnsHeader
->Flags
.Uint16
= HTONS (DnsHeader
->Flags
.Uint16
);
1811 DnsHeader
->QuestionsNum
= HTONS (DnsHeader
->QuestionsNum
);
1812 DnsHeader
->AnswersNum
= HTONS (DnsHeader
->AnswersNum
);
1813 DnsHeader
->AuthorityNum
= HTONS (DnsHeader
->AuthorityNum
);
1814 DnsHeader
->AditionalNum
= HTONS (DnsHeader
->AditionalNum
);
1816 Frag
.Len
= sizeof (*DnsHeader
);
1821 CopyMem (Frag
.Bulk
+ Frag
.Len
, QueryName
, AsciiStrLen (QueryName
));
1822 Frag
.Len
= (UINT32
) (Frag
.Len
+ AsciiStrLen (QueryName
));
1823 *(Frag
.Bulk
+ Frag
.Len
) = 0;
1827 // Rest query section
1829 DnsQuery
= (DNS_QUERY_SECTION
*) (Frag
.Bulk
+ Frag
.Len
);
1831 DnsQuery
->Type
= HTONS (Type
);
1832 DnsQuery
->Class
= HTONS (Class
);
1834 Frag
.Len
+= sizeof (*DnsQuery
);
1837 // Wrap the Frag in a net buffer.
1839 *Packet
= NetbufFromExt (&Frag
, 1, 0, 0, DnsDummyExtFree
, NULL
);
1840 if (*Packet
== NULL
) {
1841 FreePool (Frag
.Bulk
);
1842 return EFI_OUT_OF_RESOURCES
;
1846 // Store the UdpIo in ProtoData.
1848 *((UINTN
*) &((*Packet
)->ProtoData
[0])) = (UINTN
) (Instance
->UdpIo
);
1854 Retransmit the packet.
1856 @param Instance The DNS instance
1857 @param Packet Retransmit the packet
1859 @retval EFI_SUCCESS The packet is retransmitted.
1860 @retval Others Failed to retransmit.
1865 IN DNS_INSTANCE
*Instance
,
1873 ASSERT (Packet
!= NULL
);
1876 // Set the requests to the listening port, other packets to the connected port
1878 Buffer
= NetbufGetByte (Packet
, 0, NULL
);
1879 ASSERT (Buffer
!= NULL
);
1881 NET_GET_REF (Packet
);
1883 Status
= UdpIoSendDatagram (
1892 if (EFI_ERROR (Status
)) {
1893 NET_PUT_REF (Packet
);
1900 The timer ticking function for the DNS services.
1902 @param Event The ticking event
1903 @param Context The DNS service instance
1908 DnsOnTimerRetransmit (
1913 DNS_SERVICE
*Service
;
1918 DNS_INSTANCE
*Instance
;
1919 LIST_ENTRY
*EntryNetMap
;
1920 NET_MAP_ITEM
*ItemNetMap
;
1921 DNS4_TOKEN_ENTRY
*Dns4TokenEntry
;
1922 DNS6_TOKEN_ENTRY
*Dns6TokenEntry
;
1924 Dns4TokenEntry
= NULL
;
1925 Dns6TokenEntry
= NULL
;
1927 Service
= (DNS_SERVICE
*) Context
;
1930 if (Service
->IpVersion
== IP_VERSION_4
) {
1932 // Iterate through all the children of the DNS service instance. Time
1933 // out the packet. If maximum retries reached, clean the Token up.
1935 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Service
->Dns4ChildrenList
) {
1936 Instance
= NET_LIST_USER_STRUCT (Entry
, DNS_INSTANCE
, Link
);
1938 EntryNetMap
= Instance
->Dns4TxTokens
.Used
.ForwardLink
;
1939 while (EntryNetMap
!= &Instance
->Dns4TxTokens
.Used
) {
1940 ItemNetMap
= NET_LIST_USER_STRUCT (EntryNetMap
, NET_MAP_ITEM
, Link
);
1941 Dns4TokenEntry
= (DNS4_TOKEN_ENTRY
*)(ItemNetMap
->Key
);
1942 if (Dns4TokenEntry
->PacketToLive
== 0 || (--Dns4TokenEntry
->PacketToLive
> 0)) {
1943 EntryNetMap
= EntryNetMap
->ForwardLink
;
1948 // Retransmit the packet if haven't reach the maxmium retry count,
1949 // otherwise exit the transfer.
1951 if (++Dns4TokenEntry
->Token
->RetryCount
< Instance
->MaxRetry
) {
1952 DnsRetransmit (Instance
, (NET_BUF
*)ItemNetMap
->Value
);
1953 EntryNetMap
= EntryNetMap
->ForwardLink
;
1956 // Maximum retries reached, clean the Token up.
1958 Dns4RemoveTokenEntry (&Instance
->Dns4TxTokens
, Dns4TokenEntry
);
1959 Dns4TokenEntry
->Token
->Status
= EFI_TIMEOUT
;
1960 gBS
->SignalEvent (Dns4TokenEntry
->Token
->Event
);
1964 // Free the sending packet.
1966 if (ItemNetMap
->Value
!= NULL
) {
1967 NetbufFree ((NET_BUF
*)(ItemNetMap
->Value
));
1970 EntryNetMap
= Instance
->Dns4TxTokens
.Used
.ForwardLink
;
1976 // Iterate through all the children of the DNS service instance. Time
1977 // out the packet. If maximum retries reached, clean the Token up.
1979 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Service
->Dns6ChildrenList
) {
1980 Instance
= NET_LIST_USER_STRUCT (Entry
, DNS_INSTANCE
, Link
);
1982 EntryNetMap
= Instance
->Dns6TxTokens
.Used
.ForwardLink
;
1983 while (EntryNetMap
!= &Instance
->Dns6TxTokens
.Used
) {
1984 ItemNetMap
= NET_LIST_USER_STRUCT (EntryNetMap
, NET_MAP_ITEM
, Link
);
1985 Dns6TokenEntry
= (DNS6_TOKEN_ENTRY
*) (ItemNetMap
->Key
);
1986 if (Dns6TokenEntry
->PacketToLive
== 0 || (--Dns6TokenEntry
->PacketToLive
> 0)) {
1987 EntryNetMap
= EntryNetMap
->ForwardLink
;
1992 // Retransmit the packet if haven't reach the maxmium retry count,
1993 // otherwise exit the transfer.
1995 if (++Dns6TokenEntry
->Token
->RetryCount
< Instance
->MaxRetry
) {
1996 DnsRetransmit (Instance
, (NET_BUF
*) ItemNetMap
->Value
);
1997 EntryNetMap
= EntryNetMap
->ForwardLink
;
2000 // Maximum retries reached, clean the Token up.
2002 Dns6RemoveTokenEntry (&Instance
->Dns6TxTokens
, Dns6TokenEntry
);
2003 Dns6TokenEntry
->Token
->Status
= EFI_TIMEOUT
;
2004 gBS
->SignalEvent (Dns6TokenEntry
->Token
->Event
);
2008 // Free the sending packet.
2010 if (ItemNetMap
->Value
!= NULL
) {
2011 NetbufFree ((NET_BUF
*) (ItemNetMap
->Value
));
2014 EntryNetMap
= Instance
->Dns6TxTokens
.Used
.ForwardLink
;
2022 The timer ticking function for the DNS driver.
2024 @param Event The ticking event
2044 // Iterate through all the DNS4 cache list.
2046 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &mDriverData
->Dns4CacheList
) {
2047 Item4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
2048 Item4
->DnsCache
.Timeout
--;
2051 Entry
= mDriverData
->Dns4CacheList
.ForwardLink
;
2052 while (Entry
!= &mDriverData
->Dns4CacheList
) {
2053 Item4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
2054 if (Item4
->DnsCache
.Timeout
<=0) {
2055 RemoveEntryList (&Item4
->AllCacheLink
);
2056 Entry
= mDriverData
->Dns4CacheList
.ForwardLink
;
2058 Entry
= Entry
->ForwardLink
;
2063 // Iterate through all the DNS6 cache list.
2065 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &mDriverData
->Dns6CacheList
) {
2066 Item6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
2067 Item6
->DnsCache
.Timeout
--;
2070 Entry
= mDriverData
->Dns6CacheList
.ForwardLink
;
2071 while (Entry
!= &mDriverData
->Dns6CacheList
) {
2072 Item6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
2073 if (Item6
->DnsCache
.Timeout
<=0) {
2074 RemoveEntryList (&Item6
->AllCacheLink
);
2075 Entry
= mDriverData
->Dns6CacheList
.ForwardLink
;
2077 Entry
= Entry
->ForwardLink
;