2 DnsDxe support functions implementation.
4 Copyright (c) 2016, 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 if (Ip6Mode
.AddressList
!= NULL
) {
623 FreePool (Ip6Mode
.AddressList
);
626 if (Ip6Mode
.GroupTable
!= NULL
) {
627 FreePool (Ip6Mode
.GroupTable
);
630 if (Ip6Mode
.RouteTable
!= NULL
) {
631 FreePool (Ip6Mode
.RouteTable
);
634 if (Ip6Mode
.NeighborCache
!= NULL
) {
635 FreePool (Ip6Mode
.NeighborCache
);
638 if (Ip6Mode
.PrefixTable
!= NULL
) {
639 FreePool (Ip6Mode
.PrefixTable
);
642 if (Ip6Mode
.IcmpTypeList
!= NULL
) {
643 FreePool (Ip6Mode
.IcmpTypeList
);
646 if (Ip6Mode
.IsConfigured
) {
647 Udp
->Configure (Udp
, NULL
);
648 return (BOOLEAN
) (Udp
->Configure (Udp
, UdpCfgData
) == EFI_SUCCESS
);
659 @param Instance The DNS session
660 @param UdpIo The UDP_IO instance
662 @retval EFI_SUCCESS The UDP is successfully configured for the
668 IN DNS_INSTANCE
*Instance
,
672 EFI_DNS4_CONFIG_DATA
*Config
;
673 EFI_UDP4_CONFIG_DATA UdpConfig
;
676 Config
= &Instance
->Dns4CfgData
;
678 UdpConfig
.AcceptBroadcast
= FALSE
;
679 UdpConfig
.AcceptPromiscuous
= FALSE
;
680 UdpConfig
.AcceptAnyPort
= FALSE
;
681 UdpConfig
.AllowDuplicatePort
= FALSE
;
682 UdpConfig
.TypeOfService
= 0;
683 UdpConfig
.TimeToLive
= 128;
684 UdpConfig
.DoNotFragment
= FALSE
;
685 UdpConfig
.ReceiveTimeout
= 0;
686 UdpConfig
.TransmitTimeout
= 0;
687 UdpConfig
.UseDefaultAddress
= Config
->UseDefaultSetting
;
688 UdpConfig
.SubnetMask
= Config
->SubnetMask
;
689 UdpConfig
.StationPort
= Config
->LocalPort
;
690 UdpConfig
.RemotePort
= DNS_SERVER_PORT
;
692 CopyMem (&UdpConfig
.StationAddress
, &Config
->StationIp
, sizeof (EFI_IPv4_ADDRESS
));
693 CopyMem (&UdpConfig
.RemoteAddress
, &Instance
->SessionDnsServer
.v4
, sizeof (EFI_IPv4_ADDRESS
));
695 Status
= UdpIo
->Protocol
.Udp4
->Configure (UdpIo
->Protocol
.Udp4
, &UdpConfig
);
697 if ((Status
== EFI_NO_MAPPING
) && Dns4GetMapping (Instance
, UdpIo
, &UdpConfig
)) {
707 @param Instance The DNS session
708 @param UdpIo The UDP_IO instance
710 @retval EFI_SUCCESS The UDP is successfully configured for the
716 IN DNS_INSTANCE
*Instance
,
720 EFI_DNS6_CONFIG_DATA
*Config
;
721 EFI_UDP6_CONFIG_DATA UdpConfig
;
724 Config
= &Instance
->Dns6CfgData
;
726 UdpConfig
.AcceptPromiscuous
= FALSE
;
727 UdpConfig
.AcceptAnyPort
= FALSE
;
728 UdpConfig
.AllowDuplicatePort
= FALSE
;
729 UdpConfig
.TrafficClass
= 0;
730 UdpConfig
.HopLimit
= 128;
731 UdpConfig
.ReceiveTimeout
= 0;
732 UdpConfig
.TransmitTimeout
= 0;
733 UdpConfig
.StationPort
= Config
->LocalPort
;
734 UdpConfig
.RemotePort
= DNS_SERVER_PORT
;
735 CopyMem (&UdpConfig
.StationAddress
, &Config
->StationIp
, sizeof (EFI_IPv6_ADDRESS
));
736 CopyMem (&UdpConfig
.RemoteAddress
, &Instance
->SessionDnsServer
.v6
, sizeof (EFI_IPv6_ADDRESS
));
738 Status
= UdpIo
->Protocol
.Udp6
->Configure (UdpIo
->Protocol
.Udp6
, &UdpConfig
);
740 if ((Status
== EFI_NO_MAPPING
) && Dns6GetMapping (Instance
, UdpIo
, &UdpConfig
)) {
748 Update Dns4 cache to shared list of caches of all DNSv4 instances.
750 @param Dns4CacheList All Dns4 cache list.
751 @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
752 If TRUE, this function will delete matching DNS Cache entry.
753 @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
754 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
755 @param DnsCacheEntry Entry Pointer to DNS Cache entry.
757 @retval EFI_SUCCESS Update Dns4 cache successfully.
758 @retval Others Failed to update Dns4 cache.
764 IN LIST_ENTRY
*Dns4CacheList
,
765 IN BOOLEAN DeleteFlag
,
767 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry
770 DNS4_CACHE
*NewDnsCache
;
779 // Search the database for the matching EFI_DNS_CACHE_ENTRY
781 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns4CacheList
) {
782 Item
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
783 if (StrCmp (DnsCacheEntry
.HostName
, Item
->DnsCache
.HostName
) == 0 && \
784 CompareMem (DnsCacheEntry
.IpAddress
, Item
->DnsCache
.IpAddress
, sizeof (EFI_IPv4_ADDRESS
)) == 0) {
786 // This is the Dns cache entry
790 // Delete matching DNS Cache entry
792 RemoveEntryList (&Item
->AllCacheLink
);
795 } else if (Override
) {
799 Item
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
803 return EFI_ACCESS_DENIED
;
811 NewDnsCache
= AllocatePool (sizeof (DNS4_CACHE
));
812 if (NewDnsCache
== NULL
) {
813 return EFI_OUT_OF_RESOURCES
;
816 InitializeListHead (&NewDnsCache
->AllCacheLink
);
818 NewDnsCache
->DnsCache
.HostName
= AllocatePool (StrSize (DnsCacheEntry
.HostName
));
819 if (NewDnsCache
->DnsCache
.HostName
== NULL
) {
820 return EFI_OUT_OF_RESOURCES
;
823 CopyMem (NewDnsCache
->DnsCache
.HostName
, DnsCacheEntry
.HostName
, StrSize (DnsCacheEntry
.HostName
));
825 NewDnsCache
->DnsCache
.IpAddress
= AllocatePool (sizeof (EFI_IPv4_ADDRESS
));
826 if (NewDnsCache
->DnsCache
.IpAddress
== NULL
) {
827 return EFI_OUT_OF_RESOURCES
;
830 CopyMem (NewDnsCache
->DnsCache
.IpAddress
, DnsCacheEntry
.IpAddress
, sizeof (EFI_IPv4_ADDRESS
));
832 NewDnsCache
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
834 InsertTailList (Dns4CacheList
, &NewDnsCache
->AllCacheLink
);
840 Update Dns6 cache to shared list of caches of all DNSv6 instances.
842 @param Dns6CacheList All Dns6 cache list.
843 @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
844 If TRUE, this function will delete matching DNS Cache entry.
845 @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
846 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
847 @param DnsCacheEntry Entry Pointer to DNS Cache entry.
849 @retval EFI_SUCCESS Update Dns6 cache successfully.
850 @retval Others Failed to update Dns6 cache.
855 IN LIST_ENTRY
*Dns6CacheList
,
856 IN BOOLEAN DeleteFlag
,
858 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry
861 DNS6_CACHE
*NewDnsCache
;
870 // Search the database for the matching EFI_DNS_CACHE_ENTRY
872 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns6CacheList
) {
873 Item
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
874 if (StrCmp (DnsCacheEntry
.HostName
, Item
->DnsCache
.HostName
) == 0 && \
875 CompareMem (DnsCacheEntry
.IpAddress
, Item
->DnsCache
.IpAddress
, sizeof (EFI_IPv6_ADDRESS
)) == 0) {
877 // This is the Dns cache entry
881 // Delete matching DNS Cache entry
883 RemoveEntryList (&Item
->AllCacheLink
);
886 } else if (Override
) {
890 Item
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
894 return EFI_ACCESS_DENIED
;
902 NewDnsCache
= AllocatePool (sizeof (DNS6_CACHE
));
903 if (NewDnsCache
== NULL
) {
904 return EFI_OUT_OF_RESOURCES
;
907 InitializeListHead (&NewDnsCache
->AllCacheLink
);
909 NewDnsCache
->DnsCache
.HostName
= AllocatePool (StrSize (DnsCacheEntry
.HostName
));
910 if (NewDnsCache
->DnsCache
.HostName
== NULL
) {
911 return EFI_OUT_OF_RESOURCES
;
914 CopyMem (NewDnsCache
->DnsCache
.HostName
, DnsCacheEntry
.HostName
, StrSize (DnsCacheEntry
.HostName
));
916 NewDnsCache
->DnsCache
.IpAddress
= AllocatePool (sizeof (EFI_IPv6_ADDRESS
));
917 if (NewDnsCache
->DnsCache
.IpAddress
== NULL
) {
918 return EFI_OUT_OF_RESOURCES
;
921 CopyMem (NewDnsCache
->DnsCache
.IpAddress
, DnsCacheEntry
.IpAddress
, sizeof (EFI_IPv6_ADDRESS
));
923 NewDnsCache
->DnsCache
.Timeout
= DnsCacheEntry
.Timeout
;
925 InsertTailList (Dns6CacheList
, &NewDnsCache
->AllCacheLink
);
931 Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.
933 @param Dns4ServerList Common list of addresses of all configured DNSv4 server.
934 @param ServerIp DNS server Ip.
936 @retval EFI_SUCCESS Add Dns4 ServerIp to common list successfully.
937 @retval Others Failed to add Dns4 ServerIp to common list.
943 IN LIST_ENTRY
*Dns4ServerList
,
944 IN EFI_IPv4_ADDRESS ServerIp
947 DNS4_SERVER_IP
*NewServerIp
;
948 DNS4_SERVER_IP
*Item
;
956 // Search the database for the matching ServerIp
958 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns4ServerList
) {
959 Item
= NET_LIST_USER_STRUCT (Entry
, DNS4_SERVER_IP
, AllServerLink
);
960 if (CompareMem (&Item
->Dns4ServerIp
, &ServerIp
, sizeof (EFI_IPv4_ADDRESS
)) == 0) {
971 NewServerIp
= AllocatePool (sizeof (DNS4_SERVER_IP
));
972 if (NewServerIp
== NULL
) {
973 return EFI_OUT_OF_RESOURCES
;
976 InitializeListHead (&NewServerIp
->AllServerLink
);
978 CopyMem (&NewServerIp
->Dns4ServerIp
, &ServerIp
, sizeof (EFI_IPv4_ADDRESS
));
980 InsertTailList (Dns4ServerList
, &NewServerIp
->AllServerLink
);
986 Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.
988 @param Dns6ServerList Common list of addresses of all configured DNSv6 server.
989 @param ServerIp DNS server Ip.
991 @retval EFI_SUCCESS Add Dns6 ServerIp to common list successfully.
992 @retval Others Failed to add Dns6 ServerIp to common list.
998 IN LIST_ENTRY
*Dns6ServerList
,
999 IN EFI_IPv6_ADDRESS ServerIp
1002 DNS6_SERVER_IP
*NewServerIp
;
1003 DNS6_SERVER_IP
*Item
;
1011 // Search the database for the matching ServerIp
1013 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Dns6ServerList
) {
1014 Item
= NET_LIST_USER_STRUCT (Entry
, DNS6_SERVER_IP
, AllServerLink
);
1015 if (CompareMem (&Item
->Dns6ServerIp
, &ServerIp
, sizeof (EFI_IPv6_ADDRESS
)) == 0) {
1026 NewServerIp
= AllocatePool (sizeof (DNS6_SERVER_IP
));
1027 if (NewServerIp
== NULL
) {
1028 return EFI_OUT_OF_RESOURCES
;
1031 InitializeListHead (&NewServerIp
->AllServerLink
);
1033 CopyMem (&NewServerIp
->Dns6ServerIp
, &ServerIp
, sizeof (EFI_IPv6_ADDRESS
));
1035 InsertTailList (Dns6ServerList
, &NewServerIp
->AllServerLink
);
1041 Find out whether the response is valid or invalid.
1043 @param TokensMap All DNS transmittal Tokens entry.
1044 @param Identification Identification for queried packet.
1045 @param Type Type for queried packet.
1046 @param Class Class for queried packet.
1047 @param Item Return corresponding Token entry.
1049 @retval TRUE The response is valid.
1050 @retval FALSE The response is invalid.
1054 IsValidDnsResponse (
1055 IN NET_MAP
*TokensMap
,
1056 IN UINT16 Identification
,
1059 OUT NET_MAP_ITEM
**Item
1066 DNS_HEADER
*DnsHeader
;
1068 DNS_QUERY_SECTION
*QuerySection
;
1070 NET_LIST_FOR_EACH (Entry
, &TokensMap
->Used
) {
1071 *Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
1072 Packet
= (NET_BUF
*) ((*Item
)->Value
);
1073 if (Packet
== NULL
){
1077 TxString
= NetbufGetByte (Packet
, 0, NULL
);
1078 ASSERT (TxString
!= NULL
);
1079 DnsHeader
= (DNS_HEADER
*) TxString
;
1080 QueryName
= (CHAR8
*) (TxString
+ sizeof (*DnsHeader
));
1081 QuerySection
= (DNS_QUERY_SECTION
*) (QueryName
+ AsciiStrLen (QueryName
) + 1);
1083 if (NTOHS (DnsHeader
->Identification
) == Identification
&&
1084 NTOHS (QuerySection
->Type
) == Type
&&
1085 NTOHS (QuerySection
->Class
) == Class
) {
1099 @param Instance The DNS instance
1100 @param RxString Received buffer.
1101 @param Completed Flag to indicate that Dns response is valid.
1103 @retval EFI_SUCCESS Parse Dns Response successfully.
1104 @retval Others Failed to parse Dns Response.
1109 IN OUT DNS_INSTANCE
*Instance
,
1111 OUT BOOLEAN
*Completed
1114 DNS_HEADER
*DnsHeader
;
1117 DNS_QUERY_SECTION
*QuerySection
;
1120 DNS_ANSWER_SECTION
*AnswerSection
;
1124 DNS4_TOKEN_ENTRY
*Dns4TokenEntry
;
1125 DNS6_TOKEN_ENTRY
*Dns6TokenEntry
;
1129 UINT32 AnswerSectionNum
;
1132 EFI_IPv4_ADDRESS
*HostAddr4
;
1133 EFI_IPv6_ADDRESS
*HostAddr6
;
1135 EFI_DNS4_CACHE_ENTRY
*Dns4CacheEntry
;
1136 EFI_DNS6_CACHE_ENTRY
*Dns6CacheEntry
;
1138 DNS_RESOURCE_RECORD
*Dns4RR
;
1139 DNS6_RESOURCE_RECORD
*Dns6RR
;
1146 Dns4TokenEntry
= NULL
;
1147 Dns6TokenEntry
= NULL
;
1151 AnswerSectionNum
= 0;
1157 Dns4CacheEntry
= NULL
;
1158 Dns6CacheEntry
= NULL
;
1164 Status
= EFI_SUCCESS
;
1169 DnsHeader
= (DNS_HEADER
*) RxString
;
1171 DnsHeader
->Identification
= NTOHS (DnsHeader
->Identification
);
1172 DnsHeader
->Flags
.Uint16
= NTOHS (DnsHeader
->Flags
.Uint16
);
1173 DnsHeader
->QuestionsNum
= NTOHS (DnsHeader
->QuestionsNum
);
1174 DnsHeader
->AnswersNum
= NTOHS (DnsHeader
->AnswersNum
);
1175 DnsHeader
->AuthorityNum
= NTOHS (DnsHeader
->AuthorityNum
);
1176 DnsHeader
->AditionalNum
= NTOHS (DnsHeader
->AditionalNum
);
1181 QueryName
= (CHAR8
*) (RxString
+ sizeof (*DnsHeader
));
1184 // Get query section
1186 QuerySection
= (DNS_QUERY_SECTION
*) (QueryName
+ AsciiStrLen (QueryName
) + 1);
1187 QuerySection
->Type
= NTOHS (QuerySection
->Type
);
1188 QuerySection
->Class
= NTOHS (QuerySection
->Class
);
1193 AnswerName
= (CHAR8
*) QuerySection
+ sizeof (*QuerySection
);
1195 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1198 // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.
1200 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1201 if (!IsValidDnsResponse (
1202 &Instance
->Dns4TxTokens
,
1203 DnsHeader
->Identification
,
1205 QuerySection
->Class
,
1209 Status
= EFI_ABORTED
;
1212 ASSERT (Item
!= NULL
);
1213 Dns4TokenEntry
= (DNS4_TOKEN_ENTRY
*) (Item
->Key
);
1215 if (!IsValidDnsResponse (
1216 &Instance
->Dns6TxTokens
,
1217 DnsHeader
->Identification
,
1219 QuerySection
->Class
,
1223 Status
= EFI_ABORTED
;
1226 ASSERT (Item
!= NULL
);
1227 Dns6TokenEntry
= (DNS6_TOKEN_ENTRY
*) (Item
->Key
);
1231 // Continue Check Some Errors.
1233 if (DnsHeader
->Flags
.Bits
.RCode
!= DNS_FLAGS_RCODE_NO_ERROR
|| DnsHeader
->AnswersNum
< 1 || \
1234 DnsHeader
->Flags
.Bits
.QR
!= DNS_FLAGS_QR_RESPONSE
) {
1236 // The domain name referenced in the query does not exist.
1238 if (DnsHeader
->Flags
.Bits
.RCode
== DNS_FLAGS_RCODE_NAME_ERROR
) {
1239 Status
= EFI_NOT_FOUND
;
1241 Status
= EFI_DEVICE_ERROR
;
1248 // Do some buffer allocations.
1250 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1251 ASSERT (Dns4TokenEntry
!= NULL
);
1253 if (Dns4TokenEntry
->GeneralLookUp
) {
1255 // It's the GeneralLookUp querying.
1257 Dns4TokenEntry
->Token
->RspData
.GLookupData
= AllocatePool (sizeof (DNS_RESOURCE_RECORD
));
1258 if (Dns4TokenEntry
->Token
->RspData
.GLookupData
== NULL
) {
1259 Status
= EFI_OUT_OF_RESOURCES
;
1262 Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (DNS_RESOURCE_RECORD
));
1263 if (Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRList
== NULL
) {
1264 Status
= EFI_OUT_OF_RESOURCES
;
1269 // It's not the GeneralLookUp querying. Check the Query type.
1271 if (QuerySection
->Type
== DNS_TYPE_A
) {
1272 Dns4TokenEntry
->Token
->RspData
.H2AData
= AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA
));
1273 if (Dns4TokenEntry
->Token
->RspData
.H2AData
== NULL
) {
1274 Status
= EFI_OUT_OF_RESOURCES
;
1277 Dns4TokenEntry
->Token
->RspData
.H2AData
->IpList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (EFI_IPv4_ADDRESS
));
1278 if (Dns4TokenEntry
->Token
->RspData
.H2AData
->IpList
== NULL
) {
1279 Status
= EFI_OUT_OF_RESOURCES
;
1283 Status
= EFI_UNSUPPORTED
;
1288 ASSERT (Dns6TokenEntry
!= NULL
);
1290 if (Dns6TokenEntry
->GeneralLookUp
) {
1292 // It's the GeneralLookUp querying.
1294 Dns6TokenEntry
->Token
->RspData
.GLookupData
= AllocatePool (sizeof (DNS_RESOURCE_RECORD
));
1295 if (Dns6TokenEntry
->Token
->RspData
.GLookupData
== NULL
) {
1296 Status
= EFI_OUT_OF_RESOURCES
;
1299 Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (DNS_RESOURCE_RECORD
));
1300 if (Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRList
== NULL
) {
1301 Status
= EFI_OUT_OF_RESOURCES
;
1306 // It's not the GeneralLookUp querying. Check the Query type.
1308 if (QuerySection
->Type
== DNS_TYPE_AAAA
) {
1309 Dns6TokenEntry
->Token
->RspData
.H2AData
= AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA
));
1310 if (Dns6TokenEntry
->Token
->RspData
.H2AData
== NULL
) {
1311 Status
= EFI_OUT_OF_RESOURCES
;
1314 Dns6TokenEntry
->Token
->RspData
.H2AData
->IpList
= AllocatePool (DnsHeader
->AnswersNum
* sizeof (EFI_IPv6_ADDRESS
));
1315 if (Dns6TokenEntry
->Token
->RspData
.H2AData
->IpList
== NULL
) {
1316 Status
= EFI_OUT_OF_RESOURCES
;
1320 Status
= EFI_UNSUPPORTED
;
1326 Status
= EFI_NOT_FOUND
;
1329 // Processing AnswerSection.
1331 while (AnswerSectionNum
< DnsHeader
->AnswersNum
) {
1333 // Answer name should be PTR, else EFI_UNSUPPORTED returned.
1335 if ((*(UINT8
*) AnswerName
& 0xC0) != 0xC0) {
1336 Status
= EFI_UNSUPPORTED
;
1341 // Get Answer section.
1343 AnswerSection
= (DNS_ANSWER_SECTION
*) (AnswerName
+ sizeof (UINT16
));
1344 AnswerSection
->Type
= NTOHS (AnswerSection
->Type
);
1345 AnswerSection
->Class
= NTOHS (AnswerSection
->Class
);
1346 AnswerSection
->Ttl
= NTOHL (AnswerSection
->Ttl
);
1347 AnswerSection
->DataLength
= NTOHS (AnswerSection
->DataLength
);
1350 // Check whether it's the GeneralLookUp querying.
1352 if (Instance
->Service
->IpVersion
== IP_VERSION_4
&& Dns4TokenEntry
->GeneralLookUp
) {
1353 Dns4RR
= Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRList
;
1354 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1357 // Fill the ResourceRecord.
1359 Dns4RR
[RRCount
].QName
= AllocateZeroPool (AsciiStrLen (QueryName
) + 1);
1360 if (Dns4RR
[RRCount
].QName
== NULL
) {
1361 Status
= EFI_OUT_OF_RESOURCES
;
1364 CopyMem (Dns4RR
[RRCount
].QName
, QueryName
, AsciiStrLen (QueryName
));
1365 Dns4RR
[RRCount
].QType
= AnswerSection
->Type
;
1366 Dns4RR
[RRCount
].QClass
= AnswerSection
->Class
;
1367 Dns4RR
[RRCount
].TTL
= AnswerSection
->Ttl
;
1368 Dns4RR
[RRCount
].DataLength
= AnswerSection
->DataLength
;
1369 Dns4RR
[RRCount
].RData
= AllocateZeroPool (Dns4RR
[RRCount
].DataLength
);
1370 if (Dns4RR
[RRCount
].RData
== NULL
) {
1371 Status
= EFI_OUT_OF_RESOURCES
;
1374 CopyMem (Dns4RR
[RRCount
].RData
, AnswerData
, Dns4RR
[RRCount
].DataLength
);
1377 Status
= EFI_SUCCESS
;
1378 } else if (Instance
->Service
->IpVersion
== IP_VERSION_6
&& Dns6TokenEntry
->GeneralLookUp
) {
1379 Dns6RR
= Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRList
;
1380 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1383 // Fill the ResourceRecord.
1385 Dns6RR
[RRCount
].QName
= AllocateZeroPool (AsciiStrLen (QueryName
) + 1);
1386 if (Dns6RR
[RRCount
].QName
== NULL
) {
1387 Status
= EFI_OUT_OF_RESOURCES
;
1390 CopyMem (Dns6RR
[RRCount
].QName
, QueryName
, AsciiStrLen (QueryName
));
1391 Dns6RR
[RRCount
].QType
= AnswerSection
->Type
;
1392 Dns6RR
[RRCount
].QClass
= AnswerSection
->Class
;
1393 Dns6RR
[RRCount
].TTL
= AnswerSection
->Ttl
;
1394 Dns6RR
[RRCount
].DataLength
= AnswerSection
->DataLength
;
1395 Dns6RR
[RRCount
].RData
= AllocateZeroPool (Dns6RR
[RRCount
].DataLength
);
1396 if (Dns6RR
[RRCount
].RData
== NULL
) {
1397 Status
= EFI_OUT_OF_RESOURCES
;
1400 CopyMem (Dns6RR
[RRCount
].RData
, AnswerData
, Dns6RR
[RRCount
].DataLength
);
1403 Status
= EFI_SUCCESS
;
1406 // It's not the GeneralLookUp querying.
1407 // Check the Query type, parse the response packet.
1409 switch (AnswerSection
->Type
) {
1412 // This is address entry, get Data.
1414 ASSERT (Dns4TokenEntry
!= NULL
);
1416 if (AnswerSection
->DataLength
!= 4) {
1417 Status
= EFI_ABORTED
;
1421 HostAddr4
= Dns4TokenEntry
->Token
->RspData
.H2AData
->IpList
;
1422 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1423 CopyMem (&HostAddr4
[IpCount
], AnswerData
, sizeof (EFI_IPv4_ADDRESS
));
1426 // Allocate new CacheEntry pool to update DNS cache dynamically.
1428 Dns4CacheEntry
= AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY
));
1429 if (Dns4CacheEntry
== NULL
) {
1430 Status
= EFI_OUT_OF_RESOURCES
;
1433 Dns4CacheEntry
->HostName
= AllocateZeroPool (2 * (StrLen(Dns4TokenEntry
->QueryHostName
) + 1));
1434 if (Dns4CacheEntry
->HostName
== NULL
) {
1435 Status
= EFI_OUT_OF_RESOURCES
;
1438 CopyMem (Dns4CacheEntry
->HostName
, Dns4TokenEntry
->QueryHostName
, 2 * (StrLen(Dns4TokenEntry
->QueryHostName
) + 1));
1439 Dns4CacheEntry
->IpAddress
= AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS
));
1440 if (Dns4CacheEntry
->IpAddress
== NULL
) {
1441 Status
= EFI_OUT_OF_RESOURCES
;
1444 CopyMem (Dns4CacheEntry
->IpAddress
, AnswerData
, sizeof (EFI_IPv4_ADDRESS
));
1446 if (CNameTtl
!= 0 && AnswerSection
->Ttl
!= 0) {
1447 Dns4CacheEntry
->Timeout
= MIN (CNameTtl
, AnswerSection
->Ttl
);
1449 Dns4CacheEntry
->Timeout
= MAX (CNameTtl
, AnswerSection
->Ttl
);
1452 UpdateDns4Cache (&mDriverData
->Dns4CacheList
, FALSE
, TRUE
, *Dns4CacheEntry
);
1455 // Free allocated CacheEntry pool.
1457 FreePool (Dns4CacheEntry
->HostName
);
1458 Dns4CacheEntry
->HostName
= NULL
;
1460 FreePool (Dns4CacheEntry
->IpAddress
);
1461 Dns4CacheEntry
->IpAddress
= NULL
;
1463 FreePool (Dns4CacheEntry
);
1464 Dns4CacheEntry
= NULL
;
1467 Status
= EFI_SUCCESS
;
1471 // This is address entry, get Data.
1473 ASSERT (Dns6TokenEntry
!= NULL
);
1475 if (AnswerSection
->DataLength
!= 16) {
1476 Status
= EFI_ABORTED
;
1480 HostAddr6
= Dns6TokenEntry
->Token
->RspData
.H2AData
->IpList
;
1481 AnswerData
= (UINT8
*) AnswerSection
+ sizeof (*AnswerSection
);
1482 CopyMem (&HostAddr6
[IpCount
], AnswerData
, sizeof (EFI_IPv6_ADDRESS
));
1485 // Allocate new CacheEntry pool to update DNS cache dynamically.
1487 Dns6CacheEntry
= AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY
));
1488 if (Dns6CacheEntry
== NULL
) {
1489 Status
= EFI_OUT_OF_RESOURCES
;
1492 Dns6CacheEntry
->HostName
= AllocateZeroPool (2 * (StrLen(Dns6TokenEntry
->QueryHostName
) + 1));
1493 if (Dns6CacheEntry
->HostName
== NULL
) {
1494 Status
= EFI_OUT_OF_RESOURCES
;
1497 CopyMem (Dns6CacheEntry
->HostName
, Dns6TokenEntry
->QueryHostName
, 2 * (StrLen(Dns6TokenEntry
->QueryHostName
) + 1));
1498 Dns6CacheEntry
->IpAddress
= AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS
));
1499 if (Dns6CacheEntry
->IpAddress
== NULL
) {
1500 Status
= EFI_OUT_OF_RESOURCES
;
1503 CopyMem (Dns6CacheEntry
->IpAddress
, AnswerData
, sizeof (EFI_IPv6_ADDRESS
));
1505 if (CNameTtl
!= 0 && AnswerSection
->Ttl
!= 0) {
1506 Dns6CacheEntry
->Timeout
= MIN (CNameTtl
, AnswerSection
->Ttl
);
1508 Dns6CacheEntry
->Timeout
= MAX (CNameTtl
, AnswerSection
->Ttl
);
1511 UpdateDns6Cache (&mDriverData
->Dns6CacheList
, FALSE
, TRUE
, *Dns6CacheEntry
);
1514 // Free allocated CacheEntry pool.
1516 FreePool (Dns6CacheEntry
->HostName
);
1517 Dns6CacheEntry
->HostName
= NULL
;
1519 FreePool (Dns6CacheEntry
->IpAddress
);
1520 Dns6CacheEntry
->IpAddress
= NULL
;
1522 FreePool (Dns6CacheEntry
);
1523 Dns6CacheEntry
= NULL
;
1526 Status
= EFI_SUCCESS
;
1528 case DNS_TYPE_CNAME
:
1530 // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME
1531 // record in the response and restart the query at the domain name specified in the data field of the
1532 // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.
1534 CNameTtl
= AnswerSection
->Ttl
;
1537 Status
= EFI_UNSUPPORTED
;
1545 AnswerName
= (CHAR8
*) AnswerSection
+ sizeof (*AnswerSection
) + AnswerSection
->DataLength
;
1546 AnswerSectionNum
++;
1549 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1550 ASSERT (Dns4TokenEntry
!= NULL
);
1552 if (Dns4TokenEntry
->GeneralLookUp
) {
1553 Dns4TokenEntry
->Token
->RspData
.GLookupData
->RRCount
= RRCount
;
1555 if (QuerySection
->Type
== DNS_TYPE_A
) {
1556 Dns4TokenEntry
->Token
->RspData
.H2AData
->IpCount
= IpCount
;
1558 Status
= EFI_UNSUPPORTED
;
1563 ASSERT (Dns6TokenEntry
!= NULL
);
1565 if (Dns6TokenEntry
->GeneralLookUp
) {
1566 Dns6TokenEntry
->Token
->RspData
.GLookupData
->RRCount
= RRCount
;
1568 if (QuerySection
->Type
== DNS_TYPE_AAAA
) {
1569 Dns6TokenEntry
->Token
->RspData
.H2AData
->IpCount
= IpCount
;
1571 Status
= EFI_UNSUPPORTED
;
1579 // Parsing is complete, free the sending packet and signal Event here.
1581 if (Item
!= NULL
&& Item
->Value
!= NULL
) {
1582 NetbufFree ((NET_BUF
*) (Item
->Value
));
1585 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1586 ASSERT (Dns4TokenEntry
!= NULL
);
1587 Dns4RemoveTokenEntry (&Instance
->Dns4TxTokens
, Dns4TokenEntry
);
1588 Dns4TokenEntry
->Token
->Status
= Status
;
1589 if (Dns4TokenEntry
->Token
->Event
!= NULL
) {
1590 gBS
->SignalEvent (Dns4TokenEntry
->Token
->Event
);
1594 ASSERT (Dns6TokenEntry
!= NULL
);
1595 Dns6RemoveTokenEntry (&Instance
->Dns6TxTokens
, Dns6TokenEntry
);
1596 Dns6TokenEntry
->Token
->Status
= Status
;
1597 if (Dns6TokenEntry
->Token
->Event
!= NULL
) {
1598 gBS
->SignalEvent (Dns6TokenEntry
->Token
->Event
);
1604 gBS
->RestoreTPL (OldTpl
);
1609 Parse response packet.
1611 @param Packet The packets received.
1612 @param EndPoint The local/remote UDP access point
1613 @param IoStatus The status of the UDP receive
1614 @param Context The opaque parameter to the function.
1619 DnsOnPacketReceived (
1621 UDP_END_POINT
*EndPoint
,
1622 EFI_STATUS IoStatus
,
1626 DNS_INSTANCE
*Instance
;
1632 Instance
= (DNS_INSTANCE
*) Context
;
1633 NET_CHECK_SIGNATURE (Instance
, DNS_INSTANCE_SIGNATURE
);
1638 if (EFI_ERROR (IoStatus
)) {
1642 ASSERT (Packet
!= NULL
);
1644 if (Packet
->TotalSize
<= sizeof (DNS_HEADER
)) {
1648 RcvString
= NetbufGetByte (Packet
, 0, NULL
);
1649 ASSERT (RcvString
!= NULL
);
1652 // Parse Dns Response
1654 ParseDnsResponse (Instance
, RcvString
, &Completed
);
1658 if (Packet
!= NULL
) {
1659 NetbufFree (Packet
);
1663 UdpIoRecvDatagram (Instance
->UdpIo
, DnsOnPacketReceived
, Instance
, 0);
1668 Release the net buffer when packet is sent.
1670 @param Packet The packets received.
1671 @param EndPoint The local/remote UDP access point
1672 @param IoStatus The status of the UDP receive
1673 @param Context The opaque parameter to the function.
1680 UDP_END_POINT
*EndPoint
,
1681 EFI_STATUS IoStatus
,
1685 DNS_INSTANCE
*Instance
;
1688 DNS4_TOKEN_ENTRY
*Dns4TokenEntry
;
1689 DNS6_TOKEN_ENTRY
*Dns6TokenEntry
;
1691 Dns4TokenEntry
= NULL
;
1692 Dns6TokenEntry
= NULL
;
1694 Instance
= (DNS_INSTANCE
*) Context
;
1695 NET_CHECK_SIGNATURE (Instance
, DNS_INSTANCE_SIGNATURE
);
1697 if (Instance
->Service
->IpVersion
== IP_VERSION_4
) {
1698 NET_LIST_FOR_EACH (Entry
, &Instance
->Dns4TxTokens
.Used
) {
1699 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
1700 if (Packet
== (NET_BUF
*)(Item
->Value
)) {
1701 Dns4TokenEntry
= ((DNS4_TOKEN_ENTRY
*)Item
->Key
);
1702 Dns4TokenEntry
->PacketToLive
= Dns4TokenEntry
->Token
->RetryInterval
;
1707 NET_LIST_FOR_EACH (Entry
, &Instance
->Dns6TxTokens
.Used
) {
1708 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
1709 if (Packet
== (NET_BUF
*)(Item
->Value
)) {
1710 Dns6TokenEntry
= ((DNS6_TOKEN_ENTRY
*)Item
->Key
);
1711 Dns6TokenEntry
->PacketToLive
= Dns6TokenEntry
->Token
->RetryInterval
;
1717 NetbufFree (Packet
);
1721 Query request information.
1723 @param Instance The DNS instance
1724 @param Packet The packet for querying request information.
1726 @retval EFI_SUCCESS Query request information successfully.
1727 @retval Others Failed to query request information.
1732 IN DNS_INSTANCE
*Instance
,
1739 // Ready to receive the DNS response.
1741 if (Instance
->UdpIo
->RecvRequest
== NULL
) {
1742 Status
= UdpIoRecvDatagram (Instance
->UdpIo
, DnsOnPacketReceived
, Instance
, 0);
1743 if (EFI_ERROR (Status
)) {
1749 // Transmit the DNS packet.
1751 NET_GET_REF (Packet
);
1753 Status
= UdpIoSendDatagram (Instance
->UdpIo
, Packet
, NULL
, NULL
, DnsOnPacketSent
, Instance
);
1759 Construct the Packet according query section.
1761 @param Instance The DNS instance
1762 @param QueryName Queried Name
1763 @param Type Queried Type
1764 @param Class Queried Class
1765 @param Packet The packet for query
1767 @retval EFI_SUCCESS The packet is constructed.
1768 @retval Others Failed to construct the Packet.
1773 IN DNS_INSTANCE
*Instance
,
1774 IN CHAR8
*QueryName
,
1777 OUT NET_BUF
**Packet
1781 DNS_HEADER
*DnsHeader
;
1782 DNS_QUERY_SECTION
*DnsQuery
;
1785 // Messages carried by UDP are restricted to 512 bytes (not counting the IP
1788 Frag
.Bulk
= AllocatePool (DNS_MAX_MESSAGE_SIZE
* sizeof (UINT8
));
1789 if (Frag
.Bulk
== NULL
) {
1790 return EFI_OUT_OF_RESOURCES
;
1796 DnsHeader
= (DNS_HEADER
*) Frag
.Bulk
;
1797 DnsHeader
->Identification
= (UINT16
)NET_RANDOM (NetRandomInitSeed());
1798 DnsHeader
->Flags
.Uint16
= 0x0000;
1799 DnsHeader
->Flags
.Bits
.RD
= 1;
1800 DnsHeader
->Flags
.Bits
.OpCode
= DNS_FLAGS_OPCODE_STANDARD
;
1801 DnsHeader
->Flags
.Bits
.QR
= DNS_FLAGS_QR_QUERY
;
1802 DnsHeader
->QuestionsNum
= 1;
1803 DnsHeader
->AnswersNum
= 0;
1804 DnsHeader
->AuthorityNum
= 0;
1805 DnsHeader
->AditionalNum
= 0;
1807 DnsHeader
->Identification
= HTONS (DnsHeader
->Identification
);
1808 DnsHeader
->Flags
.Uint16
= HTONS (DnsHeader
->Flags
.Uint16
);
1809 DnsHeader
->QuestionsNum
= HTONS (DnsHeader
->QuestionsNum
);
1810 DnsHeader
->AnswersNum
= HTONS (DnsHeader
->AnswersNum
);
1811 DnsHeader
->AuthorityNum
= HTONS (DnsHeader
->AuthorityNum
);
1812 DnsHeader
->AditionalNum
= HTONS (DnsHeader
->AditionalNum
);
1814 Frag
.Len
= sizeof (*DnsHeader
);
1819 CopyMem (Frag
.Bulk
+ Frag
.Len
, QueryName
, AsciiStrLen (QueryName
));
1820 Frag
.Len
= (UINT32
) (Frag
.Len
+ AsciiStrLen (QueryName
));
1821 *(Frag
.Bulk
+ Frag
.Len
) = 0;
1825 // Rest query section
1827 DnsQuery
= (DNS_QUERY_SECTION
*) (Frag
.Bulk
+ Frag
.Len
);
1829 DnsQuery
->Type
= HTONS (Type
);
1830 DnsQuery
->Class
= HTONS (Class
);
1832 Frag
.Len
+= sizeof (*DnsQuery
);
1835 // Wrap the Frag in a net buffer.
1837 *Packet
= NetbufFromExt (&Frag
, 1, 0, 0, DnsDummyExtFree
, NULL
);
1838 if (*Packet
== NULL
) {
1839 FreePool (Frag
.Bulk
);
1840 return EFI_OUT_OF_RESOURCES
;
1844 // Store the UdpIo in ProtoData.
1846 *((UINTN
*) &((*Packet
)->ProtoData
[0])) = (UINTN
) (Instance
->UdpIo
);
1852 Retransmit the packet.
1854 @param Instance The DNS instance
1855 @param Packet Retransmit the packet
1857 @retval EFI_SUCCESS The packet is retransmitted.
1858 @retval Others Failed to retransmit.
1863 IN DNS_INSTANCE
*Instance
,
1871 ASSERT (Packet
!= NULL
);
1874 // Set the requests to the listening port, other packets to the connected port
1876 Buffer
= NetbufGetByte (Packet
, 0, NULL
);
1877 ASSERT (Buffer
!= NULL
);
1879 NET_GET_REF (Packet
);
1881 Status
= UdpIoSendDatagram (
1890 if (EFI_ERROR (Status
)) {
1891 NET_PUT_REF (Packet
);
1898 The timer ticking function for the DNS services.
1900 @param Event The ticking event
1901 @param Context The DNS service instance
1906 DnsOnTimerRetransmit (
1911 DNS_SERVICE
*Service
;
1916 DNS_INSTANCE
*Instance
;
1917 LIST_ENTRY
*EntryNetMap
;
1918 NET_MAP_ITEM
*ItemNetMap
;
1919 DNS4_TOKEN_ENTRY
*Dns4TokenEntry
;
1920 DNS6_TOKEN_ENTRY
*Dns6TokenEntry
;
1922 Dns4TokenEntry
= NULL
;
1923 Dns6TokenEntry
= NULL
;
1925 Service
= (DNS_SERVICE
*) Context
;
1928 if (Service
->IpVersion
== IP_VERSION_4
) {
1930 // Iterate through all the children of the DNS service instance. Time
1931 // out the packet. If maximum retries reached, clean the Token up.
1933 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Service
->Dns4ChildrenList
) {
1934 Instance
= NET_LIST_USER_STRUCT (Entry
, DNS_INSTANCE
, Link
);
1936 EntryNetMap
= Instance
->Dns4TxTokens
.Used
.ForwardLink
;
1937 while (EntryNetMap
!= &Instance
->Dns4TxTokens
.Used
) {
1938 ItemNetMap
= NET_LIST_USER_STRUCT (EntryNetMap
, NET_MAP_ITEM
, Link
);
1939 Dns4TokenEntry
= (DNS4_TOKEN_ENTRY
*)(ItemNetMap
->Key
);
1940 if (Dns4TokenEntry
->PacketToLive
== 0 || (--Dns4TokenEntry
->PacketToLive
> 0)) {
1941 EntryNetMap
= EntryNetMap
->ForwardLink
;
1946 // Retransmit the packet if haven't reach the maxmium retry count,
1947 // otherwise exit the transfer.
1949 if (++Dns4TokenEntry
->Token
->RetryCount
< Instance
->MaxRetry
) {
1950 DnsRetransmit (Instance
, (NET_BUF
*)ItemNetMap
->Value
);
1951 EntryNetMap
= EntryNetMap
->ForwardLink
;
1954 // Maximum retries reached, clean the Token up.
1956 Dns4RemoveTokenEntry (&Instance
->Dns4TxTokens
, Dns4TokenEntry
);
1957 Dns4TokenEntry
->Token
->Status
= EFI_TIMEOUT
;
1958 gBS
->SignalEvent (Dns4TokenEntry
->Token
->Event
);
1962 // Free the sending packet.
1964 if (ItemNetMap
->Value
!= NULL
) {
1965 NetbufFree ((NET_BUF
*)(ItemNetMap
->Value
));
1968 EntryNetMap
= Instance
->Dns4TxTokens
.Used
.ForwardLink
;
1974 // Iterate through all the children of the DNS service instance. Time
1975 // out the packet. If maximum retries reached, clean the Token up.
1977 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Service
->Dns6ChildrenList
) {
1978 Instance
= NET_LIST_USER_STRUCT (Entry
, DNS_INSTANCE
, Link
);
1980 EntryNetMap
= Instance
->Dns6TxTokens
.Used
.ForwardLink
;
1981 while (EntryNetMap
!= &Instance
->Dns6TxTokens
.Used
) {
1982 ItemNetMap
= NET_LIST_USER_STRUCT (EntryNetMap
, NET_MAP_ITEM
, Link
);
1983 Dns6TokenEntry
= (DNS6_TOKEN_ENTRY
*) (ItemNetMap
->Key
);
1984 if (Dns6TokenEntry
->PacketToLive
== 0 || (--Dns6TokenEntry
->PacketToLive
> 0)) {
1985 EntryNetMap
= EntryNetMap
->ForwardLink
;
1990 // Retransmit the packet if haven't reach the maxmium retry count,
1991 // otherwise exit the transfer.
1993 if (++Dns6TokenEntry
->Token
->RetryCount
< Instance
->MaxRetry
) {
1994 DnsRetransmit (Instance
, (NET_BUF
*) ItemNetMap
->Value
);
1995 EntryNetMap
= EntryNetMap
->ForwardLink
;
1998 // Maximum retries reached, clean the Token up.
2000 Dns6RemoveTokenEntry (&Instance
->Dns6TxTokens
, Dns6TokenEntry
);
2001 Dns6TokenEntry
->Token
->Status
= EFI_TIMEOUT
;
2002 gBS
->SignalEvent (Dns6TokenEntry
->Token
->Event
);
2006 // Free the sending packet.
2008 if (ItemNetMap
->Value
!= NULL
) {
2009 NetbufFree ((NET_BUF
*) (ItemNetMap
->Value
));
2012 EntryNetMap
= Instance
->Dns6TxTokens
.Used
.ForwardLink
;
2020 The timer ticking function for the DNS driver.
2022 @param Event The ticking event
2042 // Iterate through all the DNS4 cache list.
2044 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &mDriverData
->Dns4CacheList
) {
2045 Item4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
2046 Item4
->DnsCache
.Timeout
--;
2049 Entry
= mDriverData
->Dns4CacheList
.ForwardLink
;
2050 while (Entry
!= &mDriverData
->Dns4CacheList
) {
2051 Item4
= NET_LIST_USER_STRUCT (Entry
, DNS4_CACHE
, AllCacheLink
);
2052 if (Item4
->DnsCache
.Timeout
== 0) {
2053 RemoveEntryList (&Item4
->AllCacheLink
);
2054 Entry
= mDriverData
->Dns4CacheList
.ForwardLink
;
2056 Entry
= Entry
->ForwardLink
;
2061 // Iterate through all the DNS6 cache list.
2063 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &mDriverData
->Dns6CacheList
) {
2064 Item6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
2065 Item6
->DnsCache
.Timeout
--;
2068 Entry
= mDriverData
->Dns6CacheList
.ForwardLink
;
2069 while (Entry
!= &mDriverData
->Dns6CacheList
) {
2070 Item6
= NET_LIST_USER_STRUCT (Entry
, DNS6_CACHE
, AllCacheLink
);
2071 if (Item6
->DnsCache
.Timeout
== 0) {
2072 RemoveEntryList (&Item6
->AllCacheLink
);
2073 Entry
= mDriverData
->Dns6CacheList
.ForwardLink
;
2075 Entry
= Entry
->ForwardLink
;