DnsImpl.c 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243
  1. /** @file
  2. DnsDxe support functions implementation.
  3. Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "DnsImpl.h"
  7. /**
  8. Remove TokenEntry from TokenMap.
  9. @param[in] TokenMap All DNSv4 Token entrys.
  10. @param[in] TokenEntry TokenEntry need to be removed.
  11. @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.
  12. @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
  13. **/
  14. EFI_STATUS
  15. Dns4RemoveTokenEntry (
  16. IN NET_MAP *TokenMap,
  17. IN DNS4_TOKEN_ENTRY *TokenEntry
  18. )
  19. {
  20. NET_MAP_ITEM *Item;
  21. //
  22. // Find the TokenEntry first.
  23. //
  24. Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);
  25. if (Item != NULL) {
  26. //
  27. // Remove the TokenEntry if it's found in the map.
  28. //
  29. NetMapRemoveItem (TokenMap, Item, NULL);
  30. return EFI_SUCCESS;
  31. }
  32. return EFI_NOT_FOUND;
  33. }
  34. /**
  35. Remove TokenEntry from TokenMap.
  36. @param[in] TokenMap All DNSv6 Token entrys.
  37. @param[in] TokenEntry TokenEntry need to be removed.
  38. @retval EFI_SUCCESS Remove TokenEntry from TokenMap sucessfully.
  39. @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
  40. **/
  41. EFI_STATUS
  42. Dns6RemoveTokenEntry (
  43. IN NET_MAP *TokenMap,
  44. IN DNS6_TOKEN_ENTRY *TokenEntry
  45. )
  46. {
  47. NET_MAP_ITEM *Item;
  48. //
  49. // Find the TokenEntry first.
  50. //
  51. Item = NetMapFindKey (TokenMap, (VOID *) TokenEntry);
  52. if (Item != NULL) {
  53. //
  54. // Remove the TokenEntry if it's found in the map.
  55. //
  56. NetMapRemoveItem (TokenMap, Item, NULL);
  57. return EFI_SUCCESS;
  58. }
  59. return EFI_NOT_FOUND;
  60. }
  61. /**
  62. This function cancle the token specified by Arg in the Map.
  63. @param[in] Map Pointer to the NET_MAP.
  64. @param[in] Item Pointer to the NET_MAP_ITEM.
  65. @param[in] Arg Pointer to the token to be cancelled. If NULL, all
  66. the tokens in this Map will be cancelled.
  67. This parameter is optional and may be NULL.
  68. @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token
  69. is not the same as that in the Item, if Arg is not
  70. NULL.
  71. @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is
  72. cancelled.
  73. **/
  74. EFI_STATUS
  75. EFIAPI
  76. Dns4CancelTokens (
  77. IN NET_MAP *Map,
  78. IN NET_MAP_ITEM *Item,
  79. IN VOID *Arg OPTIONAL
  80. )
  81. {
  82. DNS4_TOKEN_ENTRY *TokenEntry;
  83. NET_BUF *Packet;
  84. UDP_IO *UdpIo;
  85. if ((Arg != NULL) && (Item->Key != Arg)) {
  86. return EFI_SUCCESS;
  87. }
  88. if (Item->Value != NULL) {
  89. //
  90. // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
  91. // Item->Value.
  92. //
  93. Packet = (NET_BUF *) (Item->Value);
  94. UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));
  95. UdpIoCancelSentDatagram (UdpIo, Packet);
  96. }
  97. //
  98. // Remove TokenEntry from Dns4TxTokens.
  99. //
  100. TokenEntry = (DNS4_TOKEN_ENTRY *) Item->Key;
  101. if (Dns4RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {
  102. TokenEntry->Token->Status = EFI_ABORTED;
  103. gBS->SignalEvent (TokenEntry->Token->Event);
  104. DispatchDpc ();
  105. }
  106. if (Arg != NULL) {
  107. return EFI_ABORTED;
  108. }
  109. return EFI_SUCCESS;
  110. }
  111. /**
  112. This function cancle the token specified by Arg in the Map.
  113. @param[in] Map Pointer to the NET_MAP.
  114. @param[in] Item Pointer to the NET_MAP_ITEM.
  115. @param[in] Arg Pointer to the token to be cancelled. If NULL, all
  116. the tokens in this Map will be cancelled.
  117. This parameter is optional and may be NULL.
  118. @retval EFI_SUCCESS The token is cancelled if Arg is NULL, or the token
  119. is not the same as that in the Item, if Arg is not
  120. NULL.
  121. @retval EFI_ABORTED Arg is not NULL, and the token specified by Arg is
  122. cancelled.
  123. **/
  124. EFI_STATUS
  125. EFIAPI
  126. Dns6CancelTokens (
  127. IN NET_MAP *Map,
  128. IN NET_MAP_ITEM *Item,
  129. IN VOID *Arg OPTIONAL
  130. )
  131. {
  132. DNS6_TOKEN_ENTRY *TokenEntry;
  133. NET_BUF *Packet;
  134. UDP_IO *UdpIo;
  135. if ((Arg != NULL) && (Item->Key != Arg)) {
  136. return EFI_SUCCESS;
  137. }
  138. if (Item->Value != NULL) {
  139. //
  140. // If the TokenEntry is a transmit TokenEntry, the corresponding Packet is recorded in
  141. // Item->Value.
  142. //
  143. Packet = (NET_BUF *) (Item->Value);
  144. UdpIo = (UDP_IO *) (*((UINTN *) &Packet->ProtoData[0]));
  145. UdpIoCancelSentDatagram (UdpIo, Packet);
  146. }
  147. //
  148. // Remove TokenEntry from Dns6TxTokens.
  149. //
  150. TokenEntry = (DNS6_TOKEN_ENTRY *) Item->Key;
  151. if (Dns6RemoveTokenEntry (Map, TokenEntry) == EFI_SUCCESS) {
  152. TokenEntry->Token->Status = EFI_ABORTED;
  153. gBS->SignalEvent (TokenEntry->Token->Event);
  154. DispatchDpc ();
  155. }
  156. if (Arg != NULL) {
  157. return EFI_ABORTED;
  158. }
  159. return EFI_SUCCESS;
  160. }
  161. /**
  162. Get the TokenEntry from the TokensMap.
  163. @param[in] TokensMap All DNSv4 Token entrys
  164. @param[in] Token Pointer to the token to be get.
  165. @param[out] TokenEntry Pointer to TokenEntry corresponding Token.
  166. @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.
  167. @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
  168. **/
  169. EFI_STATUS
  170. EFIAPI
  171. GetDns4TokenEntry (
  172. IN NET_MAP *TokensMap,
  173. IN EFI_DNS4_COMPLETION_TOKEN *Token,
  174. OUT DNS4_TOKEN_ENTRY **TokenEntry
  175. )
  176. {
  177. LIST_ENTRY *Entry;
  178. NET_MAP_ITEM *Item;
  179. NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
  180. Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
  181. *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);
  182. if ((*TokenEntry)->Token == Token) {
  183. return EFI_SUCCESS;
  184. }
  185. }
  186. *TokenEntry = NULL;
  187. return EFI_NOT_FOUND;
  188. }
  189. /**
  190. Get the TokenEntry from the TokensMap.
  191. @param[in] TokensMap All DNSv6 Token entrys
  192. @param[in] Token Pointer to the token to be get.
  193. @param[out] TokenEntry Pointer to TokenEntry corresponding Token.
  194. @retval EFI_SUCCESS Get the TokenEntry from the TokensMap sucessfully.
  195. @retval EFI_NOT_FOUND TokenEntry is not found in TokenMap.
  196. **/
  197. EFI_STATUS
  198. EFIAPI
  199. GetDns6TokenEntry (
  200. IN NET_MAP *TokensMap,
  201. IN EFI_DNS6_COMPLETION_TOKEN *Token,
  202. OUT DNS6_TOKEN_ENTRY **TokenEntry
  203. )
  204. {
  205. LIST_ENTRY *Entry;
  206. NET_MAP_ITEM *Item;
  207. NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
  208. Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
  209. *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);
  210. if ((*TokenEntry)->Token == Token) {
  211. return EFI_SUCCESS;
  212. }
  213. }
  214. *TokenEntry =NULL;
  215. return EFI_NOT_FOUND;
  216. }
  217. /**
  218. Cancel DNS4 tokens from the DNS4 instance.
  219. @param[in] Instance Pointer to the DNS instance context data.
  220. @param[in] Token Pointer to the token to be canceled. If NULL, all
  221. tokens in this instance will be cancelled.
  222. This parameter is optional and may be NULL.
  223. @retval EFI_SUCCESS The Token is cancelled.
  224. @retval EFI_NOT_FOUND The Token is not found.
  225. **/
  226. EFI_STATUS
  227. Dns4InstanceCancelToken (
  228. IN DNS_INSTANCE *Instance,
  229. IN EFI_DNS4_COMPLETION_TOKEN *Token
  230. )
  231. {
  232. EFI_STATUS Status;
  233. DNS4_TOKEN_ENTRY *TokenEntry;
  234. TokenEntry = NULL;
  235. if(Token != NULL ) {
  236. Status = GetDns4TokenEntry (&Instance->Dns4TxTokens, Token, &TokenEntry);
  237. if (EFI_ERROR (Status)) {
  238. return Status;
  239. }
  240. } else {
  241. TokenEntry = NULL;
  242. }
  243. //
  244. // Cancel this TokenEntry from the Dns4TxTokens map.
  245. //
  246. Status = NetMapIterate (&Instance->Dns4TxTokens, Dns4CancelTokens, TokenEntry);
  247. if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {
  248. //
  249. // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
  250. // the Dns4TxTokens and returns success.
  251. //
  252. if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {
  253. Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);
  254. }
  255. return EFI_SUCCESS;
  256. }
  257. ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns4TxTokens)));
  258. if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {
  259. Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);
  260. }
  261. return EFI_SUCCESS;
  262. }
  263. /**
  264. Cancel DNS6 tokens from the DNS6 instance.
  265. @param[in] Instance Pointer to the DNS instance context data.
  266. @param[in] Token Pointer to the token to be canceled. If NULL, all
  267. tokens in this instance will be cancelled.
  268. This parameter is optional and may be NULL.
  269. @retval EFI_SUCCESS The Token is cancelled.
  270. @retval EFI_NOT_FOUND The Token is not found.
  271. **/
  272. EFI_STATUS
  273. Dns6InstanceCancelToken (
  274. IN DNS_INSTANCE *Instance,
  275. IN EFI_DNS6_COMPLETION_TOKEN *Token
  276. )
  277. {
  278. EFI_STATUS Status;
  279. DNS6_TOKEN_ENTRY *TokenEntry;
  280. TokenEntry = NULL;
  281. if(Token != NULL ) {
  282. Status = GetDns6TokenEntry (&Instance->Dns6TxTokens, Token, &TokenEntry);
  283. if (EFI_ERROR (Status)) {
  284. return Status;
  285. }
  286. } else {
  287. TokenEntry = NULL;
  288. }
  289. //
  290. // Cancel this TokenEntry from the Dns6TxTokens map.
  291. //
  292. Status = NetMapIterate (&Instance->Dns6TxTokens, Dns6CancelTokens, TokenEntry);
  293. if ((TokenEntry != NULL) && (Status == EFI_ABORTED)) {
  294. //
  295. // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
  296. // the Dns6TxTokens and returns success.
  297. //
  298. if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {
  299. Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);
  300. }
  301. return EFI_SUCCESS;
  302. }
  303. ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns6TxTokens)));
  304. if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {
  305. Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);
  306. }
  307. return EFI_SUCCESS;
  308. }
  309. /**
  310. Free the resource related to the configure parameters.
  311. @param Config The DNS configure data
  312. **/
  313. VOID
  314. Dns4CleanConfigure (
  315. IN OUT EFI_DNS4_CONFIG_DATA *Config
  316. )
  317. {
  318. if (Config->DnsServerList != NULL) {
  319. FreePool (Config->DnsServerList);
  320. }
  321. ZeroMem (Config, sizeof (EFI_DNS4_CONFIG_DATA));
  322. }
  323. /**
  324. Free the resource related to the configure parameters.
  325. @param Config The DNS configure data
  326. **/
  327. VOID
  328. Dns6CleanConfigure (
  329. IN OUT EFI_DNS6_CONFIG_DATA *Config
  330. )
  331. {
  332. if (Config->DnsServerList != NULL) {
  333. FreePool (Config->DnsServerList);
  334. }
  335. ZeroMem (Config, sizeof (EFI_DNS6_CONFIG_DATA));
  336. }
  337. /**
  338. Allocate memory for configure parameter such as timeout value for Dst,
  339. then copy the configure parameter from Src to Dst.
  340. @param[out] Dst The destination DHCP configure data.
  341. @param[in] Src The source DHCP configure data.
  342. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  343. @retval EFI_SUCCESS The configure is copied.
  344. **/
  345. EFI_STATUS
  346. Dns4CopyConfigure (
  347. OUT EFI_DNS4_CONFIG_DATA *Dst,
  348. IN EFI_DNS4_CONFIG_DATA *Src
  349. )
  350. {
  351. UINTN Len;
  352. UINT32 Index;
  353. CopyMem (Dst, Src, sizeof (*Dst));
  354. Dst->DnsServerList = NULL;
  355. //
  356. // Allocate a memory then copy DnsServerList to it
  357. //
  358. if (Src->DnsServerList != NULL) {
  359. Len = Src->DnsServerListCount * sizeof (EFI_IPv4_ADDRESS);
  360. Dst->DnsServerList = AllocatePool (Len);
  361. if (Dst->DnsServerList == NULL) {
  362. Dns4CleanConfigure (Dst);
  363. return EFI_OUT_OF_RESOURCES;
  364. }
  365. for (Index = 0; Index < Src->DnsServerListCount; Index++) {
  366. CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv4_ADDRESS));
  367. }
  368. }
  369. return EFI_SUCCESS;
  370. }
  371. /**
  372. Allocate memory for configure parameter such as timeout value for Dst,
  373. then copy the configure parameter from Src to Dst.
  374. @param[out] Dst The destination DHCP configure data.
  375. @param[in] Src The source DHCP configure data.
  376. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  377. @retval EFI_SUCCESS The configure is copied.
  378. **/
  379. EFI_STATUS
  380. Dns6CopyConfigure (
  381. OUT EFI_DNS6_CONFIG_DATA *Dst,
  382. IN EFI_DNS6_CONFIG_DATA *Src
  383. )
  384. {
  385. UINTN Len;
  386. UINT32 Index;
  387. CopyMem (Dst, Src, sizeof (*Dst));
  388. Dst->DnsServerList = NULL;
  389. //
  390. // Allocate a memory then copy DnsServerList to it
  391. //
  392. if (Src->DnsServerList != NULL) {
  393. Len = Src->DnsServerCount * sizeof (EFI_IPv6_ADDRESS);
  394. Dst->DnsServerList = AllocatePool (Len);
  395. if (Dst->DnsServerList == NULL) {
  396. Dns6CleanConfigure (Dst);
  397. return EFI_OUT_OF_RESOURCES;
  398. }
  399. for (Index = 0; Index < Src->DnsServerCount; Index++) {
  400. CopyMem (&Dst->DnsServerList[Index], &Src->DnsServerList[Index], sizeof (EFI_IPv6_ADDRESS));
  401. }
  402. }
  403. return EFI_SUCCESS;
  404. }
  405. /**
  406. Callback of Dns packet. Does nothing.
  407. @param Arg The context.
  408. **/
  409. VOID
  410. EFIAPI
  411. DnsDummyExtFree (
  412. IN VOID *Arg
  413. )
  414. {
  415. }
  416. /**
  417. Poll the UDP to get the IP4 default address, which may be retrieved
  418. by DHCP.
  419. The default time out value is 5 seconds. If IP has retrieved the default address,
  420. the UDP is reconfigured.
  421. @param Instance The DNS instance
  422. @param UdpIo The UDP_IO to poll
  423. @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
  424. @retval TRUE The default address is retrieved and UDP is reconfigured.
  425. @retval FALSE Some error occured.
  426. **/
  427. BOOLEAN
  428. Dns4GetMapping (
  429. IN DNS_INSTANCE *Instance,
  430. IN UDP_IO *UdpIo,
  431. IN EFI_UDP4_CONFIG_DATA *UdpCfgData
  432. )
  433. {
  434. DNS_SERVICE *Service;
  435. EFI_IP4_MODE_DATA Ip4Mode;
  436. EFI_UDP4_PROTOCOL *Udp;
  437. EFI_STATUS Status;
  438. ASSERT (Instance->Dns4CfgData.UseDefaultSetting);
  439. Service = Instance->Service;
  440. Udp = UdpIo->Protocol.Udp4;
  441. Status = gBS->SetTimer (
  442. Service->TimerToGetMap,
  443. TimerRelative,
  444. DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
  445. );
  446. if (EFI_ERROR (Status)) {
  447. return FALSE;
  448. }
  449. while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
  450. Udp->Poll (Udp);
  451. if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&
  452. Ip4Mode.IsConfigured) {
  453. Udp->Configure (Udp, NULL);
  454. return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);
  455. }
  456. }
  457. return FALSE;
  458. }
  459. /**
  460. Configure the opened Udp6 instance until the corresponding Ip6 instance
  461. has been configured.
  462. @param Instance The DNS instance
  463. @param UdpIo The UDP_IO to poll
  464. @param UdpCfgData The UDP configure data to reconfigure the UDP_IO
  465. @retval TRUE Configure the Udp6 instance successfully.
  466. @retval FALSE Some error occured.
  467. **/
  468. BOOLEAN
  469. Dns6GetMapping (
  470. IN DNS_INSTANCE *Instance,
  471. IN UDP_IO *UdpIo,
  472. IN EFI_UDP6_CONFIG_DATA *UdpCfgData
  473. )
  474. {
  475. DNS_SERVICE *Service;
  476. EFI_IP6_MODE_DATA Ip6Mode;
  477. EFI_UDP6_PROTOCOL *Udp;
  478. EFI_STATUS Status;
  479. Service = Instance->Service;
  480. Udp = UdpIo->Protocol.Udp6;
  481. Status = gBS->SetTimer (
  482. Service->TimerToGetMap,
  483. TimerRelative,
  484. DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
  485. );
  486. if (EFI_ERROR (Status)) {
  487. return FALSE;
  488. }
  489. while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {
  490. Udp->Poll (Udp);
  491. if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL))) {
  492. if (Ip6Mode.AddressList != NULL) {
  493. FreePool (Ip6Mode.AddressList);
  494. }
  495. if (Ip6Mode.GroupTable != NULL) {
  496. FreePool (Ip6Mode.GroupTable);
  497. }
  498. if (Ip6Mode.RouteTable != NULL) {
  499. FreePool (Ip6Mode.RouteTable);
  500. }
  501. if (Ip6Mode.NeighborCache != NULL) {
  502. FreePool (Ip6Mode.NeighborCache);
  503. }
  504. if (Ip6Mode.PrefixTable != NULL) {
  505. FreePool (Ip6Mode.PrefixTable);
  506. }
  507. if (Ip6Mode.IcmpTypeList != NULL) {
  508. FreePool (Ip6Mode.IcmpTypeList);
  509. }
  510. if (!Ip6Mode.IsStarted || Ip6Mode.IsConfigured) {
  511. Udp->Configure (Udp, NULL);
  512. if (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS) {
  513. return TRUE;
  514. }
  515. }
  516. }
  517. }
  518. return FALSE;
  519. }
  520. /**
  521. Configure the UDP.
  522. @param Instance The DNS session
  523. @param UdpIo The UDP_IO instance
  524. @retval EFI_SUCCESS The UDP is successfully configured for the
  525. session.
  526. **/
  527. EFI_STATUS
  528. Dns4ConfigUdp (
  529. IN DNS_INSTANCE *Instance,
  530. IN UDP_IO *UdpIo
  531. )
  532. {
  533. EFI_DNS4_CONFIG_DATA *Config;
  534. EFI_UDP4_CONFIG_DATA UdpConfig;
  535. EFI_STATUS Status;
  536. Config = &Instance->Dns4CfgData;
  537. UdpConfig.AcceptBroadcast = FALSE;
  538. UdpConfig.AcceptPromiscuous = FALSE;
  539. UdpConfig.AcceptAnyPort = FALSE;
  540. UdpConfig.AllowDuplicatePort = FALSE;
  541. UdpConfig.TypeOfService = 0;
  542. UdpConfig.TimeToLive = 128;
  543. UdpConfig.DoNotFragment = FALSE;
  544. UdpConfig.ReceiveTimeout = 0;
  545. UdpConfig.TransmitTimeout = 0;
  546. UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
  547. UdpConfig.SubnetMask = Config->SubnetMask;
  548. UdpConfig.StationPort = Config->LocalPort;
  549. UdpConfig.RemotePort = DNS_SERVER_PORT;
  550. CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv4_ADDRESS));
  551. CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v4, sizeof (EFI_IPv4_ADDRESS));
  552. Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);
  553. if ((Status == EFI_NO_MAPPING) && Dns4GetMapping (Instance, UdpIo, &UdpConfig)) {
  554. return EFI_SUCCESS;
  555. }
  556. return Status;
  557. }
  558. /**
  559. Configure the UDP.
  560. @param Instance The DNS session
  561. @param UdpIo The UDP_IO instance
  562. @retval EFI_SUCCESS The UDP is successfully configured for the
  563. session.
  564. **/
  565. EFI_STATUS
  566. Dns6ConfigUdp (
  567. IN DNS_INSTANCE *Instance,
  568. IN UDP_IO *UdpIo
  569. )
  570. {
  571. EFI_DNS6_CONFIG_DATA *Config;
  572. EFI_UDP6_CONFIG_DATA UdpConfig;
  573. EFI_STATUS Status;
  574. Config = &Instance->Dns6CfgData;
  575. UdpConfig.AcceptPromiscuous = FALSE;
  576. UdpConfig.AcceptAnyPort = FALSE;
  577. UdpConfig.AllowDuplicatePort = FALSE;
  578. UdpConfig.TrafficClass = 0;
  579. UdpConfig.HopLimit = 128;
  580. UdpConfig.ReceiveTimeout = 0;
  581. UdpConfig.TransmitTimeout = 0;
  582. UdpConfig.StationPort = Config->LocalPort;
  583. UdpConfig.RemotePort = DNS_SERVER_PORT;
  584. CopyMem (&UdpConfig.StationAddress, &Config->StationIp, sizeof (EFI_IPv6_ADDRESS));
  585. CopyMem (&UdpConfig.RemoteAddress, &Instance->SessionDnsServer.v6, sizeof (EFI_IPv6_ADDRESS));
  586. Status = UdpIo->Protocol.Udp6->Configure (UdpIo->Protocol.Udp6, &UdpConfig);
  587. if ((Status == EFI_NO_MAPPING) && Dns6GetMapping (Instance, UdpIo, &UdpConfig)) {
  588. return EFI_SUCCESS;
  589. }
  590. return Status;
  591. }
  592. /**
  593. Update Dns4 cache to shared list of caches of all DNSv4 instances.
  594. @param Dns4CacheList All Dns4 cache list.
  595. @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
  596. If TRUE, this function will delete matching DNS Cache entry.
  597. @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
  598. If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
  599. @param DnsCacheEntry Entry Pointer to DNS Cache entry.
  600. @retval EFI_SUCCESS Update Dns4 cache successfully.
  601. @retval Others Failed to update Dns4 cache.
  602. **/
  603. EFI_STATUS
  604. EFIAPI
  605. UpdateDns4Cache (
  606. IN LIST_ENTRY *Dns4CacheList,
  607. IN BOOLEAN DeleteFlag,
  608. IN BOOLEAN Override,
  609. IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry
  610. )
  611. {
  612. DNS4_CACHE *NewDnsCache;
  613. DNS4_CACHE *Item;
  614. LIST_ENTRY *Entry;
  615. LIST_ENTRY *Next;
  616. NewDnsCache = NULL;
  617. Item = NULL;
  618. //
  619. // Search the database for the matching EFI_DNS_CACHE_ENTRY
  620. //
  621. NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4CacheList) {
  622. Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
  623. if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \
  624. CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS)) == 0) {
  625. //
  626. // This is the Dns cache entry
  627. //
  628. if (DeleteFlag) {
  629. //
  630. // Delete matching DNS Cache entry
  631. //
  632. RemoveEntryList (&Item->AllCacheLink);
  633. FreePool (Item->DnsCache.HostName);
  634. FreePool (Item->DnsCache.IpAddress);
  635. FreePool (Item);
  636. return EFI_SUCCESS;
  637. } else if (Override) {
  638. //
  639. // Update this one
  640. //
  641. Item->DnsCache.Timeout = DnsCacheEntry.Timeout;
  642. return EFI_SUCCESS;
  643. }else {
  644. return EFI_ACCESS_DENIED;
  645. }
  646. }
  647. }
  648. //
  649. // Add new one
  650. //
  651. NewDnsCache = AllocatePool (sizeof (DNS4_CACHE));
  652. if (NewDnsCache == NULL) {
  653. return EFI_OUT_OF_RESOURCES;
  654. }
  655. InitializeListHead (&NewDnsCache->AllCacheLink);
  656. NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));
  657. if (NewDnsCache->DnsCache.HostName == NULL) {
  658. FreePool (NewDnsCache);
  659. return EFI_OUT_OF_RESOURCES;
  660. }
  661. CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));
  662. NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv4_ADDRESS));
  663. if (NewDnsCache->DnsCache.IpAddress == NULL) {
  664. FreePool (NewDnsCache->DnsCache.HostName);
  665. FreePool (NewDnsCache);
  666. return EFI_OUT_OF_RESOURCES;
  667. }
  668. CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv4_ADDRESS));
  669. NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;
  670. InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);
  671. return EFI_SUCCESS;
  672. }
  673. /**
  674. Update Dns6 cache to shared list of caches of all DNSv6 instances.
  675. @param Dns6CacheList All Dns6 cache list.
  676. @param DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
  677. If TRUE, this function will delete matching DNS Cache entry.
  678. @param Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
  679. If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
  680. @param DnsCacheEntry Entry Pointer to DNS Cache entry.
  681. @retval EFI_SUCCESS Update Dns6 cache successfully.
  682. @retval Others Failed to update Dns6 cache.
  683. **/
  684. EFI_STATUS
  685. EFIAPI
  686. UpdateDns6Cache (
  687. IN LIST_ENTRY *Dns6CacheList,
  688. IN BOOLEAN DeleteFlag,
  689. IN BOOLEAN Override,
  690. IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry
  691. )
  692. {
  693. DNS6_CACHE *NewDnsCache;
  694. DNS6_CACHE *Item;
  695. LIST_ENTRY *Entry;
  696. LIST_ENTRY *Next;
  697. NewDnsCache = NULL;
  698. Item = NULL;
  699. //
  700. // Search the database for the matching EFI_DNS_CACHE_ENTRY
  701. //
  702. NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6CacheList) {
  703. Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
  704. if (StrCmp (DnsCacheEntry.HostName, Item->DnsCache.HostName) == 0 && \
  705. CompareMem (DnsCacheEntry.IpAddress, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS)) == 0) {
  706. //
  707. // This is the Dns cache entry
  708. //
  709. if (DeleteFlag) {
  710. //
  711. // Delete matching DNS Cache entry
  712. //
  713. RemoveEntryList (&Item->AllCacheLink);
  714. FreePool (Item->DnsCache.HostName);
  715. FreePool (Item->DnsCache.IpAddress);
  716. FreePool (Item);
  717. return EFI_SUCCESS;
  718. } else if (Override) {
  719. //
  720. // Update this one
  721. //
  722. Item->DnsCache.Timeout = DnsCacheEntry.Timeout;
  723. return EFI_SUCCESS;
  724. }else {
  725. return EFI_ACCESS_DENIED;
  726. }
  727. }
  728. }
  729. //
  730. // Add new one
  731. //
  732. NewDnsCache = AllocatePool (sizeof (DNS6_CACHE));
  733. if (NewDnsCache == NULL) {
  734. return EFI_OUT_OF_RESOURCES;
  735. }
  736. InitializeListHead (&NewDnsCache->AllCacheLink);
  737. NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));
  738. if (NewDnsCache->DnsCache.HostName == NULL) {
  739. FreePool (NewDnsCache);
  740. return EFI_OUT_OF_RESOURCES;
  741. }
  742. CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));
  743. NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv6_ADDRESS));
  744. if (NewDnsCache->DnsCache.IpAddress == NULL) {
  745. FreePool (NewDnsCache->DnsCache.HostName);
  746. FreePool (NewDnsCache);
  747. return EFI_OUT_OF_RESOURCES;
  748. }
  749. CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));
  750. NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;
  751. InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);
  752. return EFI_SUCCESS;
  753. }
  754. /**
  755. Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.
  756. @param Dns4ServerList Common list of addresses of all configured DNSv4 server.
  757. @param ServerIp DNS server Ip.
  758. @retval EFI_SUCCESS Add Dns4 ServerIp to common list successfully.
  759. @retval Others Failed to add Dns4 ServerIp to common list.
  760. **/
  761. EFI_STATUS
  762. EFIAPI
  763. AddDns4ServerIp (
  764. IN LIST_ENTRY *Dns4ServerList,
  765. IN EFI_IPv4_ADDRESS ServerIp
  766. )
  767. {
  768. DNS4_SERVER_IP *NewServerIp;
  769. DNS4_SERVER_IP *Item;
  770. LIST_ENTRY *Entry;
  771. LIST_ENTRY *Next;
  772. NewServerIp = NULL;
  773. Item = NULL;
  774. //
  775. // Search the database for the matching ServerIp
  776. //
  777. NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns4ServerList) {
  778. Item = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);
  779. if (CompareMem (&Item->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS)) == 0) {
  780. //
  781. // Already done.
  782. //
  783. return EFI_SUCCESS;
  784. }
  785. }
  786. //
  787. // Add new one
  788. //
  789. NewServerIp = AllocatePool (sizeof (DNS4_SERVER_IP));
  790. if (NewServerIp == NULL) {
  791. return EFI_OUT_OF_RESOURCES;
  792. }
  793. InitializeListHead (&NewServerIp->AllServerLink);
  794. CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));
  795. InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);
  796. return EFI_SUCCESS;
  797. }
  798. /**
  799. Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.
  800. @param Dns6ServerList Common list of addresses of all configured DNSv6 server.
  801. @param ServerIp DNS server Ip.
  802. @retval EFI_SUCCESS Add Dns6 ServerIp to common list successfully.
  803. @retval Others Failed to add Dns6 ServerIp to common list.
  804. **/
  805. EFI_STATUS
  806. EFIAPI
  807. AddDns6ServerIp (
  808. IN LIST_ENTRY *Dns6ServerList,
  809. IN EFI_IPv6_ADDRESS ServerIp
  810. )
  811. {
  812. DNS6_SERVER_IP *NewServerIp;
  813. DNS6_SERVER_IP *Item;
  814. LIST_ENTRY *Entry;
  815. LIST_ENTRY *Next;
  816. NewServerIp = NULL;
  817. Item = NULL;
  818. //
  819. // Search the database for the matching ServerIp
  820. //
  821. NET_LIST_FOR_EACH_SAFE (Entry, Next, Dns6ServerList) {
  822. Item = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);
  823. if (CompareMem (&Item->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS)) == 0) {
  824. //
  825. // Already done.
  826. //
  827. return EFI_SUCCESS;
  828. }
  829. }
  830. //
  831. // Add new one
  832. //
  833. NewServerIp = AllocatePool (sizeof (DNS6_SERVER_IP));
  834. if (NewServerIp == NULL) {
  835. return EFI_OUT_OF_RESOURCES;
  836. }
  837. InitializeListHead (&NewServerIp->AllServerLink);
  838. CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));
  839. InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);
  840. return EFI_SUCCESS;
  841. }
  842. /**
  843. Find out whether the response is valid or invalid.
  844. @param TokensMap All DNS transmittal Tokens entry.
  845. @param Identification Identification for queried packet.
  846. @param Type Type for queried packet.
  847. @param Class Class for queried packet.
  848. @param Item Return corresponding Token entry.
  849. @retval TRUE The response is valid.
  850. @retval FALSE The response is invalid.
  851. **/
  852. BOOLEAN
  853. IsValidDnsResponse (
  854. IN NET_MAP *TokensMap,
  855. IN UINT16 Identification,
  856. IN UINT16 Type,
  857. IN UINT16 Class,
  858. OUT NET_MAP_ITEM **Item
  859. )
  860. {
  861. LIST_ENTRY *Entry;
  862. NET_BUF *Packet;
  863. UINT8 *TxString;
  864. DNS_HEADER *DnsHeader;
  865. CHAR8 *QueryName;
  866. DNS_QUERY_SECTION *QuerySection;
  867. NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {
  868. *Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
  869. Packet = (NET_BUF *) ((*Item)->Value);
  870. if (Packet == NULL){
  871. continue;
  872. } else {
  873. TxString = NetbufGetByte (Packet, 0, NULL);
  874. ASSERT (TxString != NULL);
  875. DnsHeader = (DNS_HEADER *) TxString;
  876. QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));
  877. QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);
  878. if (NTOHS (DnsHeader->Identification) == Identification &&
  879. NTOHS (QuerySection->Type) == Type &&
  880. NTOHS (QuerySection->Class) == Class) {
  881. return TRUE;
  882. }
  883. }
  884. }
  885. *Item = NULL;
  886. return FALSE;
  887. }
  888. /**
  889. Parse Dns Response.
  890. @param Instance The DNS instance
  891. @param RxString Received buffer.
  892. @param Length Received buffer length.
  893. @param Completed Flag to indicate that Dns response is valid.
  894. @retval EFI_SUCCESS Parse Dns Response successfully.
  895. @retval Others Failed to parse Dns Response.
  896. **/
  897. EFI_STATUS
  898. ParseDnsResponse (
  899. IN OUT DNS_INSTANCE *Instance,
  900. IN UINT8 *RxString,
  901. IN UINT32 Length,
  902. OUT BOOLEAN *Completed
  903. )
  904. {
  905. DNS_HEADER *DnsHeader;
  906. CHAR8 *QueryName;
  907. UINT32 QueryNameLen;
  908. DNS_QUERY_SECTION *QuerySection;
  909. CHAR8 *AnswerName;
  910. DNS_ANSWER_SECTION *AnswerSection;
  911. UINT8 *AnswerData;
  912. NET_MAP_ITEM *Item;
  913. DNS4_TOKEN_ENTRY *Dns4TokenEntry;
  914. DNS6_TOKEN_ENTRY *Dns6TokenEntry;
  915. UINT32 IpCount;
  916. UINT32 RRCount;
  917. UINT32 AnswerSectionNum;
  918. UINT32 CNameTtl;
  919. EFI_IPv4_ADDRESS *HostAddr4;
  920. EFI_IPv6_ADDRESS *HostAddr6;
  921. EFI_DNS4_CACHE_ENTRY *Dns4CacheEntry;
  922. EFI_DNS6_CACHE_ENTRY *Dns6CacheEntry;
  923. DNS_RESOURCE_RECORD *Dns4RR;
  924. DNS6_RESOURCE_RECORD *Dns6RR;
  925. EFI_STATUS Status;
  926. UINT32 RemainingLength;
  927. EFI_TPL OldTpl;
  928. Item = NULL;
  929. Dns4TokenEntry = NULL;
  930. Dns6TokenEntry = NULL;
  931. IpCount = 0;
  932. RRCount = 0;
  933. AnswerSectionNum = 0;
  934. CNameTtl = 0;
  935. HostAddr4 = NULL;
  936. HostAddr6 = NULL;
  937. Dns4CacheEntry = NULL;
  938. Dns6CacheEntry = NULL;
  939. Dns4RR = NULL;
  940. Dns6RR = NULL;
  941. *Completed = TRUE;
  942. Status = EFI_SUCCESS;
  943. RemainingLength = Length;
  944. //
  945. // Check whether the remaining packet length is avaiable or not.
  946. //
  947. if (RemainingLength <= sizeof (DNS_HEADER)) {
  948. *Completed = FALSE;
  949. return EFI_ABORTED;
  950. } else {
  951. RemainingLength -= sizeof (DNS_HEADER);
  952. }
  953. //
  954. // Get header
  955. //
  956. DnsHeader = (DNS_HEADER *) RxString;
  957. DnsHeader->Identification = NTOHS (DnsHeader->Identification);
  958. DnsHeader->Flags.Uint16 = NTOHS (DnsHeader->Flags.Uint16);
  959. DnsHeader->QuestionsNum = NTOHS (DnsHeader->QuestionsNum);
  960. DnsHeader->AnswersNum = NTOHS (DnsHeader->AnswersNum);
  961. DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum);
  962. DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum);
  963. //
  964. // There is always one QuestionsNum in DNS message. The capability to handle more
  965. // than one requires to redesign the message format. Currently, it's not supported.
  966. //
  967. if (DnsHeader->QuestionsNum > 1) {
  968. *Completed = FALSE;
  969. return EFI_UNSUPPORTED;
  970. }
  971. //
  972. // Get Query name
  973. //
  974. QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));
  975. QueryNameLen = (UINT32) AsciiStrLen (QueryName) + 1;
  976. //
  977. // Check whether the remaining packet length is avaiable or not.
  978. //
  979. if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) {
  980. *Completed = FALSE;
  981. return EFI_ABORTED;
  982. } else {
  983. RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION));
  984. }
  985. //
  986. // Get query section
  987. //
  988. QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen);
  989. QuerySection->Type = NTOHS (QuerySection->Type);
  990. QuerySection->Class = NTOHS (QuerySection->Class);
  991. OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  992. //
  993. // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.
  994. //
  995. if (Instance->Service->IpVersion == IP_VERSION_4) {
  996. if (!IsValidDnsResponse (
  997. &Instance->Dns4TxTokens,
  998. DnsHeader->Identification,
  999. QuerySection->Type,
  1000. QuerySection->Class,
  1001. &Item
  1002. )) {
  1003. *Completed = FALSE;
  1004. Status = EFI_ABORTED;
  1005. goto ON_EXIT;
  1006. }
  1007. ASSERT (Item != NULL);
  1008. Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);
  1009. } else {
  1010. if (!IsValidDnsResponse (
  1011. &Instance->Dns6TxTokens,
  1012. DnsHeader->Identification,
  1013. QuerySection->Type,
  1014. QuerySection->Class,
  1015. &Item
  1016. )) {
  1017. *Completed = FALSE;
  1018. Status = EFI_ABORTED;
  1019. goto ON_EXIT;
  1020. }
  1021. ASSERT (Item != NULL);
  1022. Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);
  1023. }
  1024. //
  1025. // Continue Check Some Errors.
  1026. //
  1027. if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \
  1028. DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {
  1029. //
  1030. // The domain name referenced in the query does not exist.
  1031. //
  1032. if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {
  1033. Status = EFI_NOT_FOUND;
  1034. } else {
  1035. Status = EFI_DEVICE_ERROR;
  1036. }
  1037. goto ON_COMPLETE;
  1038. }
  1039. //
  1040. // Do some buffer allocations.
  1041. //
  1042. if (Instance->Service->IpVersion == IP_VERSION_4) {
  1043. ASSERT (Dns4TokenEntry != NULL);
  1044. if (Dns4TokenEntry->GeneralLookUp) {
  1045. //
  1046. // It's the GeneralLookUp querying.
  1047. //
  1048. Dns4TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));
  1049. if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {
  1050. Status = EFI_OUT_OF_RESOURCES;
  1051. goto ON_EXIT;
  1052. }
  1053. Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
  1054. if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
  1055. Status = EFI_OUT_OF_RESOURCES;
  1056. goto ON_EXIT;
  1057. }
  1058. } else {
  1059. //
  1060. // It's not the GeneralLookUp querying. Check the Query type.
  1061. //
  1062. if (QuerySection->Type == DNS_TYPE_A) {
  1063. Dns4TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS_HOST_TO_ADDR_DATA));
  1064. if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {
  1065. Status = EFI_OUT_OF_RESOURCES;
  1066. goto ON_EXIT;
  1067. }
  1068. Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));
  1069. if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {
  1070. Status = EFI_OUT_OF_RESOURCES;
  1071. goto ON_EXIT;
  1072. }
  1073. } else {
  1074. Status = EFI_UNSUPPORTED;
  1075. goto ON_EXIT;
  1076. }
  1077. }
  1078. } else {
  1079. ASSERT (Dns6TokenEntry != NULL);
  1080. if (Dns6TokenEntry->GeneralLookUp) {
  1081. //
  1082. // It's the GeneralLookUp querying.
  1083. //
  1084. Dns6TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));
  1085. if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {
  1086. Status = EFI_OUT_OF_RESOURCES;
  1087. goto ON_EXIT;
  1088. }
  1089. Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
  1090. if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {
  1091. Status = EFI_OUT_OF_RESOURCES;
  1092. goto ON_EXIT;
  1093. }
  1094. } else {
  1095. //
  1096. // It's not the GeneralLookUp querying. Check the Query type.
  1097. //
  1098. if (QuerySection->Type == DNS_TYPE_AAAA) {
  1099. Dns6TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS6_HOST_TO_ADDR_DATA));
  1100. if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {
  1101. Status = EFI_OUT_OF_RESOURCES;
  1102. goto ON_EXIT;
  1103. }
  1104. Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));
  1105. if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {
  1106. Status = EFI_OUT_OF_RESOURCES;
  1107. goto ON_EXIT;
  1108. }
  1109. } else {
  1110. Status = EFI_UNSUPPORTED;
  1111. goto ON_EXIT;
  1112. }
  1113. }
  1114. }
  1115. Status = EFI_NOT_FOUND;
  1116. //
  1117. // Get Answer name
  1118. //
  1119. AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);
  1120. //
  1121. // Processing AnswerSection.
  1122. //
  1123. while (AnswerSectionNum < DnsHeader->AnswersNum) {
  1124. //
  1125. // Check whether the remaining packet length is avaiable or not.
  1126. //
  1127. if (RemainingLength <= sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)) {
  1128. *Completed = FALSE;
  1129. Status = EFI_ABORTED;
  1130. goto ON_EXIT;
  1131. } else {
  1132. RemainingLength -= (sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION));
  1133. }
  1134. //
  1135. // Answer name should be PTR, else EFI_UNSUPPORTED returned.
  1136. //
  1137. if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {
  1138. Status = EFI_UNSUPPORTED;
  1139. goto ON_EXIT;
  1140. }
  1141. //
  1142. // Get Answer section.
  1143. //
  1144. AnswerSection = (DNS_ANSWER_SECTION *) (AnswerName + sizeof (UINT16));
  1145. AnswerSection->Type = NTOHS (AnswerSection->Type);
  1146. AnswerSection->Class = NTOHS (AnswerSection->Class);
  1147. AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);
  1148. AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);
  1149. //
  1150. // Check whether the remaining packet length is avaiable or not.
  1151. //
  1152. if (RemainingLength < AnswerSection->DataLength) {
  1153. *Completed = FALSE;
  1154. Status = EFI_ABORTED;
  1155. goto ON_EXIT;
  1156. } else {
  1157. RemainingLength -= AnswerSection->DataLength;
  1158. }
  1159. //
  1160. // Check whether it's the GeneralLookUp querying.
  1161. //
  1162. if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {
  1163. Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;
  1164. AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
  1165. //
  1166. // Fill the ResourceRecord.
  1167. //
  1168. Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
  1169. if (Dns4RR[RRCount].QName == NULL) {
  1170. Status = EFI_OUT_OF_RESOURCES;
  1171. goto ON_EXIT;
  1172. }
  1173. CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
  1174. Dns4RR[RRCount].QType = AnswerSection->Type;
  1175. Dns4RR[RRCount].QClass = AnswerSection->Class;
  1176. Dns4RR[RRCount].TTL = AnswerSection->Ttl;
  1177. Dns4RR[RRCount].DataLength = AnswerSection->DataLength;
  1178. Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);
  1179. if (Dns4RR[RRCount].RData == NULL) {
  1180. Status = EFI_OUT_OF_RESOURCES;
  1181. goto ON_EXIT;
  1182. }
  1183. CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);
  1184. RRCount ++;
  1185. Status = EFI_SUCCESS;
  1186. } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {
  1187. Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;
  1188. AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
  1189. //
  1190. // Fill the ResourceRecord.
  1191. //
  1192. Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
  1193. if (Dns6RR[RRCount].QName == NULL) {
  1194. Status = EFI_OUT_OF_RESOURCES;
  1195. goto ON_EXIT;
  1196. }
  1197. CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
  1198. Dns6RR[RRCount].QType = AnswerSection->Type;
  1199. Dns6RR[RRCount].QClass = AnswerSection->Class;
  1200. Dns6RR[RRCount].TTL = AnswerSection->Ttl;
  1201. Dns6RR[RRCount].DataLength = AnswerSection->DataLength;
  1202. Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);
  1203. if (Dns6RR[RRCount].RData == NULL) {
  1204. Status = EFI_OUT_OF_RESOURCES;
  1205. goto ON_EXIT;
  1206. }
  1207. CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);
  1208. RRCount ++;
  1209. Status = EFI_SUCCESS;
  1210. } else {
  1211. //
  1212. // It's not the GeneralLookUp querying.
  1213. // Check the Query type, parse the response packet.
  1214. //
  1215. switch (AnswerSection->Type) {
  1216. case DNS_TYPE_A:
  1217. //
  1218. // This is address entry, get Data.
  1219. //
  1220. ASSERT (Dns4TokenEntry != NULL);
  1221. if (AnswerSection->DataLength != 4) {
  1222. Status = EFI_ABORTED;
  1223. goto ON_EXIT;
  1224. }
  1225. HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;
  1226. AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
  1227. CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));
  1228. //
  1229. // Allocate new CacheEntry pool to update DNS cache dynamically.
  1230. //
  1231. Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));
  1232. if (Dns4CacheEntry == NULL) {
  1233. Status = EFI_OUT_OF_RESOURCES;
  1234. goto ON_EXIT;
  1235. }
  1236. Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
  1237. if (Dns4CacheEntry->HostName == NULL) {
  1238. Status = EFI_OUT_OF_RESOURCES;
  1239. goto ON_EXIT;
  1240. }
  1241. CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));
  1242. Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));
  1243. if (Dns4CacheEntry->IpAddress == NULL) {
  1244. Status = EFI_OUT_OF_RESOURCES;
  1245. goto ON_EXIT;
  1246. }
  1247. CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));
  1248. if (CNameTtl != 0 && AnswerSection->Ttl != 0) {
  1249. Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);
  1250. } else {
  1251. Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);
  1252. }
  1253. UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);
  1254. //
  1255. // Free allocated CacheEntry pool.
  1256. //
  1257. FreePool (Dns4CacheEntry->HostName);
  1258. Dns4CacheEntry->HostName = NULL;
  1259. FreePool (Dns4CacheEntry->IpAddress);
  1260. Dns4CacheEntry->IpAddress = NULL;
  1261. FreePool (Dns4CacheEntry);
  1262. Dns4CacheEntry = NULL;
  1263. IpCount ++;
  1264. Status = EFI_SUCCESS;
  1265. break;
  1266. case DNS_TYPE_AAAA:
  1267. //
  1268. // This is address entry, get Data.
  1269. //
  1270. ASSERT (Dns6TokenEntry != NULL);
  1271. if (AnswerSection->DataLength != 16) {
  1272. Status = EFI_ABORTED;
  1273. goto ON_EXIT;
  1274. }
  1275. HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;
  1276. AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
  1277. CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));
  1278. //
  1279. // Allocate new CacheEntry pool to update DNS cache dynamically.
  1280. //
  1281. Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));
  1282. if (Dns6CacheEntry == NULL) {
  1283. Status = EFI_OUT_OF_RESOURCES;
  1284. goto ON_EXIT;
  1285. }
  1286. Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
  1287. if (Dns6CacheEntry->HostName == NULL) {
  1288. Status = EFI_OUT_OF_RESOURCES;
  1289. goto ON_EXIT;
  1290. }
  1291. CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));
  1292. Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
  1293. if (Dns6CacheEntry->IpAddress == NULL) {
  1294. Status = EFI_OUT_OF_RESOURCES;
  1295. goto ON_EXIT;
  1296. }
  1297. CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));
  1298. if (CNameTtl != 0 && AnswerSection->Ttl != 0) {
  1299. Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);
  1300. } else {
  1301. Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);
  1302. }
  1303. UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);
  1304. //
  1305. // Free allocated CacheEntry pool.
  1306. //
  1307. FreePool (Dns6CacheEntry->HostName);
  1308. Dns6CacheEntry->HostName = NULL;
  1309. FreePool (Dns6CacheEntry->IpAddress);
  1310. Dns6CacheEntry->IpAddress = NULL;
  1311. FreePool (Dns6CacheEntry);
  1312. Dns6CacheEntry = NULL;
  1313. IpCount ++;
  1314. Status = EFI_SUCCESS;
  1315. break;
  1316. case DNS_TYPE_CNAME:
  1317. //
  1318. // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME
  1319. // record in the response and restart the query at the domain name specified in the data field of the
  1320. // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.
  1321. //
  1322. CNameTtl = AnswerSection->Ttl;
  1323. break;
  1324. default:
  1325. Status = EFI_UNSUPPORTED;
  1326. goto ON_EXIT;
  1327. }
  1328. }
  1329. //
  1330. // Find next one
  1331. //
  1332. AnswerName = (CHAR8 *) AnswerSection + sizeof (*AnswerSection) + AnswerSection->DataLength;
  1333. AnswerSectionNum ++;
  1334. }
  1335. if (Instance->Service->IpVersion == IP_VERSION_4) {
  1336. ASSERT (Dns4TokenEntry != NULL);
  1337. if (Dns4TokenEntry->GeneralLookUp) {
  1338. Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
  1339. } else {
  1340. if (QuerySection->Type == DNS_TYPE_A) {
  1341. Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
  1342. } else {
  1343. Status = EFI_UNSUPPORTED;
  1344. goto ON_EXIT;
  1345. }
  1346. }
  1347. } else {
  1348. ASSERT (Dns6TokenEntry != NULL);
  1349. if (Dns6TokenEntry->GeneralLookUp) {
  1350. Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
  1351. } else {
  1352. if (QuerySection->Type == DNS_TYPE_AAAA) {
  1353. Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
  1354. } else {
  1355. Status = EFI_UNSUPPORTED;
  1356. goto ON_EXIT;
  1357. }
  1358. }
  1359. }
  1360. ON_COMPLETE:
  1361. //
  1362. // Parsing is complete, free the sending packet and signal Event here.
  1363. //
  1364. if (Item != NULL && Item->Value != NULL) {
  1365. NetbufFree ((NET_BUF *) (Item->Value));
  1366. }
  1367. if (Instance->Service->IpVersion == IP_VERSION_4) {
  1368. ASSERT (Dns4TokenEntry != NULL);
  1369. Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);
  1370. Dns4TokenEntry->Token->Status = Status;
  1371. if (Dns4TokenEntry->Token->Event != NULL) {
  1372. gBS->SignalEvent (Dns4TokenEntry->Token->Event);
  1373. DispatchDpc ();
  1374. }
  1375. } else {
  1376. ASSERT (Dns6TokenEntry != NULL);
  1377. Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
  1378. Dns6TokenEntry->Token->Status = Status;
  1379. if (Dns6TokenEntry->Token->Event != NULL) {
  1380. gBS->SignalEvent (Dns6TokenEntry->Token->Event);
  1381. DispatchDpc ();
  1382. }
  1383. }
  1384. ON_EXIT:
  1385. //
  1386. // Free the allocated buffer if error happen.
  1387. //
  1388. if (EFI_ERROR (Status)) {
  1389. if (Dns4TokenEntry != NULL) {
  1390. if (Dns4TokenEntry->GeneralLookUp) {
  1391. if (Dns4TokenEntry->Token->RspData.GLookupData != NULL) {
  1392. if (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL) {
  1393. while (RRCount != 0) {
  1394. RRCount --;
  1395. if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {
  1396. FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);
  1397. }
  1398. if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {
  1399. FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);
  1400. }
  1401. }
  1402. FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);
  1403. }
  1404. FreePool (Dns4TokenEntry->Token->RspData.GLookupData);
  1405. }
  1406. } else {
  1407. if (QuerySection->Type == DNS_TYPE_A && Dns4TokenEntry->Token->RspData.H2AData != NULL) {
  1408. if (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL) {
  1409. FreePool (Dns4TokenEntry->Token->RspData.H2AData->IpList);
  1410. }
  1411. FreePool (Dns4TokenEntry->Token->RspData.H2AData);
  1412. }
  1413. }
  1414. }
  1415. if (Dns6TokenEntry != NULL) {
  1416. if (Dns6TokenEntry->GeneralLookUp) {
  1417. if (Dns6TokenEntry->Token->RspData.GLookupData != NULL) {
  1418. if (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL) {
  1419. while (RRCount != 0) {
  1420. RRCount --;
  1421. if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {
  1422. FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);
  1423. }
  1424. if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {
  1425. FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);
  1426. }
  1427. }
  1428. FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);
  1429. }
  1430. FreePool (Dns6TokenEntry->Token->RspData.GLookupData);
  1431. }
  1432. } else {
  1433. if (QuerySection->Type == DNS_TYPE_AAAA && Dns6TokenEntry->Token->RspData.H2AData != NULL) {
  1434. if (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL) {
  1435. FreePool (Dns6TokenEntry->Token->RspData.H2AData->IpList);
  1436. }
  1437. FreePool (Dns6TokenEntry->Token->RspData.H2AData);
  1438. }
  1439. }
  1440. }
  1441. if (Dns4CacheEntry != NULL) {
  1442. if (Dns4CacheEntry->HostName != NULL) {
  1443. FreePool (Dns4CacheEntry->HostName);
  1444. }
  1445. if (Dns4CacheEntry->IpAddress != NULL) {
  1446. FreePool (Dns4CacheEntry->IpAddress);
  1447. }
  1448. FreePool (Dns4CacheEntry);
  1449. }
  1450. if (Dns6CacheEntry != NULL) {
  1451. if (Dns6CacheEntry->HostName != NULL) {
  1452. FreePool (Dns6CacheEntry->HostName);
  1453. }
  1454. if (Dns6CacheEntry->IpAddress != NULL) {
  1455. FreePool (Dns6CacheEntry->IpAddress);
  1456. }
  1457. FreePool (Dns6CacheEntry);
  1458. }
  1459. }
  1460. gBS->RestoreTPL (OldTpl);
  1461. return Status;
  1462. }
  1463. /**
  1464. Parse response packet.
  1465. @param Packet The packets received.
  1466. @param EndPoint The local/remote UDP access point
  1467. @param IoStatus The status of the UDP receive
  1468. @param Context The opaque parameter to the function.
  1469. **/
  1470. VOID
  1471. EFIAPI
  1472. DnsOnPacketReceived (
  1473. NET_BUF *Packet,
  1474. UDP_END_POINT *EndPoint,
  1475. EFI_STATUS IoStatus,
  1476. VOID *Context
  1477. )
  1478. {
  1479. DNS_INSTANCE *Instance;
  1480. UINT8 *RcvString;
  1481. UINT32 Len;
  1482. BOOLEAN Completed;
  1483. Instance = (DNS_INSTANCE *) Context;
  1484. NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);
  1485. RcvString = NULL;
  1486. Completed = FALSE;
  1487. if (EFI_ERROR (IoStatus)) {
  1488. goto ON_EXIT;
  1489. }
  1490. ASSERT (Packet != NULL);
  1491. Len = Packet->TotalSize;
  1492. RcvString = NetbufGetByte (Packet, 0, NULL);
  1493. ASSERT (RcvString != NULL);
  1494. //
  1495. // Parse Dns Response
  1496. //
  1497. ParseDnsResponse (Instance, RcvString, Len, &Completed);
  1498. ON_EXIT:
  1499. if (Packet != NULL) {
  1500. NetbufFree (Packet);
  1501. }
  1502. if (!Completed) {
  1503. UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);
  1504. }
  1505. }
  1506. /**
  1507. Release the net buffer when packet is sent.
  1508. @param Packet The packets received.
  1509. @param EndPoint The local/remote UDP access point
  1510. @param IoStatus The status of the UDP receive
  1511. @param Context The opaque parameter to the function.
  1512. **/
  1513. VOID
  1514. EFIAPI
  1515. DnsOnPacketSent (
  1516. NET_BUF *Packet,
  1517. UDP_END_POINT *EndPoint,
  1518. EFI_STATUS IoStatus,
  1519. VOID *Context
  1520. )
  1521. {
  1522. DNS_INSTANCE *Instance;
  1523. LIST_ENTRY *Entry;
  1524. NET_MAP_ITEM *Item;
  1525. DNS4_TOKEN_ENTRY *Dns4TokenEntry;
  1526. DNS6_TOKEN_ENTRY *Dns6TokenEntry;
  1527. Dns4TokenEntry = NULL;
  1528. Dns6TokenEntry = NULL;
  1529. Instance = (DNS_INSTANCE *) Context;
  1530. NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);
  1531. if (Instance->Service->IpVersion == IP_VERSION_4) {
  1532. NET_LIST_FOR_EACH (Entry, &Instance->Dns4TxTokens.Used) {
  1533. Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
  1534. if (Packet == (NET_BUF *)(Item->Value)) {
  1535. Dns4TokenEntry = ((DNS4_TOKEN_ENTRY *)Item->Key);
  1536. Dns4TokenEntry->PacketToLive = Dns4TokenEntry->Token->RetryInterval;
  1537. break;
  1538. }
  1539. }
  1540. } else {
  1541. NET_LIST_FOR_EACH (Entry, &Instance->Dns6TxTokens.Used) {
  1542. Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
  1543. if (Packet == (NET_BUF *)(Item->Value)) {
  1544. Dns6TokenEntry = ((DNS6_TOKEN_ENTRY *)Item->Key);
  1545. Dns6TokenEntry->PacketToLive = Dns6TokenEntry->Token->RetryInterval;
  1546. break;
  1547. }
  1548. }
  1549. }
  1550. NetbufFree (Packet);
  1551. }
  1552. /**
  1553. Query request information.
  1554. @param Instance The DNS instance
  1555. @param Packet The packet for querying request information.
  1556. @retval EFI_SUCCESS Query request information successfully.
  1557. @retval Others Failed to query request information.
  1558. **/
  1559. EFI_STATUS
  1560. DoDnsQuery (
  1561. IN DNS_INSTANCE *Instance,
  1562. IN NET_BUF *Packet
  1563. )
  1564. {
  1565. EFI_STATUS Status;
  1566. //
  1567. // Ready to receive the DNS response.
  1568. //
  1569. if (Instance->UdpIo->RecvRequest == NULL) {
  1570. Status = UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);
  1571. if (EFI_ERROR (Status)) {
  1572. return Status;
  1573. }
  1574. }
  1575. //
  1576. // Transmit the DNS packet.
  1577. //
  1578. NET_GET_REF (Packet);
  1579. Status = UdpIoSendDatagram (Instance->UdpIo, Packet, NULL, NULL, DnsOnPacketSent, Instance);
  1580. return Status;
  1581. }
  1582. /**
  1583. Construct the Packet according query section.
  1584. @param Instance The DNS instance
  1585. @param QueryName Queried Name
  1586. @param Type Queried Type
  1587. @param Class Queried Class
  1588. @param Packet The packet for query
  1589. @retval EFI_SUCCESS The packet is constructed.
  1590. @retval Others Failed to construct the Packet.
  1591. **/
  1592. EFI_STATUS
  1593. ConstructDNSQuery (
  1594. IN DNS_INSTANCE *Instance,
  1595. IN CHAR8 *QueryName,
  1596. IN UINT16 Type,
  1597. IN UINT16 Class,
  1598. OUT NET_BUF **Packet
  1599. )
  1600. {
  1601. NET_FRAGMENT Frag;
  1602. DNS_HEADER *DnsHeader;
  1603. DNS_QUERY_SECTION *DnsQuery;
  1604. //
  1605. // Messages carried by UDP are restricted to 512 bytes (not counting the IP
  1606. // or UDP headers).
  1607. //
  1608. Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));
  1609. if (Frag.Bulk == NULL) {
  1610. return EFI_OUT_OF_RESOURCES;
  1611. }
  1612. //
  1613. // Fill header
  1614. //
  1615. DnsHeader = (DNS_HEADER *) Frag.Bulk;
  1616. DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed());
  1617. DnsHeader->Flags.Uint16 = 0x0000;
  1618. DnsHeader->Flags.Bits.RD = 1;
  1619. DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;
  1620. DnsHeader->Flags.Bits.QR = DNS_FLAGS_QR_QUERY;
  1621. DnsHeader->QuestionsNum = 1;
  1622. DnsHeader->AnswersNum = 0;
  1623. DnsHeader->AuthorityNum = 0;
  1624. DnsHeader->AditionalNum = 0;
  1625. DnsHeader->Identification = HTONS (DnsHeader->Identification);
  1626. DnsHeader->Flags.Uint16 = HTONS (DnsHeader->Flags.Uint16);
  1627. DnsHeader->QuestionsNum = HTONS (DnsHeader->QuestionsNum);
  1628. DnsHeader->AnswersNum = HTONS (DnsHeader->AnswersNum);
  1629. DnsHeader->AuthorityNum = HTONS (DnsHeader->AuthorityNum);
  1630. DnsHeader->AditionalNum = HTONS (DnsHeader->AditionalNum);
  1631. Frag.Len = sizeof (*DnsHeader);
  1632. //
  1633. // Fill Query name
  1634. //
  1635. CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));
  1636. Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));
  1637. *(Frag.Bulk + Frag.Len) = 0;
  1638. Frag.Len ++;
  1639. //
  1640. // Rest query section
  1641. //
  1642. DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);
  1643. DnsQuery->Type = HTONS (Type);
  1644. DnsQuery->Class = HTONS (Class);
  1645. Frag.Len += sizeof (*DnsQuery);
  1646. //
  1647. // Wrap the Frag in a net buffer.
  1648. //
  1649. *Packet = NetbufFromExt (&Frag, 1, 0, 0, DnsDummyExtFree, NULL);
  1650. if (*Packet == NULL) {
  1651. FreePool (Frag.Bulk);
  1652. return EFI_OUT_OF_RESOURCES;
  1653. }
  1654. //
  1655. // Store the UdpIo in ProtoData.
  1656. //
  1657. *((UINTN *) &((*Packet)->ProtoData[0])) = (UINTN) (Instance->UdpIo);
  1658. return EFI_SUCCESS;
  1659. }
  1660. /**
  1661. Retransmit the packet.
  1662. @param Instance The DNS instance
  1663. @param Packet Retransmit the packet
  1664. @retval EFI_SUCCESS The packet is retransmitted.
  1665. @retval Others Failed to retransmit.
  1666. **/
  1667. EFI_STATUS
  1668. DnsRetransmit (
  1669. IN DNS_INSTANCE *Instance,
  1670. IN NET_BUF *Packet
  1671. )
  1672. {
  1673. EFI_STATUS Status;
  1674. UINT8 *Buffer;
  1675. ASSERT (Packet != NULL);
  1676. //
  1677. // Set the requests to the listening port, other packets to the connected port
  1678. //
  1679. Buffer = NetbufGetByte (Packet, 0, NULL);
  1680. ASSERT (Buffer != NULL);
  1681. NET_GET_REF (Packet);
  1682. Status = UdpIoSendDatagram (
  1683. Instance->UdpIo,
  1684. Packet,
  1685. NULL,
  1686. NULL,
  1687. DnsOnPacketSent,
  1688. Instance
  1689. );
  1690. if (EFI_ERROR (Status)) {
  1691. NET_PUT_REF (Packet);
  1692. }
  1693. return Status;
  1694. }
  1695. /**
  1696. The timer ticking function for the DNS services.
  1697. @param Event The ticking event
  1698. @param Context The DNS service instance
  1699. **/
  1700. VOID
  1701. EFIAPI
  1702. DnsOnTimerRetransmit (
  1703. IN EFI_EVENT Event,
  1704. IN VOID *Context
  1705. )
  1706. {
  1707. DNS_SERVICE *Service;
  1708. LIST_ENTRY *Entry;
  1709. LIST_ENTRY *Next;
  1710. DNS_INSTANCE *Instance;
  1711. LIST_ENTRY *EntryNetMap;
  1712. NET_MAP_ITEM *ItemNetMap;
  1713. DNS4_TOKEN_ENTRY *Dns4TokenEntry;
  1714. DNS6_TOKEN_ENTRY *Dns6TokenEntry;
  1715. Dns4TokenEntry = NULL;
  1716. Dns6TokenEntry = NULL;
  1717. Service = (DNS_SERVICE *) Context;
  1718. if (Service->IpVersion == IP_VERSION_4) {
  1719. //
  1720. // Iterate through all the children of the DNS service instance. Time
  1721. // out the packet. If maximum retries reached, clean the Token up.
  1722. //
  1723. NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns4ChildrenList) {
  1724. Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);
  1725. EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;
  1726. while (EntryNetMap != &Instance->Dns4TxTokens.Used) {
  1727. ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);
  1728. Dns4TokenEntry = (DNS4_TOKEN_ENTRY *)(ItemNetMap->Key);
  1729. if (Dns4TokenEntry->PacketToLive == 0 || (--Dns4TokenEntry->PacketToLive > 0)) {
  1730. EntryNetMap = EntryNetMap->ForwardLink;
  1731. continue;
  1732. }
  1733. //
  1734. // Retransmit the packet if haven't reach the maxmium retry count,
  1735. // otherwise exit the transfer.
  1736. //
  1737. if (++Dns4TokenEntry->RetryCounting <= Dns4TokenEntry->Token->RetryCount) {
  1738. DnsRetransmit (Instance, (NET_BUF *)ItemNetMap->Value);
  1739. EntryNetMap = EntryNetMap->ForwardLink;
  1740. } else {
  1741. //
  1742. // Maximum retries reached, clean the Token up.
  1743. //
  1744. Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);
  1745. Dns4TokenEntry->Token->Status = EFI_TIMEOUT;
  1746. gBS->SignalEvent (Dns4TokenEntry->Token->Event);
  1747. DispatchDpc ();
  1748. //
  1749. // Free the sending packet.
  1750. //
  1751. if (ItemNetMap->Value != NULL) {
  1752. NetbufFree ((NET_BUF *)(ItemNetMap->Value));
  1753. }
  1754. EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;
  1755. }
  1756. }
  1757. }
  1758. }else {
  1759. //
  1760. // Iterate through all the children of the DNS service instance. Time
  1761. // out the packet. If maximum retries reached, clean the Token up.
  1762. //
  1763. NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns6ChildrenList) {
  1764. Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);
  1765. EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;
  1766. while (EntryNetMap != &Instance->Dns6TxTokens.Used) {
  1767. ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);
  1768. Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (ItemNetMap->Key);
  1769. if (Dns6TokenEntry->PacketToLive == 0 || (--Dns6TokenEntry->PacketToLive > 0)) {
  1770. EntryNetMap = EntryNetMap->ForwardLink;
  1771. continue;
  1772. }
  1773. //
  1774. // Retransmit the packet if haven't reach the maxmium retry count,
  1775. // otherwise exit the transfer.
  1776. //
  1777. if (++Dns6TokenEntry->RetryCounting <= Dns6TokenEntry->Token->RetryCount) {
  1778. DnsRetransmit (Instance, (NET_BUF *) ItemNetMap->Value);
  1779. EntryNetMap = EntryNetMap->ForwardLink;
  1780. } else {
  1781. //
  1782. // Maximum retries reached, clean the Token up.
  1783. //
  1784. Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);
  1785. Dns6TokenEntry->Token->Status = EFI_TIMEOUT;
  1786. gBS->SignalEvent (Dns6TokenEntry->Token->Event);
  1787. DispatchDpc ();
  1788. //
  1789. // Free the sending packet.
  1790. //
  1791. if (ItemNetMap->Value != NULL) {
  1792. NetbufFree ((NET_BUF *) (ItemNetMap->Value));
  1793. }
  1794. EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;
  1795. }
  1796. }
  1797. }
  1798. }
  1799. }
  1800. /**
  1801. The timer ticking function for the DNS driver.
  1802. @param Event The ticking event
  1803. @param Context NULL
  1804. **/
  1805. VOID
  1806. EFIAPI
  1807. DnsOnTimerUpdate (
  1808. IN EFI_EVENT Event,
  1809. IN VOID *Context
  1810. )
  1811. {
  1812. LIST_ENTRY *Entry;
  1813. LIST_ENTRY *Next;
  1814. DNS4_CACHE *Item4;
  1815. DNS6_CACHE *Item6;
  1816. Item4 = NULL;
  1817. Item6 = NULL;
  1818. //
  1819. // Iterate through all the DNS4 cache list.
  1820. //
  1821. NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
  1822. Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
  1823. Item4->DnsCache.Timeout--;
  1824. }
  1825. Entry = mDriverData->Dns4CacheList.ForwardLink;
  1826. while (Entry != &mDriverData->Dns4CacheList) {
  1827. Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
  1828. if (Item4->DnsCache.Timeout == 0) {
  1829. RemoveEntryList (&Item4->AllCacheLink);
  1830. FreePool (Item4->DnsCache.HostName);
  1831. FreePool (Item4->DnsCache.IpAddress);
  1832. FreePool (Item4);
  1833. Entry = mDriverData->Dns4CacheList.ForwardLink;
  1834. } else {
  1835. Entry = Entry->ForwardLink;
  1836. }
  1837. }
  1838. //
  1839. // Iterate through all the DNS6 cache list.
  1840. //
  1841. NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
  1842. Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
  1843. Item6->DnsCache.Timeout--;
  1844. }
  1845. Entry = mDriverData->Dns6CacheList.ForwardLink;
  1846. while (Entry != &mDriverData->Dns6CacheList) {
  1847. Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
  1848. if (Item6->DnsCache.Timeout == 0) {
  1849. RemoveEntryList (&Item6->AllCacheLink);
  1850. FreePool (Item6->DnsCache.HostName);
  1851. FreePool (Item6->DnsCache.IpAddress);
  1852. FreePool (Item6);
  1853. Entry = mDriverData->Dns6CacheList.ForwardLink;
  1854. } else {
  1855. Entry = Entry->ForwardLink;
  1856. }
  1857. }
  1858. }