/** @file\r
DnsDxe support functions implementation.\r
\r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
while (!EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
Udp->Poll (Udp);\r
\r
- if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL)) &&\r
- Ip6Mode.IsConfigured) {\r
+ if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL))) {\r
+ if (Ip6Mode.AddressList != NULL) {\r
+ FreePool (Ip6Mode.AddressList);\r
+ }\r
\r
- Udp->Configure (Udp, NULL);\r
- return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);\r
+ if (Ip6Mode.GroupTable != NULL) {\r
+ FreePool (Ip6Mode.GroupTable);\r
+ }\r
+\r
+ if (Ip6Mode.RouteTable != NULL) {\r
+ FreePool (Ip6Mode.RouteTable);\r
+ }\r
+\r
+ if (Ip6Mode.NeighborCache != NULL) {\r
+ FreePool (Ip6Mode.NeighborCache);\r
+ }\r
+\r
+ if (Ip6Mode.PrefixTable != NULL) {\r
+ FreePool (Ip6Mode.PrefixTable);\r
+ }\r
+\r
+ if (Ip6Mode.IcmpTypeList != NULL) {\r
+ FreePool (Ip6Mode.IcmpTypeList);\r
+ }\r
+\r
+ if (Ip6Mode.IsConfigured) {\r
+ Udp->Configure (Udp, NULL);\r
+ return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);\r
+ }\r
}\r
}\r
\r
@param TokensMap All DNS transmittal Tokens entry. \r
@param Identification Identification for queried packet. \r
@param Type Type for queried packet.\r
+ @param Class Class for queried packet.\r
@param Item Return corresponding Token entry.\r
\r
@retval TRUE The response is valid.\r
IN NET_MAP *TokensMap,\r
IN UINT16 Identification,\r
IN UINT16 Type,\r
+ IN UINT16 Class,\r
OUT NET_MAP_ITEM **Item\r
)\r
{\r
DnsHeader = (DNS_HEADER *) TxString;\r
QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));\r
QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
-\r
- DnsHeader->Identification = NTOHS (DnsHeader->Identification);\r
- QuerySection->Type = NTOHS (QuerySection->Type);\r
\r
- if (DnsHeader->Identification == Identification && QuerySection->Type == Type) {\r
+ if (NTOHS (DnsHeader->Identification) == Identification &&\r
+ NTOHS (QuerySection->Type) == Type && \r
+ NTOHS (QuerySection->Class) == Class) {\r
return TRUE;\r
}\r
} \r
}\r
\r
- *Item =NULL;\r
+ *Item = NULL;\r
\r
return FALSE;\r
}\r
DNS6_TOKEN_ENTRY *Dns6TokenEntry;\r
\r
UINT32 IpCount;\r
+ UINT32 RRCount;\r
UINT32 AnswerSectionNum;\r
+ UINT32 CNameTtl;\r
\r
EFI_IPv4_ADDRESS *HostAddr4;\r
EFI_IPv6_ADDRESS *HostAddr6;\r
EFI_DNS4_CACHE_ENTRY *Dns4CacheEntry;\r
EFI_DNS6_CACHE_ENTRY *Dns6CacheEntry;\r
\r
+ DNS_RESOURCE_RECORD *Dns4RR;\r
+ DNS6_RESOURCE_RECORD *Dns6RR;\r
+\r
EFI_STATUS Status;\r
\r
EFI_TPL OldTpl;\r
Dns6TokenEntry = NULL;\r
\r
IpCount = 0;\r
+ RRCount = 0;\r
AnswerSectionNum = 0;\r
+ CNameTtl = 0;\r
\r
HostAddr4 = NULL;\r
HostAddr6 = NULL;\r
\r
Dns4CacheEntry = NULL;\r
Dns6CacheEntry = NULL;\r
+ \r
+ Dns4RR = NULL;\r
+ Dns6RR = NULL;\r
\r
*Completed = TRUE;\r
Status = EFI_SUCCESS;\r
// Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.\r
//\r
if (Instance->Service->IpVersion == IP_VERSION_4) {\r
- if (!IsValidDnsResponse (&Instance->Dns4TxTokens, DnsHeader->Identification, QuerySection->Type, &Item)) {\r
+ if (!IsValidDnsResponse (\r
+ &Instance->Dns4TxTokens, \r
+ DnsHeader->Identification, \r
+ QuerySection->Type,\r
+ QuerySection->Class,\r
+ &Item\r
+ )) {\r
*Completed = FALSE;\r
Status = EFI_ABORTED;\r
goto ON_EXIT;\r
ASSERT (Item != NULL);\r
Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
} else {\r
- if (!IsValidDnsResponse (&Instance->Dns6TxTokens, DnsHeader->Identification, QuerySection->Type, &Item)) {\r
+ if (!IsValidDnsResponse (\r
+ &Instance->Dns6TxTokens, \r
+ DnsHeader->Identification, \r
+ QuerySection->Type,\r
+ QuerySection->Class,\r
+ &Item\r
+ )) {\r
*Completed = FALSE;\r
Status = EFI_ABORTED;\r
goto ON_EXIT;\r
// Continue Check Some Errors.\r
//\r
if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \\r
- DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE || QuerySection->Class != DNS_CLASS_INET) {\r
- Status = EFI_ABORTED;\r
- goto ON_EXIT;\r
- }\r
-\r
- //\r
- // Free the sending packet.\r
- //\r
- if (Item->Value != NULL) {\r
- NetbufFree ((NET_BUF *) (Item->Value));\r
+ DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {\r
+ //\r
+ // The domain name referenced in the query does not exist.\r
+ //\r
+ if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {\r
+ Status = EFI_NOT_FOUND; \r
+ } else {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+ \r
+ goto ON_COMPLETE;\r
}\r
\r
//\r
- // Check the Query type, do some buffer allocations.\r
+ // Do some buffer allocations.\r
//\r
- if (QuerySection->Type == DNS_TYPE_A) {\r
- Dns4TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
- ASSERT (Dns4TokenEntry->Token->RspData.H2AData != NULL);\r
- Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
- ASSERT (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL);\r
- } else if (QuerySection->Type == DNS_TYPE_AAAA) {\r
- Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
- ASSERT (Dns6TokenEntry->Token->RspData.H2AData != NULL);\r
- Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
- ASSERT (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL);\r
+ if (Instance->Service->IpVersion == IP_VERSION_4) {\r
+ ASSERT (Dns4TokenEntry != NULL);\r
+\r
+ if (Dns4TokenEntry->GeneralLookUp) {\r
+ //\r
+ // It's the GeneralLookUp querying.\r
+ //\r
+ Dns4TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof (DNS_RESOURCE_RECORD));\r
+ if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
+ if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ } else {\r
+ //\r
+ // It's not the GeneralLookUp querying. Check the Query type.\r
+ //\r
+ if (QuerySection->Type == DNS_TYPE_A) {\r
+ Dns4TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
+ if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
+ if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
} else {\r
- Status = EFI_UNSUPPORTED;\r
- goto ON_EXIT;\r
+ ASSERT (Dns6TokenEntry != NULL);\r
+\r
+ if (Dns6TokenEntry->GeneralLookUp) {\r
+ //\r
+ // It's the GeneralLookUp querying.\r
+ //\r
+ Dns6TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof (DNS_RESOURCE_RECORD));\r
+ if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
+ if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ } else {\r
+ //\r
+ // It's not the GeneralLookUp querying. Check the Query type.\r
+ //\r
+ if (QuerySection->Type == DNS_TYPE_AAAA) {\r
+ Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
+ if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
+ if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
}\r
\r
+ Status = EFI_NOT_FOUND;\r
+\r
//\r
// Processing AnswerSection.\r
//\r
AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);\r
AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);\r
\r
- ASSERT (AnswerSection->Class == DNS_CLASS_INET);\r
+ //\r
+ // Check whether it's the GeneralLookUp querying.\r
+ //\r
+ if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {\r
+ Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;\r
+ AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
+\r
+ //\r
+ // Fill the ResourceRecord.\r
+ //\r
+ Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
+ if (Dns4RR[RRCount].QName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
+ Dns4RR[RRCount].QType = AnswerSection->Type;\r
+ Dns4RR[RRCount].QClass = AnswerSection->Class;\r
+ Dns4RR[RRCount].TTL = AnswerSection->Ttl;\r
+ Dns4RR[RRCount].DataLength = AnswerSection->DataLength;\r
+ Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);\r
+ if (Dns4RR[RRCount].RData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);\r
+ \r
+ RRCount ++;\r
+ Status = EFI_SUCCESS;\r
+ } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {\r
+ Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;\r
+ AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
\r
- if (AnswerSection->Type == QuerySection->Type) {\r
+ //\r
+ // Fill the ResourceRecord.\r
+ //\r
+ Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
+ if (Dns6RR[RRCount].QName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
+ Dns6RR[RRCount].QType = AnswerSection->Type;\r
+ Dns6RR[RRCount].QClass = AnswerSection->Class;\r
+ Dns6RR[RRCount].TTL = AnswerSection->Ttl;\r
+ Dns6RR[RRCount].DataLength = AnswerSection->DataLength;\r
+ Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);\r
+ if (Dns6RR[RRCount].RData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+ CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);\r
+ \r
+ RRCount ++;\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ //\r
+ // It's not the GeneralLookUp querying. \r
+ // Check the Query type, parse the response packet.\r
+ //\r
switch (AnswerSection->Type) {\r
case DNS_TYPE_A:\r
//\r
// This is address entry, get Data.\r
//\r
- ASSERT (AnswerSection->DataLength == 4);\r
+ ASSERT (Dns4TokenEntry != NULL && AnswerSection->DataLength == 4);\r
\r
HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;\r
AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
\r
- //\r
- // Update DNS cache dynamically.\r
- //\r
- if (Dns4CacheEntry != NULL) {\r
- if (Dns4CacheEntry->HostName != NULL) {\r
- FreePool (Dns4CacheEntry->HostName);\r
- }\r
-\r
- if (Dns4CacheEntry->IpAddress != NULL) {\r
- FreePool (Dns4CacheEntry->IpAddress);\r
- }\r
- \r
- FreePool (Dns4CacheEntry);\r
- }\r
-\r
// \r
- // Allocate new CacheEntry pool.\r
+ // Allocate new CacheEntry pool to update DNS cache dynamically.\r
//\r
Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));\r
- ASSERT (Dns4CacheEntry != NULL);\r
+ if (Dns4CacheEntry == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
- ASSERT (Dns4CacheEntry->HostName != NULL);\r
+ if (Dns4CacheEntry->HostName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));\r
- ASSERT (Dns4CacheEntry->IpAddress != NULL);\r
+ if (Dns4CacheEntry->IpAddress == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
- Dns4CacheEntry->Timeout = AnswerSection->Ttl;\r
+\r
+ if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
+ Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
+ } else {\r
+ Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
+ }\r
\r
- UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry); \r
+ UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);\r
\r
- IpCount ++; \r
+ // \r
+ // Free allocated CacheEntry pool.\r
+ //\r
+ FreePool (Dns4CacheEntry->HostName);\r
+ Dns4CacheEntry->HostName = NULL;\r
+ \r
+ FreePool (Dns4CacheEntry->IpAddress);\r
+ Dns4CacheEntry->IpAddress = NULL;\r
+\r
+ FreePool (Dns4CacheEntry);\r
+ Dns4CacheEntry = NULL;\r
+\r
+ IpCount ++;\r
+ Status = EFI_SUCCESS;\r
break;\r
case DNS_TYPE_AAAA:\r
//\r
// This is address entry, get Data.\r
//\r
- ASSERT (AnswerSection->DataLength == 16);\r
+ ASSERT (Dns6TokenEntry != NULL && AnswerSection->DataLength == 16);\r
\r
HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;\r
AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
\r
- //\r
- // Update DNS cache dynamically.\r
- //\r
- if (Dns6CacheEntry != NULL) {\r
- if (Dns6CacheEntry->HostName != NULL) {\r
- FreePool (Dns6CacheEntry->HostName);\r
- }\r
-\r
- if (Dns6CacheEntry->IpAddress != NULL) {\r
- FreePool (Dns6CacheEntry->IpAddress);\r
- }\r
- \r
- FreePool (Dns6CacheEntry);\r
- }\r
-\r
// \r
- // Allocate new CacheEntry pool.\r
+ // Allocate new CacheEntry pool to update DNS cache dynamically.\r
//\r
Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));\r
- ASSERT (Dns6CacheEntry != NULL);\r
+ if (Dns6CacheEntry == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
- ASSERT (Dns6CacheEntry->HostName != NULL);\r
+ if (Dns6CacheEntry->HostName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));\r
- ASSERT (Dns6CacheEntry->IpAddress != NULL);\r
+ if (Dns6CacheEntry->IpAddress == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
- Dns6CacheEntry->Timeout = AnswerSection->Ttl;\r
+\r
+ if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
+ Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
+ } else {\r
+ Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
+ }\r
+ \r
+ UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);\r
+\r
+ // \r
+ // Free allocated CacheEntry pool.\r
+ //\r
+ FreePool (Dns6CacheEntry->HostName);\r
+ Dns6CacheEntry->HostName = NULL;\r
\r
- UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry); \r
+ FreePool (Dns6CacheEntry->IpAddress);\r
+ Dns6CacheEntry->IpAddress = NULL;\r
+\r
+ FreePool (Dns6CacheEntry);\r
+ Dns6CacheEntry = NULL;\r
\r
IpCount ++;\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ case DNS_TYPE_CNAME:\r
+ //\r
+ // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME \r
+ // record in the response and restart the query at the domain name specified in the data field of the \r
+ // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.\r
+ //\r
+ CNameTtl = AnswerSection->Ttl;\r
break;\r
default:\r
Status = EFI_UNSUPPORTED;\r
AnswerSectionNum ++;\r
}\r
\r
- if (QuerySection->Type == DNS_TYPE_A) {\r
- Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
- } else if (QuerySection->Type == DNS_TYPE_AAAA) {\r
- Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
- }\r
+ if (Instance->Service->IpVersion == IP_VERSION_4) {\r
+ ASSERT (Dns4TokenEntry != NULL);\r
+ \r
+ if (Dns4TokenEntry->GeneralLookUp) {\r
+ Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
+ } else {\r
+ if (QuerySection->Type == DNS_TYPE_A) {\r
+ Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+ } else {\r
+ ASSERT (Dns6TokenEntry != NULL);\r
\r
+ if (Dns6TokenEntry->GeneralLookUp) {\r
+ Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
+ } else {\r
+ if (QuerySection->Type == DNS_TYPE_AAAA) {\r
+ Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
+ } else {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+ }\r
+ \r
+ON_COMPLETE:\r
//\r
- // Parsing is complete, SignalEvent here.\r
+ // Parsing is complete, free the sending packet and signal Event here.\r
//\r
+ if (Item != NULL && Item->Value != NULL) {\r
+ NetbufFree ((NET_BUF *) (Item->Value));\r
+ }\r
+ \r
if (Instance->Service->IpVersion == IP_VERSION_4) {\r
+ ASSERT (Dns4TokenEntry != NULL);\r
Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);\r
- Dns4TokenEntry->Token->Status = EFI_SUCCESS;\r
+ Dns4TokenEntry->Token->Status = Status;\r
if (Dns4TokenEntry->Token->Event != NULL) {\r
gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
DispatchDpc ();\r
}\r
} else {\r
+ ASSERT (Dns6TokenEntry != NULL);\r
Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);\r
- Dns6TokenEntry->Token->Status = EFI_SUCCESS;\r
+ Dns6TokenEntry->Token->Status = Status;\r
if (Dns6TokenEntry->Token->Event != NULL) {\r
gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
DispatchDpc ();\r
}\r
}\r
\r
- // \r
- // Free allocated CacheEntry pool.\r
- //\r
- if (Dns4CacheEntry != NULL) {\r
- if (Dns4CacheEntry->HostName != NULL) {\r
- FreePool (Dns4CacheEntry->HostName);\r
- }\r
-\r
- if (Dns4CacheEntry->IpAddress != NULL) {\r
- FreePool (Dns4CacheEntry->IpAddress);\r
- }\r
-\r
- FreePool (Dns4CacheEntry);\r
- }\r
- \r
- if (Dns6CacheEntry != NULL) {\r
- if (Dns6CacheEntry->HostName != NULL) {\r
- FreePool (Dns6CacheEntry->HostName);\r
- }\r
-\r
- if (Dns6CacheEntry->IpAddress != NULL) {\r
- FreePool (Dns6CacheEntry->IpAddress);\r
- }\r
- \r
- FreePool (Dns6CacheEntry);\r
- }\r
-\r
ON_EXIT:\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
ASSERT (Packet != NULL);\r
+\r
+ if (Packet->TotalSize <= sizeof (DNS_HEADER)) {\r
+ goto ON_EXIT;\r
+ }\r
\r
RcvString = NetbufGetByte (Packet, 0, NULL);\r
ASSERT (RcvString != NULL);\r
//\r
ParseDnsResponse (Instance, RcvString, &Completed);\r
\r
- ON_EXIT:\r
+ON_EXIT:\r
\r
- if (Packet != NULL) {\r
- NetbufFree (Packet);\r
- }\r
+ if (Packet != NULL) {\r
+ NetbufFree (Packet);\r
+ }\r
\r
- if (!Completed) {\r
- UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
- }\r
+ if (!Completed) {\r
+ UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
+ }\r
}\r
\r
/**\r
}\r
\r
/**\r
- Construct the Packet to query Ip.\r
+ Construct the Packet according query section.\r
\r
@param Instance The DNS instance\r
- @param HostName Queried HostName \r
- @param Type DNS query Type\r
- @param Packet The packet for querying Ip\r
+ @param QueryName Queried Name \r
+ @param Type Queried Type \r
+ @param Class Queried Class \r
+ @param Packet The packet for query\r
\r
@retval EFI_SUCCESS The packet is constructed.\r
@retval Others Failed to construct the Packet.\r
\r
**/\r
EFI_STATUS\r
-ConstructDNSQueryIp (\r
+ConstructDNSQuery (\r
IN DNS_INSTANCE *Instance,\r
- IN CHAR16 *HostName,\r
+ IN CHAR8 *QueryName,\r
IN UINT16 Type,\r
+ IN UINT16 Class,\r
OUT NET_BUF **Packet\r
)\r
{\r
NET_FRAGMENT Frag;\r
DNS_HEADER *DnsHeader;\r
- CHAR8 *QueryName;\r
- DNS_QUERY_SECTION *QuerySection;\r
- CHAR8 *Header;\r
- CHAR8 *Tail;\r
- UINTN Len;\r
- UINTN Index;\r
- \r
+ DNS_QUERY_SECTION *DnsQuery;\r
\r
- Frag.Bulk = AllocatePool (DNS_DEFAULT_BLKSIZE * sizeof (UINT8));\r
+ //\r
+ // Messages carried by UDP are restricted to 512 bytes (not counting the IP\r
+ // or UDP headers).\r
+ //\r
+ Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));\r
if (Frag.Bulk == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
// Fill Query name\r
//\r
- QueryName = (CHAR8 *) (Frag.Bulk + Frag.Len);\r
- Header = QueryName;\r
- Tail = Header + 1;\r
- Len = 0;\r
- for (Index = 0; HostName[Index] != 0; Index++) {\r
- *Tail = (CHAR8) HostName[Index];\r
- if (*Tail == '.') {\r
- *Header = (CHAR8) Len;\r
- Header = Tail;\r
- Tail ++;\r
- Len = 0;\r
- } else {\r
- Tail++;\r
- Len++;\r
- }\r
- }\r
- *Header = (CHAR8) Len;\r
- *Tail = 0;\r
- Frag.Len = (UINT32) (Frag.Len + StrLen (HostName) + 2); /// 1 for header, 1 for tail.\r
-\r
+ CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));\r
+ Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));\r
+ *(Frag.Bulk + Frag.Len) = 0;\r
+ Frag.Len ++;\r
+ \r
//\r
// Rest query section\r
//\r
- QuerySection = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);\r
- QuerySection->Type = Type;\r
- QuerySection->Class = DNS_CLASS_INET;\r
+ DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);\r
\r
- QuerySection->Type = HTONS (QuerySection->Type);\r
- QuerySection->Class = HTONS (QuerySection->Class);\r
+ DnsQuery->Type = HTONS (Type);\r
+ DnsQuery->Class = HTONS (Class);\r
\r
- Frag.Len += sizeof (*QuerySection);\r
+ Frag.Len += sizeof (*DnsQuery);\r
\r
//\r
// Wrap the Frag in a net buffer.\r
Entry = mDriverData->Dns4CacheList.ForwardLink;\r
while (Entry != &mDriverData->Dns4CacheList) {\r
Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
- if (Item4->DnsCache.Timeout<=0) {\r
+ if (Item4->DnsCache.Timeout == 0) {\r
RemoveEntryList (&Item4->AllCacheLink);\r
Entry = mDriverData->Dns4CacheList.ForwardLink;\r
} else {\r
Entry = mDriverData->Dns6CacheList.ForwardLink;\r
while (Entry != &mDriverData->Dns6CacheList) {\r
Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
- if (Item6->DnsCache.Timeout<=0) {\r
+ if (Item6->DnsCache.Timeout == 0) {\r
RemoveEntryList (&Item6->AllCacheLink);\r
Entry = mDriverData->Dns6CacheList.ForwardLink;\r
} else {\r